def test_openapi_can_render_api_key_security_schemes_correctly(): # Given that I have an APIKeySecurityScheme security_scheme = APIKeySecurityScheme( name="api-key", param_name="x-api-key", in_="header", ) # When I generate a document with that security scheme document = generate_openapi_document( App(), Metadata( "example", "an example", "0.0.0", ), security_schemes=[security_scheme], default_security_scheme="api-key", ) # Then I should get back a valid, non-ambiguous, OpenAPI document assert document["components"] == { "schemas": {}, "securitySchemes": { "api-key": { "name": "x-api-key", "in": "header", "type": "apiKey", }, }, }
def test_openapi_can_render_request_only_fields(): # Given that I have a schema that has request-only fields @schema class A: x: int = field(request_only=True) def index(a: A) -> A: pass # And an app app = App(routes=[Route("/", index)]) # When I generate a document document = generate_openapi_document( app, Metadata("example", "an example", "0.0.0"), []) # Then the schema should mark that field as writeOnly response_schema = document["components"]["schemas"][ "tests.openapi.test_openapi.A"] assert response_schema["properties"] == { "x": { "type": "integer", "format": "int64", "writeOnly": True, }, }
def test_openapi_can_render_fields_with_different_request_and_response_names(): # Given that I have a schema that has different names based on whether it's in the request or response @schema class A: x: int = field(request_name="X", response_name="Y") def index(a: A) -> A: pass # And an app app = App(routes=[Route("/", index)]) # When I generate a document document = generate_openapi_document( app, Metadata("example", "an example", "0.0.0"), []) # Then the schema should mark that field as writeOnly response_schema = document["components"]["schemas"][ "tests.openapi.test_openapi.A"] assert response_schema["properties"] == { "X": { "type": "integer", "format": "int64", "writeOnly": True, }, "Y": { "type": "integer", "format": "int64", "readOnly": True, }, }
def setup_app(): get_schema = OpenAPIHandler( metadata=Metadata( title="Pet Store", description=__doc__, version="0.0.0", ), security_schemes=[HTTPSecurityScheme("Bearer", "bearer")], default_security_scheme="Bearer", ) get_schema = annotate(no_auth=True)(get_schema) get_docs = annotate(no_auth=True)(OpenAPIUIHandler()) return App( components=[ DatabaseComponent(), categories.CategoryManagerComponent(), tags.TagManagerComponent(), pets.PetManagerComponent(), ], middleware=[ ResponseRendererMiddleware(), auth_middleware, ], routes=[ Include("/v1/categories", categories.routes), Include("/v1/pets", pets.routes), Include("/v1/tags", tags.routes), Route("/_docs", get_docs), Route("/_schema", get_schema), ], )
def setup_app(): setup_logging() cookie_store = CookieStore(**settings.strict_get("sessions")) get_schema = OpenAPIHandler( Metadata( title="Chat", description="A simple chat app.", version="0.0.0", ), ) get_docs = OpenAPIUIHandler() app = App( components=[ AccountManagerComponent(), ChatHandlerFactoryComponent(), ChatroomListenerComponent(), ChatroomRegistryComponent(), CurrentAccountComponent(), PasswordHasherComponent(), RedisComponent(), SQLAlchemyEngineComponent(), SQLAlchemySessionComponent(), SessionComponent(cookie_store), SettingsComponent(settings), TemplatesComponent(path_to("templates")), ], middleware=[ RequestIdMiddleware(), SessionMiddleware(cookie_store), ResponseRendererMiddleware(), WebsocketsMiddleware(), SQLAlchemyMiddleware(), ], routes=[ Route("/_schema", get_schema), Route("/_docs", get_docs), Route("/", index), Route("/login", login), Route("/register", register), Include("/v1", [ Include("/accounts", accounts.routes, namespace="accounts"), Include("/chat", chat.routes, namespace="chat"), Include("/sessions", sessions.routes, namespace="sessions"), ], namespace="v1"), ], ) decorated_app = WhiteNoise(app, **settings.strict_get("whitenoise")) return decorated_app, app
def test_empty_app_can_return_openapi_document(): # Given that I have an empty app app = App(routes=[ Route("/schema.json", OpenAPIHandler( Metadata( title="empty application", description="an application that doesn't do anything", version="0.1.0", contact=Contact(name="Jim Gordon", ), )), name="schema"), ]) # When I visit its schema uri response = testing.TestClient(app).get("/schema.json") # Then I should get back a successful response assert response.status_code == 200 assert response.json() == { "openapi": "3.0.1", "info": { "title": "empty application", "description": "an application that doesn't do anything", "version": "0.1.0", "contact": { "name": "Jim Gordon", }, }, "paths": { "/schema.json": { "get": { "tags": [], "operationId": "schema", "summary": "Generates an OpenAPI v3 document.", "description": "", "deprecated": False, "parameters": [], "responses": { "200": { "description": "A successful response.", "content": {}, }, }, } } }, "components": { "schemas": {}, "securitySchemes": {}, }, }
def test_openapi_can_render_documents_with_method_handlers(): # Given that I have a resource class @schema class User: username: str class Users: def get_users(self) -> User: pass # And an app that uses that an instance of that resource users = Users() app = App(routes=[Route("/users", users.get_users)]) # When I generate a document document = generate_openapi_document( app, Metadata("example", "an example", "0.0.0"), []) # Then I should get back a valid document assert document
def test_openapi_can_render_lists_of_x(fields, expected): # Given that I have a schema that has a list of something in it A = type("A", (object, ), fields) A.__annotations__ = fields A = schema(A) def index() -> A: pass # And an app app = App(routes=[Route("/", index)]) # When I generate a document document = generate_openapi_document( app, Metadata("example", "an example", "0.0.0"), []) # Then the return schema should have an array of that thing response_schema = document["components"]["schemas"][ "tests.openapi.test_openapi.A"] assert response_schema["properties"] == expected
def setup_app(): setup_logging() get_docs = OpenAPIUIHandler() get_schema = OpenAPIHandler( metadata=Metadata( title="Pets", description="", version="0.0.0", ), ) app = App( components=[ ManagerComponent(PetManager), SQLAlchemyEngineComponent(), SQLAlchemySessionComponent(), SettingsComponent(settings), TemplatesComponent(path_to("templates")), ], middleware=[ RequestIdMiddleware(), ResponseRendererMiddleware(), SQLAlchemyMiddleware(), ], routes=[ Route("/_docs", get_docs), Route("/_schema", get_schema), Route("/", index), Include("/v1/pets", pets.routes, namespace="pets"), ], ) decorated_app = WhiteNoise(app, **settings.strict_get("whitenoise")) return decorated_app, app
if False: raise HTTPError(HTTP_404, {"error": "Pet not found."}) return HTTP_201, Photo(1, "http://example.com/example.png") @annotate( openapi_tags=["users"], ) def update_settings(settings: Settings) -> Settings: return settings get_schema = OpenAPIHandler( metadata=Metadata( title="Pet Store", description="An example application that generates OpenAPI schema.", version="0.1.0", ), security_schemes=[ HTTPSecurityScheme("Bearer Authorization", "bearer") ], default_security_scheme="Bearer Authorization", ) app = App( routes=[ Include("/v0/pets", [ Route("", add_pet_deprecated, method="POST"), ]), Include("/v1/pets", [ Route("", list_pets),
from molten.contrib.sqlalchemy import ( SQLAlchemyMiddleware, SQLAlchemyEngineComponent, SQLAlchemySessionComponent, ) from .api.welcome import welcome from .api.todo import TodoManagerComponent, todo_routes from .api.user import UserManagerComponent, user_routes from .common import ExtJSONRenderer from .schema import APIResponse from .settings import SETTINGS get_schema = OpenAPIHandler(metadata=Metadata( title="runcible", description="A development API to be used in vuejs courses and tutorials.", version="0.0.0", )) get_docs = OpenAPIUIHandler() components = [ SettingsComponent(SETTINGS), SQLAlchemyEngineComponent(), SQLAlchemySessionComponent(), TodoManagerComponent(), UserManagerComponent(), ] middleware = [ResponseRendererMiddleware(), SQLAlchemyMiddleware()]
SQLAlchemySessionComponent, EngineData) from molten.openapi import HTTPSecurityScheme, Metadata, OpenAPIHandler, OpenAPIUIHandler from api.comment.views import list_comments, create_comment, get_comment, delete_comment from api.user.views import list_users, create_user, get_user, delete_user from custom import JSONParser, JSONRenderer from db import Base import settings get_docs = OpenAPIUIHandler() get_schema = OpenAPIHandler( metadata=Metadata( title="Molten-Boilerplate API", description="An API for Molten-Boilerplate.", version="0.0.0", ), security_schemes=[ HTTPSecurityScheme("default", "bearer"), ], default_security_scheme="default", ) components: List[Component] = [ # TOMLSettingsComponent(), SQLAlchemyEngineComponent(), SQLAlchemySessionComponent(), SettingsComponent(settings.SETTINGS) ]
def test_openapi_can_render_documents_with_union_types(): # Given that I have a schema that uses union types @schema class A: x: int @schema class B: x: str @schema class C: x: Union[A, B, int] def index() -> C: pass # And an app that uses that an instance of that resource app = App(routes=[Route("/", index)]) # When I generate a document document = generate_openapi_document( app, Metadata("example", "an example", "0.0.0"), []) # Then I should get back a valid document assert document["components"]["schemas"] == { "tests.openapi.test_openapi.A": { "type": "object", "required": ["x"], "properties": { "x": { "type": "integer", "format": "int64" }, }, }, "tests.openapi.test_openapi.B": { "type": "object", "required": ["x"], "properties": { "x": { "type": "string" }, }, }, "tests.openapi.test_openapi.C": { "type": "object", "required": ["x"], "properties": { "x": { "anyOf": [ { "$ref": "#/components/schemas/tests.openapi.test_openapi.A" }, { "$ref": "#/components/schemas/tests.openapi.test_openapi.B" }, { "type": "integer", "format": "int64" }, ], }, } } }
from molten.openapi import OpenAPIUIHandler, OpenAPIHandler, Metadata, HTTPSecurityScheme from models import Todo, TodoManager get_schema = OpenAPIHandler(metadata=Metadata( title="Todo-backend", description="todo-backend", version="0.0.0", ), security_schemes=[ HTTPSecurityScheme("default", "bearer"), ], default_security_scheme="default") get_docs = OpenAPIUIHandler() def create_todo(todo: Todo, todo_manager: TodoManager) -> Todo: return todo_manager.create(todo)
TodoManagerComponent(), ] middleware: List[Middleware] = [ ResponseRendererMiddleware([ JSONRenderer(), ]), AuthorizationMiddleware, ] get_docs = OpenAPIUIHandler() get_schema = OpenAPIHandler( metadata=Metadata( title="Todo API", description="An API for managing todos.", version="0.0.0", ), security_schemes=[ HTTPSecurityScheme("default", "bearer"), ], default_security_scheme="default", ) routes: List[Union[Route, Include]] = [ Include("/v1/todos", [ Route("/", list_todos), Route("/", create_todo, method="POST"), Route("/{todo_id}", get_todo), Route("/{todo_id}", delete_todo, method="DELETE"), ]),
from molten import App, Route from wsgicors import CORS from molten.openapi import Metadata, OpenAPIHandler, OpenAPIUIHandler from feed_me import settings from feed_me.order.routes import routes as order_routes get_schema = OpenAPIHandler(metadata=Metadata( title="FeedMe API", description="An API for feeding people.", version="0.0.1", ), ) get_docs = OpenAPIUIHandler() routes = order_routes routes += [ Route("/_schema", get_schema), Route("/docs", get_docs), ] def make_zbs_CORS(app): return CORS(app, headers="*", methods="*", origin="*", maxage="86400") app = App(routes=routes, # components=[UserComponent()] ) if __name__ == "__main__":
{%- endif %} {%- if cookiecutter.static_support == 'y' %} from whitenoise import WhiteNoise {%- endif %} from .api.welcome import welcome from .api.todo import TodoManagerComponent, todo_routes from .common import ExtJSONRenderer from .logger import setup_logging from .schema import APIResponse from . import settings get_schema = OpenAPIHandler( metadata=Metadata( title="{{cookiecutter.project_slug}}", description="{{cookiecutter.description}}", version="0.0.0" ) ) get_docs = OpenAPIUIHandler() components = [ SettingsComponent(settings), SQLAlchemyEngineComponent(), SQLAlchemySessionComponent(), TodoManagerComponent(), ] middleware = [ResponseRendererMiddleware(), SQLAlchemyMiddleware()]
from molten import App, Include, Route, ResponseRendererMiddleware from molten.openapi import Metadata, OpenAPIHandler, OpenAPIUIHandler from molten.contrib.prometheus import expose_metrics, prometheus_middleware from settings import logging from api.v1 import room, meeting log = logging.getLogger(__name__) """ Open API """ get_schema = OpenAPIHandler(metadata=Metadata( title="Emeeting API", description="An API for managing your room meetings.", version="0.0.1", )) get_docs = OpenAPIUIHandler() """ Add middlewares """ middlewares = [prometheus_middleware, ResponseRendererMiddleware()] """ Include or add routes """ routes = [ Route("/", get_docs),
def upload_one(f: UploadedFile) -> None: f.save(path_to("uploads", f.filename)) @schema class Data: f: UploadedFile def upload_one_schema(data: Data) -> None: data.f.save(path_to("uploads", data.f.filename)) get_schema = OpenAPIHandler( metadata=Metadata( title="uploads", description="file upload api", version="0.0.0", ), ) get_docs = OpenAPIUIHandler() app = App(routes=[ Route("/upload", upload, method="POST"), Route("/upload-one", upload_one, method="POST"), Route("/upload-one-schema", upload_one_schema, method="POST"), Route("/_schema", get_schema), Route("/_docs", get_docs), ])