flask-rest-api: build a REST API on Flask using Marshmallow

Release v0.17.0. (Changelog)

flask-rest-api is a framework library for creating REST APIs.

It uses Flask as a webserver, and marshmallow to serialize and deserialize data. It relies extensively on the marshmallow ecosystem, using webargs to get arguments from requests, and apispec to generate an OpenAPI specification file as automatically as possible.

Install

flask-rest-api requires Python >= 3.5.

$ pip install flask-rest-api

Guide

Quickstart

Introduction

flask-rest-api makes a few assumptions about how the code should be structured.

The application should be split in Blueprint. It is possible to use basic Flask view functions but it is generally a good idea to use Flask MethodView classes instead.

Marshmallow Schema are used to serialize parameters and responses.

Request and response bodies are serialized as JSON.

A view function only has one successful response type and status code. All other possible responses are errors.

Simple Example

Here is a basic “Petstore example”, where The Pet class is an imaginary ORM.

First instantiate an Api with a Flask application.

from flask import Flask
from flask.views import MethodView
import marshmallow as ma
from flask_rest_api import Api, Blueprint, abort

from .model import Pet

app = Flask('My API')
app.config['OPENAPI_VERSION'] = '3.0.2'
api = Api(app)

Define a marshmallow Schema to expose the model.

class PetSchema(ma.Schema):
    id = ma.fields.Int(dump_only=True)
    name = ma.fields.String()

Define a marshmallow Schema to validate the query arguments.

class PetQueryArgsSchema(ma.Schema):
    name = ma.fields.String()

Instantiate a Blueprint.

blp = Blueprint(
    'pets', 'pets', url_prefix='/pets',
    description='Operations on pets'
)

Use MethodView classes to organize resources, and decorate view methods with Blueprint.arguments and Blueprint.response to specify request deserialization and response serialization respectively.

Use abort to return errors, passing kwargs used by the error handler (handle_http_exception) to build the error response.

@blp.route('/')
class Pets(MethodView):

    @blp.arguments(PetQueryArgsSchema, location='query')
    @blp.response(PetSchema(many=True))
    def get(self, args):
        """List pets"""
        return Pet.get(filters=args)

    @blp.arguments(PetSchema)
    @blp.response(PetSchema, code=201)
    def post(self, new_data):
        """Add a new pet"""
        item = Pet.create(**new_data)
        return item


@blp.route('/<pet_id>')
class PetsById(MethodView):

    @blp.response(PetSchema)
    def get(self, pet_id):
        """Get pet by ID"""
        try:
            item = Pet.get_by_id(pet_id)
        except ItemNotFoundError:
            abort(404, message='Item not found.')
        return item

    @blp.arguments(PetSchema)
    @blp.response(PetSchema)
    def put(self, update_data, pet_id):
        """Update existing pet"""
        try:
            item = Pet.get_by_id(pet_id)
        except ItemNotFoundError:
            abort(404, message='Item not found.')
        item.update(update_data)
        item.commit()
        return item

    @blp.response(code=204)
    def delete(self, pet_id):
        """Delete pet"""
        try:
            Pet.delete(pet_id)
        except ItemNotFoundError:
            abort(404, message='Item not found.')

Finally, register the Blueprint in the Api.

api.register_blueprint(blp)

Arguments

To inject arguments into a view function, use the Blueprint.arguments decorator. It allows to specify a Schema to deserialize and validate the parameters.

When processing a request, the input data is deserialized, validated, and injected in the view function.

@blp.route('/')
class Pets(MethodView):

    @blp.arguments(PetQueryArgsSchema, location='query')
    @blp.response(PetSchema(many=True))
    def get(self, args):
        return Pet.get(filters=args)

    @blp.arguments(PetSchema)
    @blp.response(PetSchema, code=201)
    def post(self, pet_data):
        return Pet.create(**pet_data)

Arguments Location

The following locations are allowed:

  • "json"
  • "query" (or "querystring")
  • "path"
  • "form"
  • "headers"
  • "cookies"
  • "files"

The location defaults to "json", which means body parameter.

Note

Blueprint.arguments uses webargs’s use_args decorator internally, but unlike use_args, it only accepts a single location.

Arguments Injection

By default, arguments are passed as a single positional dict argument. If as_kwargs=True is passed, the decorator passes deserialized input data as keyword arguments instead.

@blp.route('/')
class Pets(MethodView):

    @blp.arguments(PetQueryArgsSchema, location='query', as_kwargs=True)
    @blp.response(PetSchema(many=True))
    def get(self, **kwargs):
        return Pet.get(filters=**kwargs)

This decorator can be called several times on a resource function, for instance to accept both body and query parameters. The order of the decorator calls matters as it determines the order in which the parameters are passed to the view function.

@blp.route('/')
class Pets(MethodView):

    @blp.arguments(PetSchema)
    @blp.arguments(QueryArgsSchema, location='query')
    def post(pet_data, query_args):
        return Pet.create(pet_data, **query_args)

Content Type

When using body arguments, a default content type is assumed depending on the location. The location / content type mapping can be customized by modifying Blueprint.DEFAULT_LOCATION_CONTENT_TYPE_MAPPING.

DEFAULT_LOCATION_CONTENT_TYPE_MAPPING = {
    "json": "application/json",
    "form": "application/x-www-form-urlencoded",
    "files": "multipart/form-data",

It is also possible to override those defaults in a single resource by passing a string as content_type argument to Blueprint.arguments.

Note

The content type is only used for documentation purpose and has no impact on request parsing.

Note

Multipart requests with mixed types (file, form, etc.) are not supported. They can be achieved but the documentation is not correctly generated. arguments decorator can be called multiple times on the same view function but it should not be called with more that one request body location. This limitation is discussed in #46.

File Upload

File uploads as multipart/form-data are supported for both OpenAPI 3 and OpenAPI 2.

The arguments Schema should contain Upload fields. The files are injected in the view function as a dict of werkzeug FileStorage instances.

from werkzeug.utils import secure_filename
from flask_rest_api.fields import Upload

class MultipartFileSchema(ma.Schema):
    file_1 = Upload()

@blp.route('/', methods=['POST'])
@blp.arguments(MultipartFileSchema, location='files')
@blp.response(code=201)
def func(files):
    base_dir = '/path/to/storage/dir/'
    file_1 = files['file_1']
    file_1.save(secure_filename(file_1.filename))

Response

Use Blueprint.response to specify a Schema class or instance to serialize the response and a status code (defaults to 200).

In the following examples, the GET and PUT methods return an instance of Pet serialized with PetSchema:

@blp.route('/<pet_id>')
class PetsById(MethodView):

    @blp.response(PetSchema)
    def get(self, pet_id):
        return Pet.get_by_id(pet_id)

    @blp.arguments(PetSchema)
    @blp.response(PetSchema)
    def put(self, update_data, pet_id):
        pet = Pet.get_by_id(pet_id)
        pet.update(update_data)
        return pet

Here, the DELETE returns an empty response so no schema is specified.

@blp.route('/<pet_id>')
class PetsById(MethodView):

    @blp.response(code=204)
    def delete(self, pet_id):
        Pet.delete(pet_id)

If a view function returns a list of objects, the Schema must be instanciated with many=True.

@blp.route('/')
class Pets(MethodView):

    @blp.response(PetSchema(many=True))
    def get(self, args):
        return Pet.get()

Note

Even if a view function returns an empty response with a default 200 code, decorating it with Blueprint.response is useful anyway, to return a proper Flask Response object.

ETag

ETag is a web cache validation mechanism. It allows an API client to make conditional requests, such as

  • GET a resource unless it is the same as the version in cache.
  • PUT/PATCH/DELETE a resource unless the version in cache is outdated.

The first case is mostly useful to limit the bandwidth usage, the latter addresses the case where two clients update a resource at the same time (known as the “lost update problem”).

The ETag featured is available through the Blueprint.etag decorator. It can be disabled globally with the ETAG_DISABLED application parameter.

flask-rest-api provides helpers to compute ETag, but ultimately, only the developer knows what data is relevant to use as ETag source, so there can be manual work involved.

ETag Computed with API Response Data

The simplest case is when the ETag is computed using returned data, using the Schema that serializes the data.

In this case, almost eveything is automatic. Only the call to Blueprint.check_etag is manual.

The Schema must be provided explicitly, even though it is the same as the response schema.

@blp.route('/')
class Pet(MethodView):

    @blp.etag
    @blp.response(PetSchema(many=True))
    def get(self):
        return Pet.get()

    @blp.etag
    @blp.arguments(PetSchema)
    @blp.response(PetSchema)
    def post(self, new_data):
        return Pet.create(**new_data)

@blp.route('/<pet_id>')
class PetById(MethodView):

    @blp.etag
    @blp.response(PetSchema)
    def get(self, pet_id):
        return Pet.get_by_id(pet_id)

    @blp.etag
    @blp.arguments(PetSchema)
    @blp.response(PetSchema)
    def put(self, update_data, pet_id):
        pet = Pet.get_by_id(pet_id)
        # Check ETag is a manual action and schema must be provided
        blp.check_etag(pet, PetSchema)
        pet.update(update_data)
        return pet

    @blp.etag
    @blp.response(code=204)
    def delete(self, pet_id):
        pet = Pet.get_by_id(pet_id)
        # Check ETag is a manual action and schema must be provided
        blp.check_etag(pet, PetSchema)
        Pet.delete(pet_id)

ETag Computed with API Response Data Using Another Schema

Sometimes, it is not possible to use the data returned by the view function as ETag data because it contains extra information that is irrelevant, like HATEOAS information, for instance.

In this case, a specific ETag schema should be provided to Blueprint.etag. Then, it does not need to be passed to check_etag.

@blp.route('/')
class Pet(MethodView):

    @blp.etag(PetEtagSchema(many=True))
    @blp.response(PetSchema(many=True))
    def get(self):
        return Pet.get()

    @blp.etag(PetEtagSchema)
    @blp.arguments(PetSchema)
    @blp.response(PetSchema)
    def post(self, new_pet):
        return Pet.create(**new_data)

@blp.route('/<int:pet_id>')
class PetById(MethodView):

    @blp.etag(PetEtagSchema)
    @blp.response(PetSchema)
    def get(self, pet_id):
        return Pet.get_by_id(pet_id)

    @blp.etag(PetEtagSchema)
    @blp.arguments(PetSchema)
    @blp.response(PetSchema)
    def put(self, new_pet, pet_id):
        pet = Pet.get_by_id(pet_id)
        # Check ETag is a manual action and schema must be provided
        blp.check_etag(pet)
        pet.update(update_data)
        return pet

    @blp.etag(PetEtagSchema)
    @blp.response(code=204)
    def delete(self, pet_id):
        pet = self._get_pet(pet_id)
        # Check ETag is a manual action, ETag schema is used
        blp.check_etag(pet)
        Pet.delete(pet_id)

ETag Computed on Arbitrary Data

The ETag can also be computed from arbitrary data by calling Blueprint.set_etag manually.

The example below illustrates this with no ETag schema, but it is also possible to pass an ETag schema to set_etag and check_etag or equivalently to Blueprint.etag.

@blp.route('/')
class Pet(MethodView):

    @blp.etag
    @blp.response(PetSchema(many=True))
    def get(self):
        pets = Pet.get()
        # Compute ETag using arbitrary data
        blp.set_etag([pet.update_time for pet in pets])
        return pets

    @blp.etag
    @blp.arguments(PetSchema)
    @blp.response(PetSchema)
    def post(self, new_data):
        # Compute ETag using arbitrary data
        blp.set_etag(new_data['update_time'])
        return Pet.create(**new_data)

@blp.route('/<pet_id>')
class PetById(MethodView):

    @blp.etag
    @blp.response(PetSchema)
    def get(self, pet_id):
        # Compute ETag using arbitrary data
        blp.set_etag(new_data['update_time'])
        return Pet.get_by_id(pet_id)

    @blp.etag
    @blp.arguments(PetSchema)
    @blp.response(PetSchema)
    def put(self, update_data, pet_id):
        pet = Pet.get_by_id(pet_id)
        # Check ETag is a manual action
        blp.check_etag(pet, ['update_time'])
        pet.update(update_data)
        # Compute ETag using arbitrary data
        blp.set_etag(new_data['update_time'])
        return pet

    @blp.etag
    @blp.response(code=204)
    def delete(self, pet_id):
        pet = Pet.get_by_id(pet_id)
        # Check ETag is a manual action
        blp.check_etag(pet, ['update_time'])
        Pet.delete(pet_id)

ETag Not Checked Warning

It is up to the developer to call Blueprint.check_etag in the view function. It can’t be automatic.

If ETag is enabled and check_etag is not called, a warning is logged at runtime. When in DEBUG or TESTING mode, an exception is raised.

Include Headers Content in ETag

When ETag is computed with response data, that data may contain headers. It is up to the developer to decide whether this data should be part of the ETag.

By default, only pagination header is included in the ETag computation. This can be changed by customizing Blueprint.ETAG_INCLUDE_HEADERS.

OpenAPI

flask-rest-api automatically generates an OpenAPI documentation (formerly known as Swagger) for the API.

That documentation can be made accessible as a JSON file, along with a nice web interface such as ReDoc or Swagger UI.

Specify Versions

The version of the API and the version of the OpenAPI specification can be specified as Flask application parameters:

API_VERSION

Version of the API. It is copied verbatim in the documentation. It should be a string, even it the version is a number.

Default: '1'

OPENAPI_VERSION

Version of the OpenAPI standard used to describe the API. It should be provided as a string.

The OpenAPI version must be passed either as application parameter or at Api initialization in spec_kwargs parameters.

Add Documentation Information to Resources

Add Summary and Description

flask-rest-api uses view functions docstrings to fill the summary and description attributes of an operation object.

def get(...):
    """Find pets by ID

    Return pets based on ID.
    ---
    Internal comment not meant to be exposed.
    """

The part of the docstring following the '---' line is ignored.

The part before the '---' line is used as summary and description. The first lines are used as summary. If an empty line is met, all following lines are used as description.

The example above produces the following documentation attributes:

{
    'get': {
        'summary': 'Find pets by ID',
        'description': 'Return pets based on ID',
    }
}

The delimiter line is the line starting with the delimiter string defined in Blueprint.DOCSTRING_INFO_DELIMITER. This string defaults to "---" and can be customized in a subclass. None means “no delimiter”: the whole docstring is included in the docs.

Document Operations Parameters and Responses

Schemas passed in Blueprint.arguments to deserialize arguments are parsed automatically to generate corresponding documentation. Additional example and examples parameters can be used to provide examples (those are only valid for OpenAPI v3).

Likewise, schemas passed in Blueprint.response to serialize responses are parsed automatically to generate corresponding documentation. Additional example and examples parameters can be used to provide examples (examples is only valid for OpenAPI v3). Additional headers parameters can be used to document response headers.

Document Path Parameters

Path parameters are automatically documented. The type in the documentation is inferred from the path parameter converter used in the URL rule. Custom path parameters should be registered for their type to be correctly determined (see below).

The Blueprint.route method takes a parameters argument to pass documentation for parameters that are shared by all operations of a path. It can be used to pass extra documentation, such as examples, for path parameters.

Pass Extra Documentation Information

flask-rest-api tries to document the API as automatically as possible and to provide explicit means to pass extra-information that can’t be inferred from the code, such as descriptions, examples, etc.

The Blueprint.doc decorator provides a means to pass extra documentation information. It comes in handy if an OpenAPI feature is not supported, but it suffers from a few limitations, and it should be considered a last resort solution until flask-rest-api is improved to fit the need.

Known issues and alternatives are discussed in issue #71.

Populate the Root Document Object

Additional root document attributes can be passed either in the code, in Api parameter spec_kwargs, or as Flask app configuration parameters.

app.config['API_SPEC_OPTIONS'] = {'x-internal-id': '2'}

api = Api(app, spec_kwargs={'host': 'example.com', 'x-internal-id': '1'})

Note that app.config overrides spec_kwargs. The example above produces

{'host': 'example.com', 'x-internal-id': '2', ...}

Note

Again, flask-rest-api tries to provide as much information as possible, but some values can only by provided by the user.

When using OpenAPI v2, basePath is automatically set from the value of the flask parameter APPLICATION_ROOT. In OpenAPI v3, basePath is removed, and the servers attribute can only be set by the user.

Document Top-level Components

Documentation components can be passed by accessing the internal apispec Components object.

 api = Api(app)
 api.spec.components.parameter(
   'Pet name',
   'query',
   {'description': 'Item ID', 'format': 'int32', 'required': True}
)

Register Custom Fields

Standard marshmallow Field classes are documented with the correct type and format.

When using custom fields, the type and format must be passed, either explicitly or by specifying a parent field class, using Api.register_field():

# Map to ('string', 'ObjectId') passing type and format
api.register_field(ObjectId, 'string', 'ObjectId')

# Map to ('string') passing type
api.register_field(CustomString, 'string', None)

# Map to ('integer, 'int32') passing a code marshmallow field
api.register_field(CustomInteger, ma.fields.Integer)

Register Custom Path Parameter Converters

Likewise, standard types used as path parameter converters in the flask routes are correctly documented, but custom path converters must be registered.

The Api.register_converter() allows to register a converter in the Api object to generate an accurate documentation.

# Register MongoDB's ObjectId converter in Flask application
app.url_map.converters['objectid'] = ObjectIdConverter

# Register converter in Api
api.register_converter(ObjectIdConverter, 'string', 'ObjectID')

@blp.route('/pets/{objectid:pet_id}')
    ...

Enforce Order in OpenAPI Specification File

When a Blueprint is registered, a tag is created with the Blueprint name. The display order in the interface is the Blueprint registration order. And the display order inside a tag is the order in which the resources are defined in the Blueprint.

In the OpenAPI specification file, the fields of a Schema are documented as schema properties. Although objects are not ordered in JSON, OpenAPI graphical interfaces tend to respect the order in which the properties are defined in the properties object in the specification file.

When using an ordererd Schema, the fields definition order is preserved when generating the specification file and the properties are displayed in that order.

This is typically done in a base class:

class MyBaseSchema(ma.Schema):
    class Meta:
        ordered = True

class User(MyBaseSchema):
    name = ma.fields.String()
    surname = ma.fields.String()

Passing ordered Meta attribute is not necessary when using a Python version for which dictionaries are always ordered (>= 3.7 or CPython 3.6).

Serve the OpenAPI Documentation

Now that that the documentation is generated, it should be made available to the clients. flask-rest-api can define routes to provide both the documentation as a JSON file and a nice web interface to browse it interactively. This feature is accessible through Flask app parameters.

OPENAPI_URL_PREFIX

Defines the base path for both the JSON file and the UI. If None, the documentation is not served and the following parameters are ignored.

Default: None

OPENAPI_JSON_PATH

Path to the JSON file, relative to the base path.

Default: openapi.json

Both ReDoc and Swagger UI interfaces are available to present the API.

Their configuration logics are similar. If a path is set, then flask-rest-api creates a route in the application to serve the interface page, using the JS script from a user defined URL, if any, or from a CDN URL built with the version number.

OPENAPI_REDOC_PATH

If not None, path to the ReDoc page, relative to the base path.

Default: None

OPENAPI_REDOC_URL

URL to the ReDoc script. If None, a CDN version is used.

Default: None

OPENAPI_REDOC_VERSION

ReDoc version as string. Should be an existing version number, latest (latest 1.x version) or next (latest 2.x version).

This is used to build the CDN URL if OPENAPI_REDOC_URL is None.

On a production instance, it is recommended to specify a fixed version number.

Default: 'latest'

OPENAPI_SWAGGER_UI_PATH

If not None, path to the Swagger UI page, relative to the base path.

Default: None

OPENAPI_SWAGGER_UI_URL

URL to the Swagger UI script. If None, a CDN version is used.

Default: None

OPENAPI_SWAGGER_UI_VERSION

Swagger UI version as string. Contrary to ReDoc, there is no default value pointing to the latest version, so it must be specified.

This is used to build the CDN URL if OPENAPI_SWAGGER_UI_URL is None.

Default: None

OPENAPI_SWAGGER_UI_SUPPORTED_SUBMIT_METHODS

List of methods for which the ‘Try it out!’ feature is enabled. Should be a list of lowercase HTTP methods.

Passing an empty list disables the feature globally.

Default: ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace']

Warning

The version strings are not checked by flask-rest-api. They are used as is to build the URL pointing to the UI script. Typos won’t be caught.

API Reference

API Reference

flask_rest_api.abort(http_status_code, exc=None, **kwargs)[source]

Raise a HTTPException for the given http_status_code. Attach any keyword arguments to the exception for later processing.

From Flask-Restful. See NOTICE file for license information.

Api

class flask_rest_api.Api(app=None, *, spec_kwargs=None)[source]

Main class

Provides helpers to build a REST API using Flask.

Parameters:
  • app (Flask) – Flask application
  • spec_kwargs (dict) – kwargs to pass to internal APISpec instance

The spec_kwargs dictionary is passed as kwargs to the internal APISpec instance. flask-rest-api adds a few parameters to the original parameters documented in apispec.APISpec:

Parameters:
  • flask_plugin (apispec.BasePlugin) – Flask plugin
  • marshmallow_plugin (apispec.BasePlugin) – Marshmallow plugin
  • extra_plugins (list|tuple) – List of additional BasePlugin instances
  • openapi_version (str) – OpenAPI version. Can also be passed as application parameter OPENAPI_VERSION.

This allows the user to override default Flask and marshmallow plugins.

title and version APISpec parameters can’t be passed here, they are set according to the app configuration.

For more flexibility, additional spec kwargs can also be passed as app parameter API_SPEC_OPTIONS.

register_converter(converter, conv_type, conv_format=None)

Register custom path parameter converter

Parameters:
  • converter (BaseConverter) – Converter Subclass of werkzeug’s BaseConverter
  • conv_type (str) – Parameter type
  • conv_format (str) – Parameter format (optional)

Example:

# Register MongoDB's ObjectId converter in Flask application
app.url_map.converters['objectid'] = ObjectIdConverter

# Register converter in Api
api.register_converter(ObjectIdConverter, 'string', 'ObjectID')

@blp.route('/pets/{objectid:pet_id}')
    ...

api.register_blueprint(blp)

Once the converter is registered, all paths using it will have corresponding path parameter documented with the right type and format.

Should be called before registering paths with Blueprint.route.

register_field(field, *args)

Register custom Marshmallow field

Registering the Field class allows the Schema parser to set the proper type and format when documenting parameters from Schema fields.

Parameters:field (Field) – Marshmallow Field class

*args can be:

  • a pair of the form (type, format) to map to
  • a core marshmallow field type (then that type’s mapping is used)

Examples:

# Map to ('string', 'ObjectId') passing type and format
api.register_field(ObjectId, 'string', 'ObjectId')

# Map to ('string') passing type
api.register_field(CustomString, 'string', None)

# Map to ('integer, 'int32') passing a code marshmallow field
api.register_field(CustomInteger, ma.fields.Integer)

Should be called before registering schemas with schema.

handle_http_exception(error)

Return a JSON response containing a description of the error

This method is registered at app init to handle HTTPException.

  • When abort is called in the code, an HTTPException is triggered and Flask calls this handler.
  • When an exception is not caught in a view, Flask makes it an InternalServerError and calls this handler.

flask_rest_api republishes webargs’s abort. This abort allows the caller to pass kwargs and stores them in exception.data so that the error handler can use them to populate the response payload.

Extra information expected by this handler:

  • message (str): a comment
  • errors (dict): errors, typically validation errors in
    parameters and request body
  • headers (dict): additional headers
init_app(app, *, spec_kwargs=None)[source]

Initialize Api with application

register_blueprint(blp, **options)[source]

Register a blueprint in the application

Also registers documentation for the blueprint/resource

Parameters:
  • blp (Blueprint) – Blueprint to register
  • options (dict) – Keyword arguments overriding Blueprint defaults

Must be called after app is initialized.

Blueprint

class flask_rest_api.Blueprint(*args, **kwargs)[source]

Blueprint that registers info in API documentation

arguments(schema, *, location='json', content_type=None, required=True, description=None, example=None, examples=None, **kwargs)

Decorator specifying the schema used to deserialize parameters

Parameters:
  • schema (type|Schema) – Marshmallow Schema class or instance used to deserialize and validate the argument.
  • location (str) – Location of the argument.
  • content_type (str) – Content type of the argument. Should only be used in conjunction with json, form or files location. The default value depends on the location and is set in Blueprint.DEFAULT_LOCATION_CONTENT_TYPE_MAPPING. This is only used for documentation purpose.
  • required (bool) – Whether argument is required (default: True).
  • description (str) – Argument description.
  • example (dict) – Parameter example.
  • examples (list) – List of parameter examples.
  • kwargs (dict) – Keyword arguments passed to the webargs use_args decorator used internally.

The required and description only affect body arguments (OpenAPI 2) or requestBody (OpenAPI 3), because the docs expose the whole schema. For other locations, the schema is turned into an array of parameters and the required/description value of each parameter item is taken from the corresponding field in the schema.

The example and examples parameters are mutually exclusive and should only be used with OpenAPI 3 and when location is json.

See Arguments.

response(schema=None, *, code=200, description=None, example=None, examples=None, headers=None)

Decorator generating an endpoint response

Parameters:
  • schemaSchema class or instance. If not None, will be used to serialize response data.
  • code (int|str|HTTPStatus) – HTTP status code (default: 200). Used if none is returned from the view function.
  • description (str) – Description of the response (default: None).
  • example (dict) – Example of response message.
  • examples (list) – Examples of response message.
  • headers (dict) – Headers returned by the response.

The decorated function is expected to return the same types of value than a typical flask view function, except the body part may be an object or a list of objects to serialize with the schema, rather than a string.

If the decorated function returns a Response object, the schema and code parameters are only used to document the resource.

The example and examples parameters are mutually exclusive. The latter should only be used with OpenAPI 3.

The example, examples and headers parameters are only used to document the resource.

See Response.

paginate(pager=None, *, page=None, page_size=None, max_page_size=None)

Decorator adding pagination to the endpoint

Parameters:
  • pager (Page) – Page class used to paginate response data
  • page (int) – Default requested page number (default: 1)
  • page_size (int) – Default requested page size (default: 10)
  • max_page_size (int) – Maximum page size (default: 100)

If a Page class is provided, it is used to paginate the data returned by the view function, typically a lazy database cursor.

Otherwise, pagination is handled in the view function.

The decorated function may return a tuple including status and/or headers, like a typical flask view function. It may not return a Response object.

See Pagination.

etag(etag_schema=None)

Decorator generating an endpoint response

Parameters:etag_schemaSchema class or instance. If not None, will be used to serialize etag data.

Can be used as either a decorator or a decorator factory:

Example:

@blp.etag
def view_func(...):
    ...

@blp.etag(EtagSchema)
def view_func(...):
    ...

The etag decorator expects the decorated view function to return a Response object. It is the case if it is decorated with the response decorator.

See ETag.

check_etag(etag_data, etag_schema=None)

Compare If-Match header with computed ETag

Raise 412 if If-Match-Header does not match.

Must be called from resource code to check ETag.

Unfortunately, there is no way to call it automatically. It is the developer’s responsability to do it. However, a warning is logged at runtime if this function was not called.

set_etag(etag_data, etag_schema=None)

Set ETag for this response

Raise 304 if ETag identical to If-None-Match header

Must be called from resource code, unless the view function is decorated with the response decorator, in which case the ETag is computed by default from response data if set_etag is not called.

Logs a warning if called in a method other than one of GET, HEAD, POST, PUT, PATCH.

static doc(**kwargs)[source]

Decorator adding description attributes to a view function

Values passed as kwargs are copied verbatim in the docs

Example:

@blp.doc(description="Return pets based on ID",
         summary="Find pets by ID"
)
def get(...):
    ...
register_views_in_doc(app, spec)[source]

Register views information in documentation

If a schema in a parameter or a response appears in the spec schemas section, it is replaced by a reference in the parameter or response documentation:

“schema”:{“$ref”: “#/components/schemas/MySchema”}

route(rule, *, parameters=None, **options)[source]

Decorator to register url rule in application

Also stores doc info for later registration

Use this to decorate a MethodView or a resource function.

Parameters:
  • rule (str) – URL rule as string.
  • endpoint (str) – Endpoint for the registered URL rule (defaults to function name).
  • parameters (list) – List of parameters relevant to all operations in this path, only used to document the resource.
  • options (dict) – Options to be forwarded to the underlying werkzeug.routing.Rule object.

Fields

Custom marshmallow fields

class flask_rest_api.fields.Upload(format='binary', **kwargs)[source]

File upload field

Parameters:format (str) – File content encoding (binary, base64). Only relevant to OpenAPI 3. Only used for documentation purpose.

Project Info

Changelog

0.17.0 (2019-09-19)

Features:

  • Backwards-incompatible: Only return status code and short name in error handler (#84).
  • Backwards-incompatible: Remove logging from error handler. Logging can be achieved in application code by overriding handle_http_exception. Remove _prepare_error_response_content. Reponse payload is computed in handle_http_exception. (#85)
  • Backwards-incompatible: Remove InvalidLocationError. The mapping from webargs locations to OAS locations is done in apispec and no exception is raised if an invalid location is passed. (#81)
  • Add content_type argument to Blueprint.arguments and provide reasonable default content type for form and files (#83).
  • Add description parameter to Blueprint.arguments to pass description for requestBody (#93).
  • Allow customization of docstring delimiter string (#49).
  • Support file uploads as multipart/form-data (#97).

Bug fixes:

  • Fix documentation of form and files arguments: use requestBody in OAS3, document content type (#83).

Other changes:

  • Backwards-incompatible: Don’t republish NestedQueryArgsParser anymore. This belongs to user code and can be copied from webargs doc (#94).
  • Backwards-incompatible: Bump minimum apispec version to 3.0.0.

0.16.1 (2019-07-15)

Bug fixes:

  • Fix detection of unhandled exceptions in error handler for Flask=>1.1.0 (#82).

Other changes:

  • Bump minimum Flask version to 1.1.0. From this version on, uncaught exceptions are passed to the error handler as InternalServerError with the exception attached as original_exception attribute. (#82)

0.16.0 (2019-06-20)

Features:

  • Add parameters argument to Blueprint.route to pass documentation for parameters that are shared by all operations of a path (#78).

Other changes:

  • Backwards-incompatible: Bump minimum apispec version to 2.0.0.
  • Backwards-incompatible: Path parameters documentation passed in Blueprint.doc is no longer merged with automatic documentation. It should be passed in Blueprint.route instead.
  • Backwards-incompatible: Remove Api.schema and Api.definition. Those methods are useless since Schema components are automatically registered by apispec. Manual component registration is still possible using the internal apispec Components object. (#75)

0.15.1 (2019-06-18)

Bug fixes:

  • marshmallow 3.0.0rc7 compatibility (#77).

0.15.0 (2019-05-09)

Features:

  • Add parameters to pass examples and headers in Blueprint.response decorator (#63).
  • Add parameters to pass examples for requestBody in OpenAPI v3 in Blueprint.arguments decorator (#68).
  • Support status codes expressed as HTTPStatus in Blueprint.response decorator (#60). Thanks @Regzand for reporting.

Other changes:

  • Bump minimum apispec version to 1.3.2.
  • Bump minimum werkzeug version to 0.15. With 0.14.x versions, 412 responses are returned with no content.
  • Backwards-incompatible: When using Blueprint.doc decorator to provide additional documentation to the response described in the Blueprint.response decorator, the user must use the same format (str, int or HTTPStatus) to express the status code in both decorators. This is a side-effect of (#60). Now that headers and examples can be described in Blueprint.response, this should not be a common use case.

0.14.1 (2019-04-18)

Features:

  • Official Python 3.7 support (#45).
  • Rename Api.definition as Api.schema. Keep Api.definition as an alias to Api.schema for backward compatibility (#53).

Bug fixes:

  • Fix passing route with path parameter default value (#58). Thanks @zedrdave for reporting.
  • When no descrition is provided to Blueprint.response, don’t add an empty string as description in the docs.
  • Fix returning a tuple subclass from a view function. Only raw tuple instances are considered as Flask’s (return value, status, headers). tuple subclasses are treated as list and can be paginated/dumped. Raw tuple return values should be cast to another type (e.g. list) to be distinguished from (return value, status, headers) tuple. (#52) Thanks @asyncee for reporting.

0.14.0 (2019-03-08)

Features:

  • Allow view functions decorated with response to return a Response object or a tuple with status and/or headers (#40).
  • Allow view functions decorated with paginate to return a tuple with status and/or headers (#40). The pagination header is now passed in the response tuple. Users relying on undocumented get_context()['headers'] as a workaround to pass headers must update their code to pass headers in the response tuple as well.

Bug fixes:

  • Fix ETag computation when headers contain a duplicate key.

0.13.1 (2019-02-13)

Features:

  • Register Werkzeug’s UUIDConverter in Api so that uuid path parameters are correctly documented.

0.13.0 (2019-02-12)

Features:

  • Add flask_plugin and marshmallow_plugin spec kwargs to allow overriding base plugins.
  • Backwards-incompatible: Rename plugins spec kwarg into extra_plugins.
  • Backwards-incompatible: Don’t default to OpenAPI version 2.0. The version must now be specified, either as OPENAPI_VERSION app parameter or as openapi_version spec kwarg.
  • Support apispec 1.0.0.
  • Backwards-incompatible: Drop support for apispec 0.x.

0.12.0 (2018-12-02)

Features:

  • Backwards-incompatible: Api.register_converter doesn’t register converter in Flask app anymore. It should be registered manually using app.url_map.converters['converter_name'] = Converter.
  • Api.definition, Api.register_field and Api.register_converter can be called before app initialization. The information is buffered and passed to the internal APISpec object when it is created, in Api.init_app.

0.11.2 (2018-11-28)

Bug fixes:

  • Fix typo in ErrorHandlerMixin._prepare_error_response_content.

0.11.1 (2018-11-20)

Features:

  • The HTTP_METHODS list that defines the order of the methods in the spec is now a class attribute of Blueprint. It can be overridden to enforce another order.

Bug fixes:

  • Import Mapping from collections.abc rather than collections. The latter is deprecated in Python 3.7 and will be removed in 3.8.
  • Merge manual doc added with Blueprint.doc with automatic documentation after auto doc is prepared (i.e. adapted to OpenAPI version) (#19). Thanks @fbergroth for reporting.
  • Merge automatic path parameter documentation with existing manual doc rather than append as duplicate parameter (#23). Thanks @congenica-andrew for reporting.
  • Fix path parameter documentation structure when using OpenAPI v3.
  • Document http status codes as strings, not integers.
  • Fix use of Swagger UI config parameter OPENAPI_SWAGGER_UI_URL.

Other changes:

  • 100% test coverage !

0.11.0 (2018-11-09)

Features:

  • Backwards-incompatible: Rework of the ETag feature. It is now accesible using dedicated Blueprint.etag decorator. check_etag and set_etag are methods of Blueprint and etag.INCLUDE_HEADERS is replaced with Blueprint.ETAG_INCLUDE_HEADERS. It is enabled by default (only on views decorated with Blueprint.etag) and disabled with ETAG_DISABLED application configuration parameter. is_etag_enabled is now private. (#21)
  • Backwards-incompatible: The response decorator returns a Response object rather than a (Response object, status code) tuple. The status code is set in the Response object.
  • Support apispec 1.0.0b5.

0.10.0 (2018-10-24)

Features:

  • Backwards-incompatible: Don’t prefix all routes in the spec with APPLICATION_ROOT. If using OpenAPI v2, set APPLICATION_ROOT as basePath. If using OpenAPI v3, the user should specify servers manually.
  • Backwards-incompatible: In testing and debug modes, verify_check_etag not only logs a warning but also raises CheckEtagNotCalledError if check_etag is not called in a resource that needs it.

0.9.2 (2018-10-16)

Features:

  • Api.register_blueprint passes **options keyword parameters to app.register_blueprint to override Blueprint defaults. Thanks @dryobates for the suggestion.

0.9.1 (2018-10-11)

Features:

  • Support apispec 1.0.0b3.

Bug fixes:

  • Fix crash when serving documentation at root of application. Thanks @fbergroth for the suggestion.

0.9.0 (2018-10-01)

Features:

  • Backwards-incompatible: When pagination parameters are out of range, the API does not return a 404 error anymore. It returns a 200 code with an empty list and pagination metadata (#10).
  • Backwards-incompatible: Remove dependency on python-dateutil. This is an optional marshmallow dependency. Whether it is needed to deserialize date, time, or datetime strings depends on the application.
  • Rework internal features by using mixin classes. This makes the code cleaner and adds customization possibilities (#9).
  • Backwards-incompatible: DEFAULT_PAGINATION_PARAMETERS is a class attribute of Blueprint.
  • Backwards-incompatible: When no Page class is passed to pagination, (i.e. when doing pagination in view function), the pagination parameters are passed as a PaginationParameters object. The item count must be passed by setting it as item_count attribute of the PaginationParameters object. The set_item_count function is removed.
  • The pagination header name can be configured by overriding PAGINATION_HEADER_FIELD_NAME class attribute of Blueprint. If set to None, no pagination header is added to the response.
  • Backwards-incompatible: The paginate decorator doesn’t use NestedQueryFlaskParser by default. It is renamed as NestedQueryArgsParser and it can be used by overriding Blueprint.ARGUMENTS_PARSER.
  • Backwards-incompatible: Drop Flask 0.x support. Flask>=1.0 is now required.
  • Default error handler is registered for generic HTTPException. Other extensions may register other handlers for specific exceptions or codes (#12).

0.8.1 (2018-09-24)

Features:

  • Add page (page number) to pagination metadata.
  • Set produces and consumes root document attributes when using OpenAPI v2.

Bug fixes:

  • Document body parameter correctly when using OpenAPI v3.

0.8.0 (2018-09-20)

Features:

  • Add API_SPEC_OPTIONS app config parameter. Thanks @xalioth for the suggestion.
  • Backwards-incompatible: Api accepts a spec_kargs parameter, passed as kwargs to the internal APISpec instance. spec_plugins is removed, plugins shall be passed as spec_kwargs={'plugins': [...]}.
  • Backwards-incompatible: Get summary and description from docstrings (#5).
  • Add support for marshmallow 3.0.0b13. 2.x and 3b are now supported.
  • Add support for apispec 1.0.0b2. 0.x and 1b are now supported.

Bug fixes:

  • Document response schema correctly when using OpenAPI 3 (#8). Thanks @ffarella for reporting.

0.7.0 (2018-07-19)

Other changes:

  • Backwards-incompatible: Remove _wrapper_class from Page. Creating a custom pager is easier by just overriding Page methods.
  • Backwards-incompatible: Let OPENAPI_SWAGGER_UI_SUPPORTED_SUBMIT_METHODS default to “all methods” list.

0.6.1 (2018-06-29)

Bug fixes:

  • Swagger UI integration: respect OPENAPI_SWAGGER_UI_URL configuration paramater.
  • Api.register_field: use APISpec.register_field rather than access self.spec.ma_plugin directly.

0.6.0 (2018-06-29)

Features:

  • Backwards-incompatible: Use apispec 0.39.0 plugin class interface.
  • Backwards-incompatible: Expose APISpec’s register_field and register_converter methods from Api object. Api.register_converter signature is modified to make name parameter optional.
  • Pass extra apispec plugins to internal APISpec instance.
  • Backwards-incompatible: Drop official support for Python 3.4.

0.5.2 (2018-06-21)

Features:

  • Pass OpenAPI version as OPENAPI_VERSION app config parameter.
  • Add Swagger UI (3.x) integration.

0.5.1 (2018-06-18)

Features:

  • ReDoc: Use unpkg CDN for 2.x version.

0.5.0 (2018-06-05)

Features:

  • Backwards-incompatible: In Blueprint.route, the endpoint name defaults to the function name with the case unchanged. Before this change, the name was lowercased.
  • Backwards-incompatible: Pagination is now managed by dedicated Blueprint.paginate decorator.
  • Add etag.INCLUDE_HEADERS to specify which headers to use for ETag computation (defaults to ['X-Pagination']).
  • In verify_check_etag, endpoint name is added to the warning message.

0.4.2 (2018-04-27)

Bug fixes:

  • Pagination: don’t crash if item_count is not set, just log a warning and set no pagination header.
  • API spec: Fix leading/trailing slash issues in api-docs Blueprint. Fixes compatibility with Flask 1.0.

0.4.1 (2018-04-17)

Features:

  • Allow multiple calls to Blueprint.arguments on a view function.
  • Enforce order of fields in PaginationParametersSchema and PaginationMetadataSchema.
  • Minor improvements in test_examples.py.

0.4.0 (2018-04-05)

Features:

  • Backwards-incompatible: The case of a parameter both in URL and in arguments Schema is now unsupported.
  • Backwards-incompatible: By default, Schema parameter passed in Blueprint.arguments is documented as required.
  • Backwards-incompatible: APISpec.register_field now uses apispec API. It must be passed a (type, format) couple or an already registered Field class (this includes base marshmallow Fields. When using (type, format), format doesn’t default to None anymore.
  • Preserve order when serving the spec file: - Fields are printed in declaration order if Schema.Meta.ordered is True - Methods in a method view are printed in this order: [‘OPTIONS’, ‘HEAD’, ‘GET’, ‘POST’, ‘PUT’, ‘PATCH’, ‘DELETE’] - Paths are added in declaration order

Bug fixes:

  • Document response as array when using paginate_with.

0.3.0 (2018-03-02)

Features:

  • Add leading and trailing / to OPENAPI_URL_PREFIX if missing.
  • Backwards-incompatible: Change default URL path for OpenAPI JSON to 'openapi.json'.

Bug fixes:

  • Fix OpenAPI docs URL paths.
  • Backwards-incompatible: Blueprint.route(self, rule, **options) matches flask’s Blueprint signature.

0.2.0 (2018-03-02)

Features:

  • format parameter in register_converter and register_field is now optional and defaults to None.
  • APISpec inherits from original apispec.APISpec.
  • Backwards-incompatible: The internal APISpec instance is now exposed as public attribute spec of Api. register_converter and register_field are not proxied anymore by Api and must be called on spec.
  • Backwards-incompatible: Api.register_converter takes a name parameter and registers a converter in the Flask application as well as in its internal APISpec instance.
  • Backwards-incompatible: Api.register_spec_plugin is removed. api.register_spec_plugin(...) shall be replaced with api.spec.setup_plugin(...).

0.1.1 (2018-02-16)

Bug fixes:

  • Fix version number.

Support:

  • Add dev-requirements.txt.

0.1.0 (2018-02-16)

First release.

License

MIT License

Copyright (c) 2016-2019 Nobatek/INEF4 and contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Authors

Leads

Contributors (chronological)