Skip to content

Commit

Permalink
Merge branch 'master' of github.com:KarrLab/datanator_rest_api
Browse files Browse the repository at this point in the history
  • Loading branch information
lzy7071 committed Aug 27, 2019
2 parents f636a88 + 5e7c234 commit c2f7595
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 73 deletions.
2 changes: 1 addition & 1 deletion README.md
@@ -1,5 +1,5 @@
[![PyPI package](https://img.shields.io/pypi/v/datanator_rest_api.svg)](https://pypi.python.org/pypi/datanator_rest_api)
[![PyPI Status](https://img.shields.io/pypi/status/openapi-spec-validator.svg)](https://pypi.python.org/pypi/datanator_rest_api)
[![PyPI Status](https://img.shields.io/pypi/status/datanator_rest_api.svg)](https://pypi.python.org/pypi/datanator_rest_api)
[![Documentation](https://readthedocs.org/projects/datanator-rest-api/badge/?version=latest)](https://docs.karrlab.org/datanator_rest_api)
[![Test results](https://circleci.com/gh/KarrLab/datanator_rest_api.svg?style=shield)](https://circleci.com/gh/KarrLab/datanator_rest_api)
[![Test coverage](https://coveralls.io/repos/github/KarrLab/datanator_rest_api/badge.svg)](https://coveralls.io/github/KarrLab/datanator_rest_api)
Expand Down
46 changes: 6 additions & 40 deletions datanator_rest_api/core.py
Expand Up @@ -6,51 +6,17 @@
:License: MIT
"""
import connexion
from connexion.resolver import Resolver as Resolver
from connexion.resolver import RestyResolver
from connexion.mock import MockResolver
from datanator_rest_api.server import AutoResolver
import re

def createApp(apiName="DatanatorAPI.yaml", entryModule="datanator_rest_api.routes",specification_dir="./spec",resolver=AutoResolver,validate_responses=False):
app=connexion.App(__name__, specification_dir=specification_dir)
app.add_api(apiName,resolver=resolver(entryModule), validate_responses=validate_responses)
return app

class AutoResolver(RestyResolver):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def resolve_operation_id_using_rest_semantics(self, operation):
"""
Resolves the operationId using REST semantics
:type operation: connexion.operations.AbstractOperation
"""
path_match = re.search(
r'^/?(?P<resource_name>([\w\-](?<!/))*)(?P<trailing_slash>/*)(?P<extended_path>.*)$', operation.path
)

def get_controller_name():

name = self.default_module_name
resource_name = path_match.group('resource_name')

if resource_name:
resource_controller_name = resource_name.replace('-', '_')
name += '.' + resource_controller_name

return name

def get_path_name():
return path_match.group('extended_path').replace('/', '.') if path_match.group('extended_path') else ''

def get_function_name():
method = operation.method

return method.lower()

return '{}.{}{}'.format(get_controller_name(), get_path_name(), get_function_name())


if __name__ == "__main__":

app = connexion.App(__name__, specification_dir='spec/')
app.add_api('DatanatorAPI.yaml', resolver=AutoResolver(
"datanator_rest_api.routes"), validate_responses=False)
app=createApp()
app.run(port=8080, debug=True)
38 changes: 38 additions & 0 deletions datanator_rest_api/server/AutoResolver.py
@@ -0,0 +1,38 @@
from connexion.resolver import RestyResolver
import re


class AutoResolver(RestyResolver):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def resolve_operation_id_using_rest_semantics(self, operation):
"""
Resolves the operationId using REST semantics
:type operation: connexion.operations.AbstractOperation
"""
path_match = re.search(
r'^/?(?P<resource_name>([\w\-](?<!/))*)(?P<trailing_slash>/*)(?P<extended_path>.*)$', operation.path
)

def get_controller_name():

name = self.default_module_name
resource_name = path_match.group('resource_name')

if resource_name:
resource_controller_name = resource_name.replace('-', '_')
name += '.' + resource_controller_name

return name

def get_path_name():
return path_match.group('extended_path').replace('/', '.') if path_match.group('extended_path') else ''

def get_function_name():
method = operation.method

return method.lower()

return '{}.{}{}'.format(get_controller_name(), get_path_name(), get_function_name())
1 change: 1 addition & 0 deletions datanator_rest_api/server/__init__.py
@@ -0,0 +1 @@
from .AutoResolver import AutoResolver
2 changes: 1 addition & 1 deletion tests/requirements.txt
@@ -1,4 +1,4 @@
flask >= 1.1.0
capturer # to capture standard output in tests
mock # to mock python classes and methods
swagger_tester #to confirm api responses meet specification
prance #to parse api
22 changes: 20 additions & 2 deletions tests/test_core.py
Expand Up @@ -5,12 +5,30 @@
:Copyright: 2019, Karr Lab
:License: MIT
"""
import connexion
import flask
from datanator_rest_api import core
import unittest


class CoreTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.app = app=core.createApp()
cls.client = cls.app.app.test_client()
cls.client.testing = True

def test_1(self):
# Example test
self.assertTrue(True) # example assertion
response = self.client.get('/datanator/')
assert(response.status_code == 200)

def test_initialization(self):

self.assertIs(type(self.app),connexion.apps.flask_app.FlaskApp,msg="App did not create properly")

def test_run(self):
self.assertIs(type(self.client),flask.testing.FlaskClient)
response = self.client.get('/datanator/')
assert(response.status_code == 200)


29 changes: 0 additions & 29 deletions tests/test_implementation.py

This file was deleted.

40 changes: 40 additions & 0 deletions tests/test_spec/test_implementation.py
@@ -0,0 +1,40 @@
"""
Test the implementation of the API
:Author: Bilal Shaikh < bilalshaikh42@gmail.com >
:Date: 2019-08-23
:Copyright: 2019, Karr Lab
:License: MIT
"""
import connexion
import unittest
import datanator_rest_api.core as core
from prance import BaseParser


class ImplementationTestCase(unittest.TestCase):
def setUp(self):

self.AutoResolver = core.AutoResolver
self.app = connexion.App(__name__)
self.app.add_api('../../datanator_rest_api/spec/DatanatorAPI.yaml', resolver=self.AutoResolver(
"datanator_rest_api.routes"), validate_responses=False)
self.client = self.app.app.test_client()
self.client.testing = True

def test_1(self):
response = self.client.get('/datanator/')
assert(response.status_code == 200)


class RoutesTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.parser = BaseParser('./datanator_rest_api/spec/DatanatorAPI.yaml')
cls.specification = cls.parser.specification
cls.paths = cls.specification['paths']
cls.routes = cls.paths.keys()

def test_routes(self):
for route in self.routes:
print(route)
assert(True)

0 comments on commit c2f7595

Please sign in to comment.