All Projects → maximdanilchenko → Aiohttp Apispec

maximdanilchenko / Aiohttp Apispec

Licence: mit
Build and document REST APIs with aiohttp and apispec

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to Aiohttp Apispec

Rest Hapi
🚀 A RESTful API generator for Node.js
Stars: ✭ 1,102 (+540.7%)
Mutual labels:  swagger, documentation, validation
Apispec
A pluggable API specification generator. Currently supports the OpenAPI Specification (f.k.a. the Swagger specification)..
Stars: ✭ 831 (+383.14%)
Mutual labels:  swagger, marshmallow, documentation
Sanic Ms
基于sanic的微服务基础架构
Stars: ✭ 336 (+95.35%)
Mutual labels:  swagger, asyncio, aiohttp
Webargs
A friendly library for parsing HTTP request arguments, with built-in support for popular web frameworks, including Flask, Django, Bottle, Tornado, Pyramid, webapp2, Falcon, and aiohttp.
Stars: ✭ 1,145 (+565.7%)
Mutual labels:  marshmallow, validation, aiohttp
Pymxget
mxget的Python实现
Stars: ✭ 136 (-20.93%)
Mutual labels:  asyncio, aiohttp
Aiohttp
Asynchronous HTTP client/server framework for asyncio and Python
Stars: ✭ 11,972 (+6860.47%)
Mutual labels:  asyncio, aiohttp
Aioinflux
Asynchronous Python client for InfluxDB
Stars: ✭ 142 (-17.44%)
Mutual labels:  asyncio, aiohttp
Express Typescript Boilerplate
A delightful way to building a RESTful API with NodeJs & TypeScript by @w3tecch
Stars: ✭ 2,293 (+1233.14%)
Mutual labels:  documentation, validation
L5 Swagger
OpenApi or Swagger integration to Laravel
Stars: ✭ 1,781 (+935.47%)
Mutual labels:  swagger, documentation
Python Simple Rest Client
Simple REST client for python 3.6+
Stars: ✭ 143 (-16.86%)
Mutual labels:  asyncio, aiohttp
Aiohttp Session
Web sessions for aiohttp.web
Stars: ✭ 171 (-0.58%)
Mutual labels:  asyncio, aiohttp
Backendschool2019
Приложение для практического руководства по разработке бекенд-сервисов на Python (на основе вступительного испытания в Школу бэкенд‑разработки Яндекса)
Stars: ✭ 129 (-25%)
Mutual labels:  asyncio, aiohttp
Aioelasticsearch
aioelasticsearch-py wrapper for asyncio
Stars: ✭ 127 (-26.16%)
Mutual labels:  asyncio, aiohttp
Awesome Documentation Tools
🔥 📚 All the tools, processes and resources you need to create an awesome API & Project documentation
Stars: ✭ 138 (-19.77%)
Mutual labels:  swagger, documentation
Aiohttp Sse
Server-sent events support for aiohttp
Stars: ✭ 125 (-27.33%)
Mutual labels:  asyncio, aiohttp
Kubernetes asyncio
Python asynchronous client library for Kubernetes http://kubernetes.io/
Stars: ✭ 147 (-14.53%)
Mutual labels:  asyncio, aiohttp
Aiozipkin
Distributed tracing instrumentation for asyncio with zipkin
Stars: ✭ 161 (-6.4%)
Mutual labels:  asyncio, aiohttp
Flama
🔥 Fire up your API with this flamethrower
Stars: ✭ 161 (-6.4%)
Mutual labels:  swagger, marshmallow
Openapi Spec Validator
OpenAPI Spec validator
Stars: ✭ 161 (-6.4%)
Mutual labels:  swagger, validation
Gain
Web crawling framework based on asyncio.
Stars: ✭ 2,002 (+1063.95%)
Mutual labels:  asyncio, aiohttp

aiohttp-apispec

Build and document REST APIs with aiohttp and apispec

Pypi Contributors Downloads

build status [docs] [codcov] Code style: black

aiohttp-apispec key features:

  • docs and request_schema decorators to add swagger spec support out of the box;
  • validation_middleware middleware to enable validating with marshmallow schemas from those decorators;
  • SwaggerUI support.
  • New from version 2.0 - match_info_schema, querystring_schema, form_schema, json_schema, headers_schema and cookies_schema decorators for specific request parts validation. Look here for more info.

aiohttp-apispec api is fully inspired by flask-apispec library

Contents

Install

pip install aiohttp-apispec

Quickstart

Also you can read blog post about quickstart with aiohttp-apispec

from aiohttp_apispec import (
    docs,
    request_schema,
    setup_aiohttp_apispec,
)
from aiohttp import web
from marshmallow import Schema, fields


class RequestSchema(Schema):
    id = fields.Int()
    name = fields.Str(description="name")

@docs(
    tags=["mytag"],
    summary="Test method summary",
    description="Test method description",
)
@request_schema(RequestSchema(strict=True))
async def index(request):
    return web.json_response({"msg": "done", "data": {}})


app = web.Application()
app.router.add_post("/v1/test", index)

# init docs with all parameters, usual for ApiSpec
setup_aiohttp_apispec(
    app=app, 
    title="My Documentation", 
    version="v1",
    url="/api/docs/swagger.json",
    swagger_path="/api/docs",
)

# Now we can find spec on 'http://localhost:8080/api/docs/swagger.json'
# and docs on 'http://localhost:8080/api/docs'
web.run_app(app)

Class based views are also supported:

class TheView(web.View):
    @docs(
        tags=["mytag"],
        summary="View method summary",
        description="View method description",
    )
    @request_schema(RequestSchema(strict=True))
    @response_schema(ResponseSchema(), 200)
    def delete(self):
        return web.json_response(
            {"msg": "done", "data": {"name": self.request["data"]["name"]}}
        )


app.router.add_view("/v1/view", TheView)

As alternative you can add responses info to docs decorator, which is more compact way. And it allows you not to use schemas for responses documentation:

@docs(
    tags=["mytag"],
    summary="Test method summary",
    description="Test method description",
    responses={
        200: {
            "schema": ResponseSchema,
            "description": "Success response",
        },  # regular response
        404: {"description": "Not found"},  # responses without schema
        422: {"description": "Validation error"},
    },
)
@request_schema(RequestSchema(strict=True))
async def index(request):
    return web.json_response({"msg": "done", "data": {}})

Adding validation middleware

from aiohttp_apispec import validation_middleware

...

app.middlewares.append(validation_middleware)

Now you can access all validated data in route from request['data'] like so:

@docs(
    tags=["mytag"],
    summary="Test method summary",
    description="Test method description",
)
@request_schema(RequestSchema(strict=True))
@response_schema(ResponseSchema, 200)
async def index(request):
    uid = request["data"]["id"]
    name = request["data"]["name"]
    return web.json_response(
        {"msg": "done", "data": {"info": f"name - {name}, id - {uid}"}}
    )

You can change Request's 'data' param to another with request_data_name argument of setup_aiohttp_apispec function:

setup_aiohttp_apispec(
    app=app,
    request_data_name="validated_data",
)

...


@request_schema(RequestSchema(strict=True))
async def index(request):
    uid = request["validated_data"]["id"]
    ...

Also you can do it for specific view using put_into parameter (beginning from version 2.0):

@request_schema(RequestSchema(strict=True), put_into="validated_data")
async def index(request):
    uid = request["validated_data"]["id"]
    ...

More decorators

Starting from version 2.0 you can use shortenings for documenting and validating specific request parts like cookies, headers etc using those decorators:

Decorator name Default put_into param
match_info_schema match_info
querystring_schema querystring
form_schema form
json_schema json
headers_schema headers
cookies_schema cookies

And example:

@docs(
    tags=["users"],
    summary="Create new user",
    description="Add new user to our toy database",
    responses={
        200: {"description": "Ok. User created", "schema": OkResponse},
        401: {"description": "Unauthorized"},
        422: {"description": "Validation error"},
        500: {"description": "Server error"},
    },
)
@headers_schema(AuthHeaders)  # <- schema for headers validation
@json_schema(UserMeta)  # <- schema for json body validation
@querystring_schema(UserParams)  # <- schema for querystring params validation
async def create_user(request: web.Request):
    headers = request["headers"]  # <- validated headers!
    json_data = request["json"]  # <- validated json!
    query_params = request["querystring"]  # <- validated querystring!
    ...

Custom error handling

If you want to catch validation errors by yourself you could use error_callback parameter and create your custom error handler. Note that it can be one of coroutine or callable and it should have interface exactly like in examples below:

from marshmallow import ValidationError, Schema
from aiohttp import web
from typing import Optional, Mapping, NoReturn


def my_error_handler(
    error: ValidationError,
    req: web.Request,
    schema: Schema,
    error_status_code: Optional[int] = None,
    error_headers: Optional[Mapping[str, str]] = None,
) -> NoReturn:
    raise web.HTTPBadRequest(
            body=json.dumps(error.messages),
            headers=error_headers,
            content_type="application/json",
        )

setup_aiohttp_apispec(app, error_callback=my_error_handler)

Also you can create your own exceptions and create regular Request in middleware like so:

class MyException(Exception):
    def __init__(self, message):
        self.message = message

# It can be coroutine as well:
async def my_error_handler(
    error, req, schema, error_status_code, error_headers
):
    await req.app["db"].do_smth()  # So you can use some async stuff
    raise MyException({"errors": error.messages, "text": "Oops"})

# This middleware will handle your own exceptions:
@web.middleware
async def intercept_error(request, handler):
    try:
        return await handler(request)
    except MyException as e:
        return web.json_response(e.message, status=400)


setup_aiohttp_apispec(app, error_callback=my_error_handler)

# Do not forget to add your own middleware before validation_middleware
app.middlewares.extend([intercept_error, validation_middleware])

Build swagger web client

3.X SwaggerUI version

Just add swagger_path parameter to setup_aiohttp_apispec function.

For example:

setup_aiohttp_apispec(app, swagger_path="/docs")

Then go to /docs and see awesome SwaggerUI

2.X SwaggerUI version

If you prefer older version you can use aiohttp_swagger library. aiohttp-apispec adds swagger_dict parameter to aiohttp web application after initialization (with setup_aiohttp_apispec function). So you can use it easily like:

from aiohttp_apispec import setup_aiohttp_apispec
from aiohttp_swagger import setup_swagger


def create_app(app):
    setup_aiohttp_apispec(app)

    async def swagger(app):
        setup_swagger(
            app=app, swagger_url="/api/doc", swagger_info=app["swagger_dict"]
        )

    app.on_startup.append(swagger)
    # now we can access swagger client on '/api/doc' url
    ...
    return app

Versioning

This software follows Semantic Versioning.


Please star this repository if this project helped you!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].