def test_authtoken_serializer(self): patterns = [url(r'^api-token-auth/', obtain_auth_token)] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) print(schema) route = schema['paths']['/api-token-auth/']['post'] body_schema = route['requestBody']['content']['application/json'][ 'schema'] assert body_schema == {'$ref': '#/components/schemas/AuthToken'} assert schema['components']['schemas']['AuthToken'] == { 'type': 'object', 'properties': { 'username': { 'type': 'string', 'writeOnly': True }, 'password': { 'type': 'string', 'writeOnly': True }, 'token': { 'type': 'string', 'readOnly': True }, }, 'required': ['username', 'password'] }
def test_overridden_get_tags_method(self): class MySchema(AutoSchema): def get_tags(self, path, method): if path.endswith('/new/'): tags = ['tag1', 'tag2'] elif path.endswith('/old/'): tags = ['tag2', 'tag3'] else: tags = ['tag4', 'tag5'] return tags class ExampleStringTagsViewSet(views.ExampleGenericViewSet): schema = MySchema() router = routers.SimpleRouter() router.register('example', ExampleStringTagsViewSet, basename="example") generator = SchemaGenerator(patterns=router.urls) schema = generator.get_schema(request=create_request('/')) assert schema['paths']['/example/new/']['get']['tags'] == [ 'tag1', 'tag2' ] assert schema['paths']['/example/old/']['get']['tags'] == [ 'tag2', 'tag3' ]
def MediaSchemaAPIView(request): """ Use SchemaGenerator to generate Zubhub Media Server API Schema instead of get_schema_view. this is neccessary because `get_schema_view` somehow ignores some api endpoints even when told to generate schema for those. Returns Media Server API schema. """ from rest_framework.schemas.openapi import SchemaGenerator from django.urls import path schema_url_patterns = [ path('upload-file/', UploadFileAPIView), path('delete-file/', DeleteFileAPIView), path('sigen/', SigGenAPIView), path('get-cloudinary-resource-info/', GetCloudinaryResourceInfoAPIView), path('media-schema/', MediaSchemaAPIView) ] generator = SchemaGenerator(title='Zubhub Media Server API', patterns=schema_url_patterns) return Response(generator.get_schema())
def test_duplicate_operation_id(self): patterns = [ path('duplicate1/', views.ExampleOperationIdDuplicate1.as_view()), path('duplicate2/', views.ExampleOperationIdDuplicate2.as_view()), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') generator.get_schema(request=request) assert len(w) == 1 assert issubclass(w[-1].category, UserWarning) print(str(w[-1].message)) assert 'You have a duplicated operationId' in str(w[-1].message)
def test_schema_with_no_paths(self): patterns = [] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) assert schema['paths'] == {}
def handle(self, *args, **options): generator = SchemaGenerator( title='Coaching API', version='0.0.1', ) schema = generator.get_schema() renderer = renderers.JSONOpenAPIRenderer() output = renderer.render(schema, renderer_context={}) self.stdout.write(output.decode())
def test_overridden_tags(self): class ExampleStringTagsViewSet(views.ExampleGenericAPIView): schema = AutoSchema(tags=['example1', 'example2']) url_patterns = [ url(r'^test/?$', ExampleStringTagsViewSet.as_view()), ] generator = SchemaGenerator(patterns=url_patterns) schema = generator.get_schema(request=create_request('/')) assert schema['paths']['/test/']['get']['tags'] == ['example1', 'example2']
def test_component_should_not_be_generated_for_delete_method(self): class ExampleView(generics.DestroyAPIView): schema = AutoSchema(operation_id_base='example') url_patterns = [ path('example/', ExampleView.as_view()), ] generator = SchemaGenerator(patterns=url_patterns) schema = generator.get_schema(request=create_request('/')) assert 'components' not in schema assert 'content' not in schema['paths']['/example/']['delete']['responses']['204']
def get(self, request, format=None): generator = SchemaGenerator(title='Social Web API') schema = generator.get_schema() data = { path: [method for method in schema['paths'][path]] for path in schema['paths'] } return Response(data=data, status=status.HTTP_200_OK)
def test_schema_information_empty(self): """Construction of the top level dictionary.""" patterns = [ url(r'^example/?$', views.ExampleListView.as_view()), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) assert schema['info']['title'] == '' assert schema['info']['version'] == ''
def test_schema_construction(self): """Construction of the top level dictionary.""" patterns = [ url(r'^example/?$', views.ExampleListView.as_view()), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) assert 'openapi' in schema assert 'paths' in schema
def test_mount_url_prefixed_to_paths(self): patterns = [ url(r'^example/?$', views.ExampleListView.as_view()), url(r'^example/{pk}/?$', views.ExampleDetailView.as_view()), ] generator = SchemaGenerator(patterns=patterns, url='/api') generator._initialise_endpoints() paths = generator.get_schema()["paths"] assert '/api/example/' in paths assert '/api/example/{id}/' in paths
def test_schema_rendering_to_json(self): patterns = [ path('example/', views.ExampleGenericAPIView.as_view()), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) ret = JSONOpenAPIRenderer().render(schema) assert b'"openapi": "' in ret assert b'"default": "0.0"' in ret
def generateSchema(): generator = SchemaGenerator(title="Experimenter API") schema = generator.get_schema() paths = schema["paths"] for path in paths: if "/api/v1/" in path: for method in paths[path]: paths[path][method]["tags"] = ["public"] elif "/api/v2/" in path: for method in paths[path]: paths[path][method]["tags"] = ["private"] return json.dumps(schema, indent=2)
def test_prefixed_paths_construction(self): """Construction of the `paths` key maintains a common prefix.""" patterns = [ url(r'^v1/example/?$', views.ExampleListView.as_view()), url(r'^v1/example/{pk}/?$', views.ExampleDetailView.as_view()), ] generator = SchemaGenerator(patterns=patterns) generator._initialise_endpoints() paths = generator.get_schema()["paths"] assert '/v1/example/' in paths assert '/v1/example/{id}/' in paths
def test_schema_information(self): """Construction of the top level dictionary.""" patterns = [ path('example/', views.ExampleListView.as_view()), ] generator = SchemaGenerator(patterns=patterns, title='My title', version='1.2.3', description='My description') request = create_request('/') schema = generator.get_schema(request=request) assert schema['info']['title'] == 'My title' assert schema['info']['version'] == '1.2.3' assert schema['info']['description'] == 'My description'
def test_serializer_validators(self): patterns = [ url(r'^example/?$', views.ExampleValdidatedAPIView.as_view()), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) response = schema['paths']['/example/']['get']['responses'] response_schema = response['200']['content']['application/json'][ 'schema']['properties'] assert response_schema['integer']['type'] == 'integer' assert response_schema['integer']['maximum'] == 99 assert response_schema['integer']['minimum'] == -11 assert response_schema['string']['minLength'] == 2 assert response_schema['string']['maxLength'] == 10 assert response_schema['regex']['pattern'] == r'[ABC]12{3}' assert response_schema['regex'][ 'description'] == 'must have an A, B, or C followed by 1222' assert response_schema['decimal1']['type'] == 'number' assert response_schema['decimal1']['multipleOf'] == .01 assert response_schema['decimal1']['maximum'] == 10000 assert response_schema['decimal1']['minimum'] == -10000 assert response_schema['decimal2']['type'] == 'number' assert response_schema['decimal2']['multipleOf'] == .0001 assert response_schema['email']['type'] == 'string' assert response_schema['email']['format'] == 'email' assert response_schema['email']['default'] == '*****@*****.**' assert response_schema['url']['type'] == 'string' assert response_schema['url']['nullable'] is True assert response_schema['url']['default'] == 'http://www.example.com' assert response_schema['uuid']['type'] == 'string' assert response_schema['uuid']['format'] == 'uuid' assert response_schema['ip4']['type'] == 'string' assert response_schema['ip4']['format'] == 'ipv4' assert response_schema['ip6']['type'] == 'string' assert response_schema['ip6']['format'] == 'ipv6' assert response_schema['ip']['type'] == 'string' assert 'format' not in response_schema['ip']
def test_repeat_operation_ids(self): router = routers.SimpleRouter() router.register('account', views.ExampleGenericViewSet, basename="account") urlpatterns = router.urls generator = SchemaGenerator(patterns=urlpatterns) request = create_request('/') schema = generator.get_schema(request=request) schema_str = str(schema) print(schema_str) assert schema_str.count("operationId") == 2 assert schema_str.count("newExample") == 1 assert schema_str.count("oldExample") == 1
def test_component_name(self): patterns = [ path('example/', views.ExampleAutoSchemaComponentName.as_view()), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) print(schema) assert 'components' in schema assert 'schemas' in schema['components'] assert 'Ulysses' in schema['components']['schemas']
def test_paths_construction(self): """Construction of the `paths` key.""" patterns = [ url(r'^example/?$', views.ExampleListView.as_view()), ] generator = SchemaGenerator(patterns=patterns) generator._initialise_endpoints() paths = generator.get_schema()["paths"] assert '/example/' in paths example_operations = paths['/example/'] assert len(example_operations) == 2 assert 'get' in example_operations assert 'post' in example_operations
def test_auto_generated_apiview_tags(self): class RestaurantAPIView(views.ExampleGenericAPIView): pass class BranchAPIView(views.ExampleGenericAPIView): pass url_patterns = [ url(r'^any-dash_underscore/?$', RestaurantAPIView.as_view()), url(r'^restaurants/branches/?$', BranchAPIView.as_view()) ] generator = SchemaGenerator(patterns=url_patterns) schema = generator.get_schema(request=create_request('/')) assert schema['paths']['/any-dash_underscore/']['get']['tags'] == ['any-dash-underscore'] assert schema['paths']['/restaurants/branches/']['get']['tags'] == ['restaurants']
def WebSchemaAPIView(request): """ Use SchemaGenerator to generate Zubhub Web API Schema instead of get_schema_view. this is neccessary because `get_schema_view` somehow ignores some api endpoints even when told to generate schema for those. Returns Web API schema. """ from rest_framework.schemas.openapi import SchemaGenerator from .urls import schema_url_patterns generator = SchemaGenerator(title='Zubhub Web Server API', patterns=schema_url_patterns) return Response(generator.get_schema())
def test_serializer_datefield(self): patterns = [ url(r'^example/?$', views.ExampleGenericViewSet.as_view({"get": "get"})), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) response = schema['paths']['/example/']['get']['responses'] response_schema = response['200']['content']['application/json']['schema']['properties'] assert response_schema['date']['type'] == response_schema['datetime']['type'] == 'string' assert response_schema['date']['format'] == 'date' assert response_schema['datetime']['format'] == 'date-time'
def test_serializer_model(self): """Construction of the top level dictionary.""" patterns = [ url(r'^example/?$', views.ExampleGenericAPIViewModel.as_view()), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) print(schema) assert 'components' in schema assert 'schemas' in schema['components'] assert 'ExampleModel' in schema['components']['schemas']
def test_operation_id_viewset(self): router = routers.SimpleRouter() router.register('account', views.ExampleViewSet, basename="account") urlpatterns = router.urls generator = SchemaGenerator(patterns=urlpatterns) request = create_request('/') schema = generator.get_schema(request=request) print(schema) assert schema['paths']['/account/']['get']['operationId'] == 'listExampleViewSets' assert schema['paths']['/account/']['post']['operationId'] == 'createExampleViewSet' assert schema['paths']['/account/{id}/']['get']['operationId'] == 'retrieveExampleViewSet' assert schema['paths']['/account/{id}/']['put']['operationId'] == 'updateExampleViewSet' assert schema['paths']['/account/{id}/']['patch']['operationId'] == 'partialUpdateExampleViewSet' assert schema['paths']['/account/{id}/']['delete']['operationId'] == 'destroyExampleViewSet'
def test_serializer_datefield(self): patterns = [ url(r'^example/?$', views.ExampleGenericViewSet.as_view({"get": "get"})), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') schema = generator.get_schema(request=request) response = schema['paths']['/example/']['get']['responses'] response_schema = response['200']['content']['application/json'][ 'schema']['properties'] assert response_schema['date']['type'] == response_schema['datetime'][ 'type'] == 'string' assert response_schema['date']['format'] == 'date' assert response_schema['datetime']['format'] == 'date-time'
def test_duplicate_component_name(self): patterns = [ path('duplicate1/', views.ExampleAutoSchemaDuplicate1.as_view()), path('duplicate2/', views.ExampleAutoSchemaDuplicate2.as_view()), ] generator = SchemaGenerator(patterns=patterns) request = create_request('/') with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') schema = generator.get_schema(request=request) assert len(w) == 1 assert issubclass(w[-1].category, UserWarning) assert 'has been overriden with a different value.' in str(w[-1].message) assert 'components' in schema assert 'schemas' in schema['components'] assert 'Duplicate' in schema['components']['schemas']
def handle(self, *args, **options): # the location where the markdown and other files live docs_dir = os.path.join(os.path.dirname(settings.MAIN_DOC_YAML), 'docs') if options['site_dir']: site_dir = options['site_dir'] else: site_dir = os.path.join(os.path.dirname(settings.MAIN_DOC_YAML), 'site') kwargs = {'config_file': settings.MAIN_DOC_YAML, 'site_dir': site_dir} # build docs build.build(mkdocs_config.load_config(**kwargs), dirty=False) # generate the openAPI spec: generator = SchemaGenerator(title='WebMEV REST API Specification') schema = generator.get_schema(request=None, public=True) renderer = JSONOpenAPIRenderer() output = renderer.render(schema, renderer_context={}) with open(os.path.join(site_dir, 'openapi_spec.json'), 'w') as fout: fout.write(output.decode()) # add the information relevant for the commit/push kwargs['remote_name'] = options['remote_name'] kwargs['remote_branch'] = options['remote_branch'] # due to the way config info is accessed from within the mkdocs gh_deploy # function below, it needs both dict-like access and attribute-like access # UserDict fits that bill config = UserDict(kwargs) config.config_file_path = settings.MAIN_DOC_YAML if options['push']: gh_deploy.gh_deploy(config, message=options['message'])
def introspect(self, request): """ description = ActionProviderDescription( globus_auth_scope=config.our_scope, title="What Time Is It Right Now?", admin_contact="*****@*****.**", synchronous=False, input_schema=schema, api_version="1.0", subtitle=( "From the makers of Philbert: " "Another exciting promotional tie-in for whattimeisitrightnow.com" ), description="", keywords=["time", "whattimeisitnow", "productivity"], visible_to=["all_authenticated_users"], runnable_by=["all_authenticated_users"], administered_by=["*****@*****.**"], ) """ # Generate a path based on the standard automate URLs above patterns = [path(request.path, include(self.urls()))] generator = SchemaGenerator(patterns=patterns) return Response(generator.get_schema())