[doc-schema] the "/" route on a domain now returns the OpenAPI-validated Schema (not a list of schemas), the "dummy_domain" test now validates OpenAPI specs
This commit is contained in:
parent
20563081f5
commit
14e051bd91
|
@ -12,6 +12,8 @@ from schema import SchemaError
|
|||
|
||||
from starlette.applications import Starlette
|
||||
from starlette.routing import Router, Route
|
||||
from starlette.schemas import SchemaGenerator
|
||||
from .lib.responses import ORJSONResponse
|
||||
|
||||
from .lib.acl import AclRoute
|
||||
|
||||
|
@ -42,15 +44,15 @@ class HalfDomain(Starlette):
|
|||
self.app = app
|
||||
|
||||
self.m_domain = importlib.import_module(domain) if module is None else module
|
||||
d_domain = getattr(self.m_domain, 'domain', domain)
|
||||
self.name = d_domain['name']
|
||||
self.id = d_domain['id']
|
||||
self.version = d_domain['version']
|
||||
self.halfapi_version = d_domain.get('halfapi_version', __version__)
|
||||
self.deps = d_domain.get('deps', tuple())
|
||||
self.d_domain = getattr(self.m_domain, 'domain', domain)
|
||||
self.name = self.d_domain['name']
|
||||
self.id = self.d_domain['id']
|
||||
self.version = self.d_domain['version']
|
||||
self.halfapi_version = self.d_domain.get('halfapi_version', __version__)
|
||||
self.deps = self.d_domain.get('deps', tuple())
|
||||
|
||||
if not router:
|
||||
self.router = d_domain.get('routers', '.routers')
|
||||
self.router = self.d_domain.get('routers', '.routers')
|
||||
else:
|
||||
self.router = router
|
||||
|
||||
|
@ -405,7 +407,7 @@ class HalfDomain(Starlette):
|
|||
Generator(HalfRoute)
|
||||
"""
|
||||
yield HalfRoute('/',
|
||||
JSONRoute([ self.schema() ]),
|
||||
self.schema_openapi(),
|
||||
[{'acl': lib_acl.public}],
|
||||
'GET'
|
||||
)
|
||||
|
@ -459,3 +461,35 @@ class HalfDomain(Starlette):
|
|||
}
|
||||
schema['paths'] = self.schema_dict()
|
||||
return schema
|
||||
|
||||
def schema_openapi(self) -> Route:
|
||||
schema = SchemaGenerator(
|
||||
{
|
||||
'openapi': '3.0.0',
|
||||
'info': {
|
||||
'title': self.name,
|
||||
'version': self.version,
|
||||
'x-acls': tuple(getattr(self.m_acl, 'ACLS', ())),
|
||||
**({
|
||||
f'x-{key}': value
|
||||
for key, value in self.d_domain.items()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
)
|
||||
|
||||
async def inner(request, *args, **kwargs):
|
||||
"""
|
||||
description: |
|
||||
Returns the current API routes description (OpenAPI v3)
|
||||
as a JSON object
|
||||
responses:
|
||||
200:
|
||||
description: API Schema in OpenAPI v3 format
|
||||
"""
|
||||
return ORJSONResponse(
|
||||
schema.get_schema(routes=request.app.routes))
|
||||
|
||||
return inner
|
||||
|
||||
|
|
|
@ -122,14 +122,11 @@ class TestDomain(TestCase):
|
|||
def check_routes(self):
|
||||
r = self.client.request('get', '/')
|
||||
assert r.status_code == 200
|
||||
schemas = r.json()
|
||||
assert isinstance(schemas, list)
|
||||
for schema in schemas:
|
||||
assert isinstance(schema, dict)
|
||||
assert 'openapi' in schema
|
||||
assert 'info' in schema
|
||||
assert 'paths' in schema
|
||||
assert 'domain' in schema
|
||||
schema = r.json()
|
||||
assert isinstance(schema, dict)
|
||||
assert 'openapi' in schema
|
||||
assert 'info' in schema
|
||||
assert 'paths' in schema
|
||||
|
||||
r = self.client.request('get', '/halfapi/acls')
|
||||
assert r.status_code == 200
|
||||
|
|
|
@ -12,6 +12,9 @@ async def get(test):
|
|||
"""
|
||||
description:
|
||||
returns the path parameter
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
return ORJSONResponse(str(test))
|
||||
|
||||
|
@ -19,6 +22,9 @@ def post(test):
|
|||
"""
|
||||
description:
|
||||
returns the path parameter
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
return str(test)
|
||||
|
||||
|
@ -26,6 +32,9 @@ def patch(test):
|
|||
"""
|
||||
description:
|
||||
returns the path parameter
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
return str(test)
|
||||
|
||||
|
@ -33,6 +42,9 @@ def put(test):
|
|||
"""
|
||||
description:
|
||||
returns the path parameter
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
return str(test)
|
||||
|
||||
|
@ -40,5 +52,8 @@ def delete(test):
|
|||
"""
|
||||
description:
|
||||
returns the path parameter
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
return str(test)
|
||||
|
|
|
@ -6,5 +6,8 @@ def get():
|
|||
"""
|
||||
description:
|
||||
Not implemented
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -60,6 +60,9 @@ def get(data):
|
|||
"""
|
||||
description:
|
||||
returns the arguments passed in
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
logger.error('%s', data['foo'])
|
||||
return data
|
||||
|
@ -68,6 +71,9 @@ def post(data):
|
|||
"""
|
||||
description:
|
||||
returns the arguments passed in
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
logger.error('%s', data)
|
||||
return data
|
||||
|
|
|
@ -25,24 +25,43 @@ ROUTES = {
|
|||
async def get_abc_alphabet_TEST(request, *args, **kwargs):
|
||||
"""
|
||||
description: Not implemented
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
parameters:
|
||||
- name: test
|
||||
in: path
|
||||
description: Test parameter in route with "ROUTES" constant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
"""
|
||||
return NotImplementedResponse()
|
||||
|
||||
async def get_abc_pinnochio(request, *args, **kwargs):
|
||||
"""
|
||||
description: Not implemented
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
return NotImplementedResponse()
|
||||
|
||||
async def get_config(request, *args, **kwargs):
|
||||
"""
|
||||
description: Not implemented
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
return NotImplementedResponse()
|
||||
|
||||
async def get_arguments(request, *args, **kwargs):
|
||||
"""
|
||||
description: Liste des datatypes.
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
return ORJSONResponse({
|
||||
'foo': kwargs.get('data').get('foo'),
|
||||
|
|
|
@ -12,6 +12,9 @@ def get(halfapi):
|
|||
"""
|
||||
description:
|
||||
returns the configuration of the domain
|
||||
responses:
|
||||
200:
|
||||
description: test response
|
||||
"""
|
||||
logger.error('%s', halfapi)
|
||||
# TODO: Remove in 0.7.0
|
||||
|
|
|
@ -7,6 +7,10 @@ import json
|
|||
import os
|
||||
import sys
|
||||
import pprint
|
||||
import openapi_spec_validator
|
||||
import logging
|
||||
logger = logging.getLogger()
|
||||
|
||||
from halfapi.lib.constants import API_SCHEMA
|
||||
|
||||
|
||||
|
@ -58,8 +62,6 @@ def test_schema(application_debug):
|
|||
c = TestClient(application_debug)
|
||||
|
||||
r = c.request('get', '/')
|
||||
schemas = r.json()
|
||||
assert isinstance(schemas, list)
|
||||
for schema in schemas:
|
||||
assert isinstance(schema, dict)
|
||||
assert API_SCHEMA.validate(schema)
|
||||
schema = r.json()
|
||||
assert isinstance(schema, dict)
|
||||
openapi_spec_validator.validate_spec(schema)
|
||||
|
|
Loading…
Reference in New Issue