personal web log written by izabeera and dryobates

sphinx httpdomain rest

Documenting Flask REST API in Sphinx

by dryobates

Many REST frameworks have built in documentation for provided API. Many specialized software exists for centralized API documentation. But if all you need is to include documentation for your project in your regular sphinx documentation then sphinxcontrib-httpdomain can be helpful.

sphinxcontrib-httpdomain has a lot roles and directives for providing documentation for rest api. It has also autodoc support for Flask, Bottle and Tornado.

We use Flask, so here's quick example, how much you can get with it.


System Message: WARNING/2 (<string>, line 8)

Cannot analyze code. Pygments package not found.

.. code-block:: python

    extensions = [

In documentation:

System Message: WARNING/2 (<string>, line 20)

Cannot analyze code. Pygments package not found.

.. code-block:: rst

    API Documentation


    .. qrefflask:: myapp.api:make_port()

    API Details

    .. autoflask:: myapp.api:make_port()

In code:

System Message: WARNING/2 (<string>, line 39)

Cannot analyze code. Pygments package not found.

.. code-block:: python


    class PostsCollection(ActionResource):
        """Posts collection."""

        def get(self):
            """Return collection of posts.

            .. :quickref: Posts Collection; Get collection of posts.

            **Example request**:

            .. sourcecode:: http

              GET /posts/ HTTP/1.1
              Accept: application/json

            **Example response**:

            .. sourcecode:: http

              HTTP/1.1 200 OK
              Vary: Accept
              Content-Type: application/json

                  "post_id": 12345,
                  "author": "/author/123/",
                  "tags": ["sphinx", "rst", "flask"],
                  "title": "Documenting API in Sphinx with httpdomain",
                  "body": "How to..."
                  "post_id": 12346,
                  "author": "/author/123/",
                  "tags": ["python3", "typehints", "annotations"],
                  "title": "To typehint or not to typehint that is the question",
                  "body": "Static checking in python..."

            :query sort: sorting order e.g. sort=author,-pub_date
            :query q: full text search query
            :resheader Content-Type: application/json
            :status 200: posts found
            :returns: :class:`myapp.objects.Post`
            schema = PostSchema(many=True, strict=True)
            return schema.dump(self.do_get_post_collection())

        def post(self):
            """Add new post.

            .. :quickref: Posts Collection; Add new post to collection.

            :reqheader Accept: application/json
            :<json string title: post title
            :<json string body: post body
            :<json string author: author id
            :<json List[string] tags: tags list
            :>json int: id
            :resheader Content-Type: application/json
            :resheader Location: post url
            :status 201: post created
            :status 400: malformed request
            :status 422: invalid parameters
                post_data = json.loads('utf-8'))
            except json.JSONDecodeError as e:
                return {'errors': [e]}, 400
                post_id = self.do_add_post(post_data)
            except ValidationError as e:
                return {'errors': e.args[0]}, 422
                return {'id': post_id}, 201, {'Location': self.api.url_for(PostItem, post_id=post_id)}

    def make_port():
        """Creates api access port."""

        app = Flask(__name__)
        api = Api(app)
        post_collection_actions = {
            'api': api,
            'add_post': AddPost(),
            'get_post_collection': GetPostCollection(),

        api.add_resource(PostsCollection, '/posts/',
        return app

And the result is:

In the above source code I have written examples by hand. That's only to show what can be done. Personally I'd prefer to pass link to source code of test. Probably doctest could be even better. I have to explore that idea for API requests.

One thing that doesn't look good for me is description of JSON. We use jsonschema and can generate it on the fly. I don't know how to include it in documentation. The only extension for jsonschema I found is sphinxcontrib-jsonschema but it can only read schema from file :( Do you know something better?

Jakub Stolarski. Software engineer. I work professionally as programmer since 2005. Speeding up software development with Test Driven Development, task automation and optimization for performance are things that focus my mind from my early career up to now. If you ask me for my religion: Python, Vim and FreeBSD are my trinity ;) Email: