Build and document REST APIs with aiohttp and apispec
Switch branches/tags
Clone or download
Latest commit a17a68f Nov 12, 2018
Type Name Latest commit message Commit time
Failed to load latest commit information.
aiohttp_apispec Merge pull request #31 from ttyridal/custom_responses_in_docs Nov 12, 2018
docs theeming Aug 24, 2018
tests Adding test for path parameter description added twice bug #28 Nov 9, 2018
.gitignore title and version kwargs Oct 23, 2018
.travis.yml python 3.7 travis Aug 31, 2018
LICENSE Initial commit Dec 5, 2017 readme refactoring Oct 17, 2018
dev-requirements.txt docs fix Oct 23, 2018 version 0.7.6 Nov 12, 2018


Build and document REST APIs with aiohttp and apispec

Pypi build status [codcov]

[docs] Code style: black Contributors

Python 3.5 Python 3.6 Python 3.7


aiohttp-apispec key features:

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

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



pip install aiohttp-apispec


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

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

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

      summary="Test method summary", 
      description="Test method description")
@marshal_with(ResponseSchema(), 200)
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
    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'

Class based views are also supported:

class TheView(web.View):
        summary="View method summary",
        description="View method description",
    @marshal_with(ResponseSchema(), 200)
    def delete(self):
        return web.json_response(
            {"msg": "done", "data": {"name": self.request["data"]["name"]}}

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

Adding validation middleware

from aiohttp_apispec import validation_middleware



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

    summary='Test method summary',
    description='Test method description',
@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}'}}

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

                      title='My Documentation',

async def index(request):
    uid = request['validated_data']['id']

If you want to catch validation errors you should write your own middleware and catch web.HTTPClientError, json.JSONDecodeError and so on. Like this:

async def my_middleware(request, handler):
        return await handler(request)
    except web.HTTPClientError:
        return web.json_response(status=400)
    my_middleware,  # Catch exception by your own, format it and respond to client

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):
        app=app, swagger_url='/api/doc', swagger_info=app['swagger_dict']
# now we can access swagger client on /api/doc url