Интеграция с OpenAPI#
В этом руководстве показано, как интегрировать OpenAPI с RESTAlchemy API.
Мы:
- Создадим API с OpenAPI-роутами.
- Подключим
OpenApiApplicationиOpenApiSpecificationRoute. - Аннотируем контроллеры схемами OpenAPI.
- Получим OpenAPI-спецификацию.
Пример основан на examples/openapi_app.py.
1. DM-модель#
from restalchemy.dm import models, properties, types
class FileModel(models.ModelWithUUID):
name = properties.property(types.String(), required=True)
2. Контроллер с OpenAPI-аннотациями#
Модули: restalchemy.openapi.utils и restalchemy.openapi.constants используются для описания схем.
from restalchemy.api import actions, constants, controllers, resources
from restalchemy.openapi import constants as oa_c
from restalchemy.openapi import engines as openapi_engines
from restalchemy.openapi import structures as openapi_structures
from restalchemy.openapi import utils as oa_utils
class FilesController(controllers.Controller):
"""Controller for /v1/files/[<id>] endpoint."""
__resource__ = resources.ResourceByRAModel(
model_class=FileModel,
process_filters=True,
convert_underscore=False,
)
def create(self, **kwargs):
# Implement file upload logic here
pass
create.openapi_schema = oa_utils.Schema(
summary="Upload file",
parameters=(),
responses=oa_c.build_openapi_create_response(
"%s_Create" % __resource__.get_model().__name__
),
request_body=oa_c.build_openapi_req_body_multipart(
description="Upload file to docs set",
properties={"file": {"format": "binary", "type": "string"}},
),
)
@oa_utils.extend_schema(
summary="Download file",
parameters=(),
responses=oa_c.build_openapi_response_octet_stream(),
)
@actions.get
def download(self, resource, **kwargs):
data = resource.download_file()
headers = {
"Content-Type": constants.CONTENT_TYPE_OCTET_STREAM,
"Content-Disposition": f'attachment; filename="{resource.name}"',
}
return data, 200, headers
download.openapi_schema = oa_utils.Schema(
summary="Download file",
parameters=(),
responses=oa_c.build_openapi_response_octet_stream(),
)
Ключевые моменты:
- Объекты
oa_utils.Schema, прикреплённые к методам контроллера, описывают: summary,parameters,responses,request_body,tags.@oa_utils.extend_schema— вариант через декоратор для actions.- Если схемы не заданы, RA сгенерирует разумные значения по умолчанию на основе ресурсов и DM-типов.
3. Роуты и роут спецификации OpenAPI#
from restalchemy.api import routes
class FileDownloadAction(routes.Action):
"""Handler for /v1/files/<id>/actions/download endpoint."""
__controller__ = FilesController
class FilesRoute(routes.Route):
"""Handler for /v1/files/<id> endpoint."""
__controller__ = FilesController
__allow_methods__ = [
routes.CREATE,
routes.DELETE,
routes.FILTER,
routes.GET,
routes.UPDATE,
]
download = routes.action(FileDownloadAction, invoke=True)
class ApiEndpointController(controllers.RoutesListController):
"""Controller for /v1/ endpoint."""
__TARGET_PATH__ = "/v1/"
class ApiEndpointRoute(routes.Route):
"""Handler for /v1/ endpoint."""
__controller__ = ApiEndpointController
__allow_methods__ = [routes.FILTER, routes.GET]
specifications = routes.action(routes.OpenApiSpecificationRoute)
files = routes.route(FilesRoute)
class UserApiApp(routes.RootRoute):
__controller__ = controllers.RootController
__allow_methods__ = [routes.FILTER]
setattr(UserApiApp, "v1", routes.route(ApiEndpointRoute))
OpenApiSpecificationRoute— встроенный роут, который отдаёт OpenAPI-спеки.ApiEndpointRoute.specificationsподключает его по пути/v1/specifications/.
4. OpenAPI engine и приложение#
from restalchemy.api import applications, middlewares
def get_openapi_engine():
openapi_engine = openapi_engines.OpenApiEngine(
info=openapi_structures.OpenApiInfo(),
paths=openapi_structures.OpenApiPaths(),
components=openapi_structures.OpenApiComponents(),
)
return openapi_engine
def get_user_api_application():
return UserApiApp
def build_wsgi_application():
return middlewares.attach_middlewares(
applications.OpenApiApplication(
route_class=get_user_api_application(),
openapi_engine=get_openapi_engine(),
),
[],
)
OpenApiApplicationрасширяетWSGIAppсвойствомopenapi_engine.OpenApiSpecificationControllerиспользует этот engine для построения спеки.
5. Получение OpenAPI спеки#
После запуска приложения вы можете получить спеку:
- Версия в пути (
3.0.3) соответствует версии OpenAPI, которую вы запрашиваете. - В ответе возвращается JSON-документ OpenAPI.
Этот URL можно подключить к Swagger UI или генераторам клиентов.
Резюме#
- Используйте
OpenApiApplicationиOpenApiSpecificationRoute, чтобы отдавать OpenAPI. - Аннотируйте методы контроллеров через
oa_utils.Schemaили@extend_schema, когда нужен точный контроль. - Иначе можно опираться на defaults RA, полученные из ресурсов и DM-типов.