Skip to content

Commit

Permalink
version 0.12.0
Browse files Browse the repository at this point in the history
  • Loading branch information
vvcheremushkin committed Feb 12, 2020
1 parent 1694188 commit 3defd49
Show file tree
Hide file tree
Showing 30 changed files with 611 additions and 418 deletions.
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
ujson
typing_extensions
marshmallow>=3.0.0rc8,<4
starlette<=1
apispec<3
starlette<1
apispec<4

# Testing
pytest
Expand Down
52 changes: 26 additions & 26 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,47 @@


def get_long_description():
with open("README.md", encoding="utf8") as f:
with open('README.md', encoding='utf8') as f:
return f.read()


def get_packages(package):
return [
dirpath
for dirpath, dirnames, filenames in os.walk(package)
if os.path.exists(os.path.join(dirpath, "__init__.py"))
if os.path.exists(os.path.join(dirpath, '__init__.py'))
]


setup(
name="star_resty",
python_requires=">=3.7",
name='star_resty',
python_requires='>=3.7',
install_requires=[
"ujson",
"typing_extensions",
"marshmallow>=3.0.0rc8,<4",
"starlette<=1",
"apispec<3",
'ujson',
'typing_extensions',
'marshmallow>=3.0.0rc8,<4',
'starlette<1',
'apispec<4',
],
version="0.0.11",
url="https://github.com/slv0/start_resty",
license="BSD",
description="The web framework",
version='0.0.12',
url='https://github.com/slv0/start_resty',
license='BSD',
description='The web framework',
long_description=get_long_description(),
long_description_content_type="text/markdown",
author="Slava Cheremushkin",
author_email="slv0.chr@gmail.com",
packages=get_packages("star_resty"),
package_data={"star_resty": ["py.typed"]},
data_files=[("", ["LICENSE"])],
long_description_content_type='text/markdown',
author='Slava Cheremushkin',
author_email='slv0.chr@gmail.com',
packages=get_packages('star_resty'),
package_data={'star_resty': ['py.typed']},
data_files=[('', ['LICENSE'])],
classifiers=[
"Development Status :: 3 - Alpha",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Topic :: Internet :: WWW/HTTP",
"Programming Language :: Python :: 3.7",
'Development Status :: 3 - Alpha',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Programming Language :: Python :: 3.7',
],
zip_safe=False,
)
2 changes: 1 addition & 1 deletion star_resty/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .apidocs import setup_spec
from .method import *
from .operation import Operation
from .types import *
from .payload import *
40 changes: 40 additions & 0 deletions star_resty/apidocs/operation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from starlette.routing import Route

from star_resty.method import Method
from .request import resolve_parameters, resolve_request_body, resolve_request_body_params
from .response import resolve_responses

__all__ = ('setup_route_operations',)


def setup_route_operations(route: Route, endpoint: Method, version: int = 2,
add_head_methods: bool = False):
operation = setup_operation(endpoint, version=version)
operation = {key: val for key, val in operation.items() if val is not None}
return {method.lower(): operation for method in route.methods
if (method != 'HEAD' or add_head_methods)}


def setup_operation(endpoint: Method, version=2):
options = endpoint.meta
res = {
'tags': [options.tag],
'description': options.description,
'summary': options.summary,
'produces': [endpoint.serializer.media_type],
'parameters': resolve_parameters(endpoint),
'responses': resolve_responses(endpoint),
}

if options.security is not None:
res['security'] = options.security

if version > 2:
res['requestBody'] = resolve_request_body(endpoint)
else:
res['parameters'].extend(resolve_request_body_params(endpoint))

if options.meta:
res.update(options.meta)

return res
53 changes: 53 additions & 0 deletions star_resty/apidocs/request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from star_resty.method import Method
from star_resty.method.parser import RequestParser

__all__ = ('resolve_parameters', 'resolve_request_body', 'resolve_request_body_params')


def resolve_parameters(endpoint: Method):
parameters = []
parser = getattr(endpoint, '__parser__', None)
if parser is None:
return parameters

for p in parser:
if p.schema is not None and p.location != 'body':
parameters.append({'in': p.location, 'schema': p.schema})

return parameters


def resolve_request_body(endpoint: Method):
parser = getattr(endpoint, '__parser__', None)
if parser is None:
return None

content = resolve_request_body_content(parser)
if content:
return {'content': content}


def resolve_request_body_content(parser: RequestParser):
content = {}
for p in parser:
if p.schema is not None and p.location == 'body' and p.media_type:
content[p.media_type] = {'schema': p.schema}

return content


def resolve_request_body_params(endpoint: Method):
params = []
parser = getattr(endpoint, '__parser__', None)
if parser is None:
return params

for p in parser:
if p.schema is not None and p.location == 'body' and p.media_type:
params.append({
'name': 'body',
'in': 'body',
'schema': p.schema
})

return params
40 changes: 40 additions & 0 deletions star_resty/apidocs/response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import inspect
from typing import Union, Dict, Type

from star_resty.method import Method

__all__ = ('resolve_responses',)


def resolve_responses(endpoint: Method):
responses = {}
if endpoint.response_schema:
responses[str(endpoint.status_code)] = {
'schema': endpoint.response_schema
}

errors = endpoint.meta.errors or ()
for e in errors:
if isinstance(e, dict) and e.get('status_code'):
responses[str(e['status_code'])] = {key: val for key, val in e.items() if key != 'status_code'}
elif isinstance(e, Exception) and getattr(e, 'status_code', None) is not None:
responses[str(getattr(e, 'status_code'))] = create_error_schema_by_exc(e)
elif inspect.isclass(e) and issubclass(e, Exception) and getattr(e, 'status_code', None) is not None:
responses[str(getattr(e, 'status_code'))] = create_error_schema_by_exc(e)

parser = getattr(endpoint, '__parser__', None)
if parser and '404' not in responses:
responses['400'] = {'description': 'Bad request'}

return responses


def create_error_schema_by_exc(e: Union[Exception, Type[Exception]]) -> Dict:
schema = {'description': (getattr(e, 'detail', None)
or getattr(e, 'description', None)
or str(e))}
error_schema = getattr(e, 'schema', None)
if error_schema is not None:
schema['schema'] = error_schema

return schema
31 changes: 31 additions & 0 deletions star_resty/apidocs/route.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from typing import Sequence, Union

from apispec import APISpec
from starlette.routing import Route, Mount

from .operation import setup_route_operations
from .utils import convert_path

__all__ = ('setup_routes',)


def setup_routes(routes: Sequence[Union[Route, Mount]],
spec: APISpec, version: int = 2,
add_head_methods: bool = False,
path: str = ''):
for route in routes:
if isinstance(route, Mount):
setup_routes(route.routes, spec, version=version, add_head_methods=add_head_methods,
path=f'{path}{route.path}')
continue
elif isinstance(route, Route) and not route.include_in_schema:
continue

endpoint = getattr(route.endpoint, '__endpoint__', None)
if endpoint is None:
continue

operations = setup_route_operations(route, endpoint, version=version,
add_head_methods=add_head_methods)
route_path = f'{path}{route.path}'
spec.path(convert_path(route_path), operations=operations)
Loading

0 comments on commit 3defd49

Please sign in to comment.