/aiohttp-apispec

Build and document REST APIs with aiohttp and apispec

Primary LanguagePythonMIT LicenseMIT

aiohttp-apispec

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

Python 3.5 Python 3.6 Python 3.7

Build and document REST APIs with aiohttp and apispec

img

aiohttp-apispec key features:

  • docs, use_kwargs and marshal_with decorators to add swagger spec support out of the box
  • aiohttp_apispec_middleware middleware to enable validating with marshmallow schemas from those decorators

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

Install

pip install aiohttp-apispec

Quickstart

from aiohttp_apispec import docs, use_kwargs, marshal_with, AiohttpApiSpec
from aiohttp import web
from marshmallow import Schema, fields


class RequestSchema(Schema):
    id = fields.Int()
    name = fields.Str(description='name')
    bool_field = fields.Bool()


class ResponseSchema(Schema):
    msg = fields.Str()
    data = fields.Dict()


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


# Class based views are also supported:
class TheView(web.View):
    @docs(
        tags=['mytag'],
        summary='View method summary',
        description='View method description',
    )
    @use_kwargs(RequestSchema(strict=True))
    def delete(self):
        return web.json_response({'msg': 'done', 
                                  'data': {'name': self.request['data']['name']}})


app = web.Application()
app.router.add_post('/v1/test', index)
app.router.add_view('/v1/view', TheView)

# init docs with all parameters, usual for ApiSpec
doc = AiohttpApiSpec(
    app=app, title='My Documentation', version='v1', url='/api/docs/api-docs'
)

# now we can find it on 'http://localhost:8080/api/docs/api-docs'
web.run_app(app)

Adding validation middleware

from aiohttp_apispec import aiohttp_apispec_middleware

...

app.middlewares.append(aiohttp_apispec_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',
)
@use_kwargs(RequestSchema(strict=True))
@marshal_with(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}'}}
    )

Build swagger web client

aiohttp-apispec adds swagger_dict parameter to aiohttp web application after initialization. So you can use it easily with aiohttp_swagger library:

from aiohttp_swagger import setup_swagger

...

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

TODO List before 1.0.0 can be released:

  • Generating json spec from marshmallow data schemas
  • Kwargs/marshal_with decorators for request/response schemas and docs decorator for connecting schemas to swagger spec with additional params through aiohttp routes
  • Data validation through additional middleware (built using webargs)
  • 97% more cov with tests
  • Documentation on readthedocs
  • More simple initialisation - register method is not needed. Instead of it we can use some middleware to register all routs on app start
  • Class based views support
  • Nested apps support
  • Flexible settings for aiohttp_apispec_middleware middleware (like request param name and error handling)