Welcome to Flask-RESTPlus’s documentation!

Flask-RestPlus provide syntaxic suger, helpers and automatically generated Swagger documentation on top of Flask-Restful.

Compatibility

flask-restplus requires Python 2.7+.

Installation

You can install flask-restplus with pip:

$ pip install flask-restplus

or with easy_install:

$ easy_install flask-restplus

Documentation

This part of the documentation will show you how to get started in using Flask-RESTPlus with Flask.

Installation

Install Flask-RESTPlus with pip:

pip install flask-restful

The development version can be downloaded from GitHub.

git clone https://github.com/noirbizarre/flask-restplus.git
cd flask-restplus
pip install -e .[dev,test]

Flask-RESTful requires Python version 2.6, 2.7, 3.3, 3.4 or 3.5. It’s also working with PyPy and PyPy3.

Quick start

This guide assumes you have a working understanding of Flask, and that you have already installed both Flask and Flask-RESTPlus. If not, then follow the steps in the Installation section.

Initialization

As every other extension, you can initialize it with an application object:

from flask import Flask
from flask.ext.restplus import Api

app = Flask(__name__)
api = Api(app)

of lazily with the factory pattern:

from flask import Flask
from flask.ext.restplus import Api

api = Api()

app = Flask(__name__)
api.init_app(app)

A Minimal API

A minimal Flask-RESTPlus API looks like this:

from flask import Flask
from flask_restplus import Resource, Api

app = Flask(__name__)
api = Api(app)

@api.route('/hello')
class HelloWorld(Resource):
    def get(self):
        return {'hello': 'world'}

if __name__ == '__main__':
    app.run(debug=True)

Save this as api.py and run it using your Python interpreter. Note that we’ve enabled Flask debugging mode to provide code reloading and better error messages.

$ python api.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader

Warning

Debug mode should never be used in a production environment!

Now open up a new prompt to test out your API using curl:

$ curl http://127.0.0.1:5000/hello
{"hello": "world"}

You can also use the automatic documentation on you API root (by default). In this case: http://127.0.0.1:5000/. See Swagger UI for a complete documentation on the automatic documentation.

Resourceful Routing

The main building block provided by Flask-RESTPlus are resources. Resources are built on top of Flask pluggable views, giving you easy access to multiple HTTP methods just by defining methods on your resource. A basic CRUD resource for a todo application (of course) looks like this:

from flask import Flask, request
from flask_restplus import Resource, Api

app = Flask(__name__)
api = Api(app)

todos = {}

@api.route('/<string:todo_id>')
class TodoSimple(Resource):
    def get(self, todo_id):
        return {todo_id: todos[todo_id]}

    def put(self, todo_id):
        todos[todo_id] = request.form['data']
        return {todo_id: todos[todo_id]}

if __name__ == '__main__':
    app.run(debug=True)

You can try it like this:

$ curl http://localhost:5000/todo1 -d "data=Remember the milk" -X PUT
{"todo1": "Remember the milk"}
$ curl http://localhost:5000/todo1
{"todo1": "Remember the milk"}
$ curl http://localhost:5000/todo2 -d "data=Change my brakepads" -X PUT
{"todo2": "Change my brakepads"}
$ curl http://localhost:5000/todo2
{"todo2": "Change my brakepads"}

Or from python if you have the Requests library installed:

>>> from requests import put, get
>>> put('http://localhost:5000/todo1', data={'data': 'Remember the milk'}).json()
{u'todo1': u'Remember the milk'}
>>> get('http://localhost:5000/todo1').json()
{u'todo1': u'Remember the milk'}
>>> put('http://localhost:5000/todo2', data={'data': 'Change my brakepads'}).json()
{u'todo2': u'Change my brakepads'}
>>> get('http://localhost:5000/todo2').json()
{u'todo2': u'Change my brakepads'}

Flask-RESTPlus understands multiple kinds of return values from view methods. Similar to Flask, you can return any iterable and it will be converted into a response, including raw Flask response objects. Flask-RESTful also support setting the response code and response headers using multiple return values, as shown below:

class Todo1(Resource):
    def get(self):
        # Default to 200 OK
        return {'task': 'Hello world'}

class Todo2(Resource):
    def get(self):
        # Set the response code to 201
        return {'task': 'Hello world'}, 201

class Todo3(Resource):
    def get(self):
        # Set the response code to 201 and return custom headers
        return {'task': 'Hello world'}, 201, {'Etag': 'some-opaque-string'}

Endpoints

Many times in an API, your resource will have multiple URLs. You can pass multiple URLs to the add_resource() method or to the route() decorator, both on the Api object. Each one will be routed to your Resource:

api.add_resource(HelloWorld, '/hello', '/world')

# or

@api.route('/hello', '/world')
class HelloWorld(Resource):
    pass

You can also match parts of the path as variables to your resource methods.

api.add_resource(Todo, '/todo/<int:todo_id>', endpoint='todo_ep')

# or

@api.route('/todo/<int:todo_id>', endpoint='todo_ep')
class HelloWorld(Resource):
    pass

Note

If a request does not match any of your application’s endpoints, Flask-RESTPlus will return a 404 error message with suggestions of other endpoints that closely match the requested endpoint. This can be disabled by setting ERROR_404_HELP to False in your application config.

Argument Parsing

While Flask provides easy access to request data (i.e. querystring or POST form encoded data), it’s still a pain to validate form data. Flask-RESTPlus has built-in support for request data validation using a library similar to argparse.

from flask_restplus import reqparse

parser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate to charge for this resource')
args = parser.parse_args()

Note

Unlike the argparse module, parse_args() returns a Python dictionary instead of a custom data structure.

Using the RequestParser class also gives you sane error messages for free. If an argument fails to pass validation, Flask-RESTPlus will respond with a 400 Bad Request and a response highlighting the error.

$ curl -d 'rate=foo' http://127.0.0.1:5000/todos
{'status': 400, 'message': 'foo cannot be converted to int'}

The inputs module provides a number of included common conversion functions such as date() and url().

Calling parse_args() with strict=True ensures that an error is thrown if the request includes arguments your parser does not define.

args = parser.parse_args(strict=True)

Data Formatting

By default, all fields in your return iterable will be rendered as-is. While this works great when you’re just dealing with Python data structures, it can become very frustrating when working with objects. To solve this problem, Flask-RESTPlus provides the fields module and the marshal_with() decorator. Similar to the Django ORM and WTForm, you use the fields module to describe the structure of your response.

from collections import OrderedDict

from flask import Flask
from flask_restplus import fields, Api, Resource

app = Flask(__name__)
api = Api(app)

model = api.model('Model', {
    'task': fields.String,
    'uri': fields.Url('todo_ep')
})

class TodoDao(object):
    def __init__(self, todo_id, task):
        self.todo_id = todo_id
        self.task = task

        # This field will not be sent in the response
        self.status = 'active'

@api.route('/todo')
class Todo(Resource):
    @api.marshal_with(model)
    def get(self, **kwargs):
        return TodoDao(todo_id='my_todo', task='Remember the milk')

The above example takes a python object and prepares it to be serialized. The marshal_with() decorator will apply the transformation described by model. The only field extracted from the object is task. The fields.Url field is a special field that takes an endpoint name and generates a URL for that endpoint in the response. Using the marshal_with() decorator also document the output in the swagger specifications. Many of the field types you need are already included. See the fields guide for a complete list.

Full example

See the Full example section for fully functionnal example.

Response marshalling

Flask-RESTPlus provides an easy way to control what data you actually render in your response or expect as in input payload. With the fields module, you can use whatever objects (ORM models/custom classes/etc.) you want in your resource. fields also lets you format and filter the response so you don’t have to worry about exposing internal data structures.

It’s also very clear when looking at your code what data will be rendered and how it will be formatted.

Basic Usage

You can define a dict or OrderedDict of fields whose keys are names of attributes or keys on the object to render, and whose values are a class that will format & return the value for that field. This example has three fields: two are String and one is a DateTime, formatted as an ISO 8601 datetime string (RFC 822 is supported as well):

from flask_restplus import Resource, fields

model = api.model('Model', {
    'name': fields.String,
    'address': fields.String,
    'date_updated': fields.DateTime(dt_format='rfc822'),
})

@api.route('/todo')
class Todo(Resource):
    @api.marshal_with(model, envelope='resource')
    def get(self, **kwargs):
        return db_get_todo()  # Some function that queries the db

This example assumes that you have a custom database object (todo) that has attributes name, address, and date_updated. Any additional attributes on the object are considered private and won’t be rendered in the output. An optional envelope keyword argument is specified to wrap the resulting output.

The decorator marshal_with() is what actually takes your data object and applies the field filtering. The marshalling can work on single objects, dicts, or lists of objects.

Note

marshal_with() is a convenience decorator, that is functionally equivalent to:

class Todo(Resource):
    def get(self, **kwargs):
        return marshal(db_get_todo(), model), 200

The @api.marshal_with decorator add the swagger documentation ability.

This explicit expression can be used to return HTTP status codes other than 200 along with a successful response (see abort() for errors).

Renaming Attributes

Often times your public facing field name is different from your internal field name. To configure this mapping, use the attribute keyword argument.

model = {
    'name': fields.String(attribute='private_name'),
    'address': fields.String,
}

A lambda (or any callable) can also be specified as the attribute

model = {
    'name': fields.String(attribute=lambda x: x._private_name),
    'address': fields.String,
}

Nested properties can also be accessed with attribute:

model = {
    'name': fields.String(attribute='people_list.0.person_dictionary.name'),
    'address': fields.String,
}

Default Values

If for some reason your data object doesn’t have an attribute in your fields list, you can specify a default value to return instead of None.

model = {
    'name': fields.String(default='Anonymous User'),
    'address': fields.String,
}

Custom Fields & Multiple Values

Sometimes you have your own custom formatting needs. You can subclass the fields.Raw class and implement the format function. This is especially useful when an attribute stores multiple pieces of information. e.g. a bit-field whose individual bits represent distinct values. You can use fields to multiplex a single attribute to multiple output values.

This example assumes that bit 1 in the flags attribute signifies a “Normal” or “Urgent” item, and bit 2 signifies “Read” or “Unread”. These items might be easy to store in a bitfield, but for a human readable output it’s nice to convert them to seperate string fields.

class UrgentItem(fields.Raw):
    def format(self, value):
        return "Urgent" if value & 0x01 else "Normal"

class UnreadItem(fields.Raw):
    def format(self, value):
        return "Unread" if value & 0x02 else "Read"

model = {
    'name': fields.String,
    'priority': UrgentItem(attribute='flags'),
    'status': UnreadItem(attribute='flags'),
}

Url & Other Concrete Fields

Flask-RESTPlus includes a special field, fields.Url, that synthesizes a uri for the resource that’s being requested. This is also a good example of how to add data to your response that’s not actually present on your data object.

class RandomNumber(fields.Raw):
    def output(self, key, obj):
        return random.random()

model = {
    'name': fields.String,
    # todo_resource is the endpoint name when you called api.route()
    'uri': fields.Url('todo_resource'),
    'random': RandomNumber,
}

By default fields.Url returns a relative uri. To generate an absolute uri that includes the scheme, hostname and port, pass the keyword argument absolute=True in the field declaration. To override the default scheme, pass the scheme keyword argument:

model = {
    'uri': fields.Url('todo_resource', absolute=True)
    'https_uri': fields.Url('todo_resource', absolute=True, scheme='https')
}

Complex Structures

You can have a flat structure that marshal() will transform to a nested structure:

>>> from flask_restplus import fields, marshal
>>> import json
>>>
>>> resource_fields = {'name': fields.String}
>>> resource_fields['address'] = {}
>>> resource_fields['address']['line 1'] = fields.String(attribute='addr1')
>>> resource_fields['address']['line 2'] = fields.String(attribute='addr2')
>>> resource_fields['address']['city'] = fields.String
>>> resource_fields['address']['state'] = fields.String
>>> resource_fields['address']['zip'] = fields.String
>>> data = {'name': 'bob', 'addr1': '123 fake street', 'addr2': '', 'city': 'New York', 'state': 'NY', 'zip': '10468'}
>>> json.dumps(marshal(data, resource_fields))
'{"name": "bob", "address": {"line 1": "123 fake street", "line 2": "", "state": "NY", "zip": "10468", "city": "New York"}}'

Note

The address field doesn’t actually exist on the data object, but any of the sub-fields can access attributes directly from the object as if they were not nested.

List Field

You can also unmarshal fields as lists

>>> from flask_restplus import fields, marshal
>>> import json
>>>
>>> resource_fields = {'name': fields.String, 'first_names': fields.List(fields.String)}
>>> data = {'name': 'Bougnazal', 'first_names' : ['Emile', 'Raoul']}
>>> json.dumps(marshal(data, resource_fields))
>>> '{"first_names": ["Emile", "Raoul"], "name": "Bougnazal"}'

Nested Field

While nesting fields using dicts can turn a flat data object into a nested response, you can use Nested to unmarshal nested data structures and render them appropriately.

>>> from flask_restplus import fields, marshal
>>> import json
>>>
>>> address_fields = {}
>>> address_fields['line 1'] = fields.String(attribute='addr1')
>>> address_fields['line 2'] = fields.String(attribute='addr2')
>>> address_fields['city'] = fields.String(attribute='city')
>>> address_fields['state'] = fields.String(attribute='state')
>>> address_fields['zip'] = fields.String(attribute='zip')
>>>
>>> resource_fields = {}
>>> resource_fields['name'] = fields.String
>>> resource_fields['billing_address'] = fields.Nested(address_fields)
>>> resource_fields['shipping_address'] = fields.Nested(address_fields)
>>> address1 = {'addr1': '123 fake street', 'city': 'New York', 'state': 'NY', 'zip': '10468'}
>>> address2 = {'addr1': '555 nowhere', 'city': 'New York', 'state': 'NY', 'zip': '10468'}
>>> data = { 'name': 'bob', 'billing_address': address1, 'shipping_address': address2}
>>>
>>> json.dumps(marshal_with(data, resource_fields))
'{"billing_address": {"line 1": "123 fake street", "line 2": null, "state": "NY", "zip": "10468", "city": "New York"}, "name": "bob", "shipping_address": {"line 1": "555 nowhere", "line 2": null, "state": "NY", "zip": "10468", "city": "New York"}}'

This example uses two Nested fields. The Nested constructor takes a dict of fields to render as sub-fields.input. The important difference between the Nested constructor and nested dicts (previous example), is the context for attributes. In this example, billing_address is a complex object that has its own fields and the context passed to the nested field is the sub-object instead of the original data object. In other words: data.billing_address.addr1 is in scope here, whereas in the previous example data.addr1 was the location attribute. Remember: Nested and List objects create a new scope for attributes.

Use Nested with List to marshal lists of more complex objects:

user_fields = api.model('User', {
    'id': fields.Integer,
    'name': fields.String,
})

user_list_fields = api.model('UserList', {
    'users': fields.List(fields.Nested(user_fields)),
})

The api.model() factory

The model() factory allows you to instanciate and register models to your API or Namespace.

my_fields = api.model('MyModel', {
    'name': fields.String,
    'age': fields.Integer(min=0)
})

# Equivalent to
my_fields = Model('MyModel', {
    'name': fields.String,
    'age': fields.Integer(min=0)
})
api.models[my_fields.name] = my_fields

Duplicating with clone

The Model.extend() method allows you to instanciate an augmented model. It saves you duplicating all fields.

parent = Model('Parent', {
    'name': fields.String
})

child = parent.extend('Child', {
    'age': fields.Integer
})

The Api/Namespace.clone also register it on the API.

parent = api.model('Parent', {
    'name': fields.String
})

child = api.extend('Child', parent, {
    'age': fields.Integer
})

Polymorphism with api.inherit

The Model.inherit() method allows to extend a model in the “Swagger way” and to start handling polymorphism.

parent = api.model('Parent', {
    'name': fields.String,
    'class': fields.String(discriminator=True)
})

child = api.inherit('Child', parent, {
    'extra': fields.String
})

The Api/Namespace.clone will register both the parent and the child in the Swagger models definitions.

parent = Model('Parent', {
    'name': fields.String,
    'class': fields.String(discriminator=True)
})

child = parent.inherit('Child', {
    'extra': fields.String
})

The class field in this example will be populated with the serialized model name only if the property does not exists in the serialized object.

The Polymorph field allows you to specify a mapping between Python classes and fields specifications.

mapping = {
    Child1: child1_fields,
    Child2: child2_fields,
}

fields = api.model('Thing', {
    owner: fields.Polymorph(mapping)
})

Custom fields

Custom output fields let you perform your own output formatting without having to modify your internal objects directly. All you have to do is subclass Raw and implement the format() method:

class AllCapsString(fields.Raw):
    def format(self, value):
        return value.upper()


# example usage
fields = {
    'name': fields.String,
    'all_caps_name': AllCapsString(attribute=name),
}

You can also use the __schema_format__, __schema_type__ and __schema_example__ to specify the produced types and examples:

class MyIntField(fields.Integer):
    __schema_format__ = 'int64'

class MySpecialField(fields.Raw):
    __schema_type__ = 'some-type'
    __schema_format__ = 'some-format'

class MyVerySpecialField(fields.Raw):
    __schema_example__ = 'hello, world'

Request Parsing

Warning

The whole request parser part of Flask-RESTPlus is slated for removal and will be replaced by documentation on how to integrate with other packages that do the input/output stuff better (such as marshmallow). This means that it will be maintained until 2.0 but consider it deprecated. Don’t worry, if you have code using that now and wish to continue doing so, it’s not going to go away any time too soon.

Flask-RESTPlus’s request parsing interface, reqparse, is modeled after the argparse interface. It’s designed to provide simple and uniform access to any variable on the flask.request object in Flask.

Basic Arguments

Here’s a simple example of the request parser. It looks for two arguments in the flask.Request.values dict: an integer and a string

from flask_restplus import reqparse

parser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate cannot be converted')
parser.add_argument('name')
args = parser.parse_args()

Note

The default argument type is a unicode string. This will be str in python3 and unicode in python2.

If you specify the help value, it will be rendered as the error message when a type error is raised while parsing it. If you do not specify a help message, the default behavior is to return the message from the type error itself. See Error Messages for more details.

Note

By default, arguments are not required. Also, arguments supplied in the request that are not part of the RequestParser will be ignored.

Note

Arguments declared in your request parser but not set in the request itself will default to None.

Required Arguments

To require a value be passed for an argument, just add required=True to the call to add_argument().

parser.add_argument('name', required=True, help="Name cannot be blank!")

Multiple Values & Lists

If you want to accept multiple values for a key as a list, you can pass action='append'

parser.add_argument('name', action='append')

This will let you make queries like

curl http://api.example.com -d "name=bob" -d "name=sue" -d "name=joe"

And your args will look like this

args = parser.parse_args()
args['name']    # ['bob', 'sue', 'joe']

Other Destinations

If for some reason you’d like your argument stored under a different name once it’s parsed, you can use the dest keyword argument.

parser.add_argument('name', dest='public_name')

args = parser.parse_args()
args['public_name']

Argument Locations

By default, the RequestParser tries to parse values from flask.Request.values, and flask.Request.json.

Use the location argument to add_argument() to specify alternate locations to pull the values from. Any variable on the flask.Request can be used. For example:

# Look only in the POST body
parser.add_argument('name', type=int, location='form')

# Look only in the querystring
parser.add_argument('PageSize', type=int, location='args')

# From the request headers
parser.add_argument('User-Agent', location='headers')

# From http cookies
parser.add_argument('session_id', location='cookies')

# From file uploads
parser.add_argument('picture', type=werkzeug.datastructures.FileStorage, location='files')

Note

Only use type=list when location='json'. See this issue for more details

Multiple Locations

Multiple argument locations can be specified by passing a list to location:

parser.add_argument('text', location=['headers', 'values'])

When multiple locations are specified, the arguments from all locations specified are combined into a single MultiDict. The last location listed takes precedence in the result set.

If the argument location list includes the headers location the argument names will no longer be case insensitive and must match their title case names (see str.title()). Specifying location='headers' (not as a list) will retain case insensitivity.

Parser Inheritance

Often you will make a different parser for each resource you write. The problem with this is if parsers have arguments in common. Instead of rewriting arguments you can write a parent parser containing all the shared arguments and then extend the parser with copy(). You can also overwrite any argument in the parent with replace_argument(), or remove it completely with remove_argument(). For example:

from flask_restplus import reqparse

parser = reqparse.RequestParser()
parser.add_argument('foo', type=int)

parser_copy = parser.copy()
parser_copy.add_argument('bar', type=int)

# parser_copy has both 'foo' and 'bar'

parser_copy.replace_argument('foo', required=True, location='json')
# 'foo' is now a required str located in json, not an int as defined
#  by original parser

parser_copy.remove_argument('foo')
# parser_copy no longer has 'foo' argument

Error Handling

The default way errors are handled by the RequestParser is to abort on the first error that occurred. This can be beneficial when you have arguments that might take some time to process. However, often it is nice to have the errors bundled together and sent back to the client all at once. This behavior can be specified either at the Flask application level or on the specific RequestParser instance. To invoke a RequestParser with the bundling errors option, pass in the argument bundle_errors. For example

from flask_restplus import reqparse

parser = reqparse.RequestParser(bundle_errors=True)
parser.add_argument('foo', type=int, required=True)
parser.add_argument('bar', type=int, required=True)

# If a request comes in not containing both 'foo' and 'bar', the error that
# will come back will look something like this.

{
    "message":  {
        "foo": "foo error message",
        "bar": "bar error message"
    }
}

# The default behavior would only return the first error

parser = RequestParser()
parser.add_argument('foo', type=int, required=True)
parser.add_argument('bar', type=int, required=True)

{
    "message":  {
        "foo": "foo error message"
    }
}

The application configuration key is “BUNDLE_ERRORS”. For example

from flask import Flask

app = Flask(__name__)
app.config['BUNDLE_ERRORS'] = True

Warning

BUNDLE_ERRORS is a global setting that overrides the bundle_errors option in individual RequestParser instances.

Error Messages

Error messages for each field may be customized using the help parameter to Argument (and also RequestParser.add_argument).

If no help parameter is provided, the error message for the field will be the string representation of the type error itself. If help is provided, then the error message will be the value of help.

help may include an interpolation token, {error_msg}, that will be replaced with the string representation of the type error. This allows the message to be customized while preserving the original error:

from flask_restplus import reqparse


parser = reqparse.RequestParser()
parser.add_argument(
    'foo',
    choices=('one', 'two'),
    help='Bad choice: {error_msg}'
)

# If a request comes in with a value of "three" for `foo`:

{
    "message":  {
        "foo": "Bad choice: three is not a valid choice",
    }
}

Error handling

HTTPException handling

Werkzeug HTTPException are automatically properly seriliazed reusing the description attribute.

from werkzeug.exceptions import BadRequest
raise BadRequest()

will return a 400 HTTP code and output

{
    "message": "The browser (or proxy) sent a request that this server could not understand."
}

whereas this:

from werkzeug.exceptions import BadRequest
raise BadRequest('My custom message')

will output

{
    "message": "My custom message"
}

You can attach extras attributes to the output by providing a data attribute to your exception.

from werkzeug.exceptions import BadRequest
e = BadRequest('My custom message')
e.data = {'custom': 'value'}
raise e

will output

{
    "message": "My custom message",
    "custom": "value"
}

The Flask abort helper

The abort helper properly wraps errors into a HTTPException so it will have the same behavior.

from flask import abort
abort(400)

will return a 400 HTTP code and output

{
    "message": "The browser (or proxy) sent a request that this server could not understand."
}

whereas this:

from flask import abort
abort(400, 'My custom message')

will output

{
    "message": "My custom message"
}

The Flask-RESTPlus abort helper

The errors.abort() and the Namespace.abort() helpers works like the original Flask flask.abort() but it will also add the keyword arguments to the response.

from flask_restplus import abort
abort(400, custom='value')

will return a 400 HTTP code and output

{
    "message": "The browser (or proxy) sent a request that this server could not understand.",
    "custom": "value"
}

whereas this:

from flask import abort
abort(400, 'My custom message', custom='value')

will output

{
    "message": "My custom message",
    "custom": "value"
}

The @api.errorhandler decorator

The @api.errorhandler decorator allows you to register a specific handler for a given exception, in the same manner that you can do with Flask/Blueprint @errorhandler decorator.

@api.errorhandler(CustomException)
def handle_custom_exception(error):
    '''Return a custom message and 400 status code'''
    return {'message': 'What you want'}, 400


@api.errorhandler(AnotherException)
def handle_another_exception(error):
    '''Return a custom message and 500 status code'''
    return {'message': error.specific}


@api.errorhandler(FakeException)
def handle_fake_exception_with_header(error):
    '''Return a custom message and 400 status code'''
    return {'message': error.message}, 400, {'My-Header': 'Value'}

You can also document the error:

@api.errorhandler(FakeException)
@api.marshal_with(error_fields, code=400)
@api.header('My-Header',  'Some description')
def handle_fake_exception_with_header(error):
    '''This is a custom error'''
    return {'message': error.message}, 400, {'My-Header': 'Value'}


@api.route('/test/')
class TestResource(Resource):
    def get(self):
        '''
        Do something

        :raises CustomException: In case of something
        '''
        pass

In this example, the :raise: docstring will be automatically extracted and the response 400 will be documented properly.

It also allows for overriding the default error handler when used wihtout parameter:

@api.errorhandler
def default_error_handler(error):
    '''Default error handler'''
    return {'message': str(error)}, getattr(error, 'code', 500)

Fields masks

Flask-Restplus support partial object fetching (aka. fields mask) by supplying a custom header in the request.

By default the header is X-Fields but it can be changed with the RESTPLUS_MASK_HEADER parameter.

Syntax

The syntax is actually quite simple. You just provide a coma separated list of field names, optionally wrapped in brackets.

# These two mask are equivalents
mask = '{name,age}'
# or
mask = 'name,age'
data = requests.get('/some/url/', headers={'X-Fields': mask})
assert len(data) == 2
assert 'name' in data
assert 'age' in data

To specify a nested fields mask, simply provide it in bracket following the field name:

mask = '{name, age, pet{name}}'

Nesting specification works with nested object or list of objects:

# Will apply the mask {name} to each pet
# in the pets list.
mask = '{name, age, pets{name}}'

There is a special star token meaning “all remaining fields”. It allows to only specify nested filtering:

# Will apply the mask {name} to each pet
# in the pets list and take all other root fields
# without filtering.
mask = '{pets{name},*}'

# Will not filter anything
mask = '*'

Usage

By default, each time you use api.marshal or @api.marshal_with, the mask will be automatically applied if the header is present.

The header will be exposed as a Swagger parameter each time you use the @api.marshal_with decorator.

As Swagger does not permit exposing a global header once it can make your Swagger specifications a lot more verbose. You can disable this behavior by setting RESTPLUS_MASK_SWAGGER to False.

You can also specify a default mask that will be applied if no header mask is found.

class MyResource(Resource):
    @api.marshal_with(my_model, mask='name,age')
    def get(self):
        pass

Default mask can also be handled at model level:

model = api.model('Person', {
    'name': fields.String,
    'age': fields.Integer,
    'boolean': fields.Boolean,
}, mask='{name,age}')

It will be exposed into the model x-mask vendor field:

{"definitions": {
    "Test": {
        "properties": {
            "age": {"type": "integer"},
            "boolean": {"type": "boolean"},
            "name": {"type": "string"}
        },
        "x-mask": "{name,age}"
    }
}}

To override default masks, you need to give another mask or pass * as mask.

Swagger documentation

A Swagger API documentation is automatically generated and available on your API root but you need to provide some details with the @api.doc() decorator.

Documenting with the @api.doc() decorator

This decorator allows you specify some details about your API. They will be used in the Swagger API declarations.

You can document a class or a method.

@api.route('/my-resource/<id>', endpoint='my-resource')
@api.doc(params={'id': 'An ID'})
class MyResource(Resource):
    def get(self, id):
        return {}

    @api.doc(responses={403: 'Not Authorized'})
    def post(self, id):
        api.abort(403)

Automatically documented models

All models instanciated with model(), clone() and inherit() will be automatically documented in your swagger specifications

The inherit() will register both the parent and the child in the Swagger models definitions.

parent = api.model('Parent', {
    'name': fields.String,
    'class': fields.String(discriminator=True)
})

child = api.inherit('Child', parent, {
    'extra': fields.String
})

Will produce the following Swagger definitions:

"Parent": {
    "properties": {
        "name": {"type": "string"},
        "class": {"type": "string"}
    },
    "discriminator": "class",
    "required": ["class"]
},
"Child": {
    "allOf": [{
            "$ref": "#/definitions/Parent"
        }, {
            "properties": {
                "extra": {"type": "string"}
            }
        }
    ]
}

The @api.marshal_with() decorator

This decorator works like the raw marshal_with() decorator with the difference that it documents the methods. The optional parameter code allows you to specify the expected HTTP status code (200 by default). The optional parameter as_list allows you to specify whether or not the objects are returned as a list.

resource_fields = api.model('Resource', {
    'name': fields.String,
})

@api.route('/my-resource/<id>', endpoint='my-resource')
class MyResource(Resource):
    @api.marshal_with(resource_fields, as_list=True)
    def get(self):
        return get_objects()

    @api.marshal_with(resource_fields, code=201)
    def post(self):
        return create_object(), 201

The Api.marshal_list_with() decorator is strictly equivalent to Api.marshal_with(fields, as_list=True)().

resource_fields = api.model('Resource', {
    'name': fields.String,
})

@api.route('/my-resource/<id>', endpoint='my-resource')
class MyResource(Resource):
    @api.marshal_list_with(resource_fields)
    def get(self):
        return get_objects()

    @api.marshal_with(resource_fields)
    def post(self):
        return create_object()

The @api.expect() decorator

The @api.expect() decorator allows you to specify the expected input fields. It accepts an optional boolean parameter validate defining wether or not the payload should be validated. The validation behavior can be customized globally by either setting the RESTPLUS_VALIDATE configuration to True or passing validate=True to the API constructor.

The following syntaxes are equivalents:

resource_fields = api.model('Resource', {
    'name': fields.String,
})

@api.route('/my-resource/<id>')
class MyResource(Resource):
    @api.expect(resource_fields)
    def get(self):
        pass
resource_fields = api.model('Resource', {
    'name': fields.String,
})

@api.route('/my-resource/<id>')
class MyResource(Resource):
    @api.doc(body=resource_fields)
    def get(self):
        pass

It allows you specify lists as expected input too:

resource_fields = api.model('Resource', {
    'name': fields.String,
})

@api.route('/my-resource/<id>')
class MyResource(Resource):
    @api.expect([resource_fields])
    def get(self):
        pass

Or a RequestParser:

parser = api.parser()
parser.add_argument('param', type=int, help='Some param', location='form')
parser.add_argument('in_files', type=FileStorage, location='files')


@api.route('/with-parser/', endpoint='with-parser')
class WithParserResource(restplus.Resource):
    @api.expect(parser)
    def get(self):
        return {}

An exemple of on-demand validation:

resource_fields = api.model('Resource', {
    'name': fields.String,
})

@api.route('/my-resource/<id>')
class MyResource(Resource):
    # Payload validation disabled
    @api.expect(resource_fields)
    def post(self):
        pass

    # Payload validation enabled
    @api.expect(resource_fields, validate=True)
    def post(self):
        pass

An exemple of application-wide validation by config:

app.config['RESTPLUS_VALIDATE'] = True

api = Api(app)

resource_fields = api.model('Resource', {
    'name': fields.String,
})

@api.route('/my-resource/<id>')
class MyResource(Resource):
    # Payload validation enabled
    @api.expect(resource_fields)
    def post(self):
        pass

    # Payload validation disabled
    @api.expect(resource_fields, validate=False)
    def post(self):
        pass

An exemple of application-wide validation by constructor:

api = Api(app, validate=True)

resource_fields = api.model('Resource', {
    'name': fields.String,
})

@api.route('/my-resource/<id>')
class MyResource(Resource):
    # Payload validation enabled
    @api.expect(resource_fields)
    def post(self):
        pass

    # Payload validation disabled
    @api.expect(resource_fields, validate=False)
    def post(self):
        pass

Documenting with the @api.response() decorator

The @api.response() decorator allows you to document the known responses and is a shortcut for @api.doc(responses='...').

The following synatxes are equivalents:

@api.route('/my-resource/')
class MyResource(Resource):
    @api.response(200, 'Success')
    @api.response(400, 'Validation Error')
    def get(self):
        pass


@api.route('/my-resource/')
class MyResource(Resource):
    @api.doc(responses={
        200: 'Success',
        400: 'Validation Error'
    })
    def get(self):
        pass

You can optionally specify a response model as third argument:

model = api.model('Model', {
    'name': fields.String,
})

@api.route('/my-resource/')
class MyResource(Resource):
    @api.response(200, 'Success', model)
    def get(self):
        pass

If you use the @api.marshal_with() decorator, it automatically document the response:

model = api.model('Model', {
    'name': fields.String,
})

@api.route('/my-resource/')
class MyResource(Resource):
    @api.response(400, 'Validation error')
    @api.marshal_with(model, code=201, description='Object created')
    def post(self):
        pass

At least, you can specify a default response sent without knowing the response code

@api.route('/my-resource/')
class MyResource(Resource):
    @api.response('default', 'Error')
    def get(self):
        pass

The @api.route() decorator

You can provide class-wide documentation by using the Api.route()‘s’ doc parameter. It accept the same attribute/syntax than the Api.doc() decorator.

By example, these two declaration are equivalents:

@api.route('/my-resource/<id>', endpoint='my-resource')
@api.doc(params={'id': 'An ID'})
class MyResource(Resource):
    def get(self, id):
        return {}
@api.route('/my-resource/<id>', endpoint='my-resource', doc={params:{'id': 'An ID'}})
class MyResource(Resource):
    def get(self, id):
        return {}

Documenting the fields

Every Flask-Restplus fields accepts optional arguments used to document the field:

  • required: a boolean indicating if the field is always set (default: False)
  • description: some details about the field (default: None)
  • example: an example to use when displaying (default: None)

There is also field specific attributes.

The String field accept the following optional arguments:

  • enum: an array restricting the authorized values.
  • min_length: the minimum length expected
  • max_length: the maximum length expected
  • pattern: a RegExp pattern the string need to validate

The Integer, Float and Arbitrary fields accept the following optional arguments:

  • min: restrict the minimum accepted value.
  • max: restrict the maximum accepted value.
  • exclusiveMin: if True, minimum value is not in allowed interval.
  • exclusiveMax: if True, maximum value is not in allowed interval.
  • multiple: specify that the number must be a multiple of this value.

The DateTime field also accept the min, max`, ``exclusiveMin and exclusiveMax optional arguments but they should be date or datetime (either as ISO strings or native objects).

my_fields = api.model('MyModel', {
    'name': fields.String(description='The name', required=True),
    'type': fields.String(description='The object type', enum=['A', 'B']),
    'age': fields.Integer(min=0),
})

Documenting the methods

Each resource will be documented as a Swagger path.

Each resource method (get, post, put, delete, path, options, head) will be documented as a swagger operation.

You can specify the Swagger unique operationId with the id documentation.

@api.route('/my-resource/')
class MyResource(Resource):
    @api.doc(id='get_something')
    def get(self):
        return {}

You can also use the first argument for the same purpose:

@api.route('/my-resource/')
class MyResource(Resource):
    @api.doc('get_something')
    def get(self):
        return {}

If not specified, a default operationId is provided with the following pattern:

{{verb}}_{{resource class name | camelCase2dashes }}

In the previous example, the default generated operationId will be get_my_resource

You can override the default operationId generator by giving a callable as default_id parameter to your API. This callable will receive two positional arguments:

  • the resource class name
  • this lower cased HTTP method
def default_id(resource, method):
    return ''.join((method, resource))

api = Api(app, default_id=default_id)

In the previous example, the generated operationId will be getMyResource

Each operation will automatically receive the namespace tag. If the resource is attached to the root API, it will receive the default namespace tag.

Method parameters

For each method, the path parameter are automatically extracted. You can provide additional parameters (from query parameters, body or form) or additional details on path parameters with the params documentation.

Input and output models

You can specify the serialized output model with the model documentation.

You can specify an input format for POST and PUT with the body documentation.

fields = api.model('MyModel', {
    'name': fields.String(description='The name', required=True),
    'type': fields.String(description='The object type', enum=['A', 'B']),
    'age': fields.Integer(min=0),
})


@api.model(fields={'name': fields.String, 'age': fields.Integer})
class Person(fields.Raw):
    def format(self, value):
        return {'name': value.name, 'age': value.age}


@api.route('/my-resource/<id>', endpoint='my-resource')
@api.doc(params={'id': 'An ID'})
class MyResource(Resource):
    @api.doc(model=fields)
    def get(self, id):
        return {}

    @api.doc(model='MyModel', body=Person)
    def post(self, id):
        return {}

You can’t have body and form or file parameters at the same time, it will raise a SpecsError.

Models can be specified with a RequestParser.

parser = api.parser()
parser.add_argument('param', type=int, help='Some param', location='form')
parser.add_argument('in_files', type=FileStorage, location='files')

@api.route('/with-parser/', endpoint='with-parser')
class WithParserResource(restplus.Resource):
    @api.doc(parser=parser)
    def get(self):
        return {}

Note

The decoded payload will be available as a dictionary in the payload attribute in the request context.

@api.route('/my-resource/')
class MyResource(Resource):
    def get(self):
        data = api.payload

Headers

You can document headers with the @api.header decorator shortcut.

@api.route('/with-headers/')
@api.header('X-Header', 'Some expected header', required=True)
class WithHeaderResource(restplus.Resource):
    @api.header('X-Collection', type=[str], collectionType='csv')
    def get(self):
        pass

Cascading

Documentation handling is done in cascade. Method documentation override class-wide documentation. Inherited documentation override parent one.

By example, these two declaration are equivalents:

@api.route('/my-resource/<id>', endpoint='my-resource')
@api.doc(params={'id': 'An ID'})
class MyResource(Resource):
    def get(self, id):
        return {}
@api.route('/my-resource/<id>', endpoint='my-resource')
@api.doc(params={'id': 'Class-wide description'})
class MyResource(Resource):
    @api.doc(params={'id': 'An ID'})
    def get(self, id):
        return {}

You can also provide method specific documentation from a class decoration. The following example will produce the same documentation than the two previous examples:

@api.route('/my-resource/<id>', endpoint='my-resource')
@api.doc(params={'id': 'Class-wide description'})
@api.doc(get={'params': {'id': 'An ID'}})
class MyResource(Resource):
    def get(self, id):
        return {}

Marking as deprecated

You can mark as deprecated some resources or methods with the @api.deprecated decorator:

# Deprecate the full resource
@api.deprecated
@api.route('/resource1/')
class Resource1(Resource):
    def get(self):
        return {}

# Hide methods
@api.route('/resource4/')
class Resource4(Resource):
    def get(self):
        return {}

    @api.deprecated
    def post(self):
        return {}

    def put(self):
        return {}

Hiding from documentation

You can hide some resources or methods from documentation using one of the following syntaxes:

# Hide the full resource
@api.route('/resource1/', doc=False)
class Resource1(Resource):
    def get(self):
        return {}

@api.route('/resource2/')
@api.doc(False)
class Resource2(Resource):
    def get(self):
        return {}

@api.route('/resource3/')
@api.hide
class Resource3(Resource):
    def get(self):
        return {}

# Hide methods
@api.route('/resource4/')
@api.doc(delete=False)
class Resource4(Resource):
    def get(self):
        return {}

    @api.doc(False)
    def post(self):
        return {}

    @api.hide
    def put(self):
        return {}

    def delete(self):
        return {}

Documenting autorizations

In order to document an authorization you can provide an authorization dictionary to the API constructor:

authorizations = {
    'apikey': {
        'type': 'apiKey',
        'in': 'header',
        'name': 'X-API-KEY'
    }
}
api = Api(app, authorizations=authorizations)

Next, you need to set the authorization documentation on each resource/method requiring it. You can use a decorator to make it easier:

def apikey(func):
    return api.doc(security='apikey')(func)

@api.route('/resource/')
class Resource1(Resource):
    @apikey
    def get(self):
        pass

    @api.doc(security='apikey')
    def post(self):
        pass

You can apply this requirement globally with the security constructor parameter:

authorizations = {
    'apikey': {
        'type': 'apiKey',
        'in': 'header',
        'name': 'X-API-KEY'
    }
}
api = Api(app, authorizations=authorizations, security='apikey')

You can have multiple security schemes:

authorizations = {
    'apikey': {
        'type': 'apiKey',
        'in': 'header',
        'name': 'X-API'
    },
    'oauth2': {
        'type': 'oauth2',
        'flow': 'accessCode',
        'tokenUrl': 'https://somewhere.com/token',
        'scopes': {
            'read': 'Grant read-only access',
            'write': 'Grant read-write access',
        }
    }
}
api = Api(self.app, security=['apikey', {'oauth2': 'read'}], authorizations=authorizations)

And compose/override them at method level:

@api.route('/authorizations/')
class Authorized(Resource):
    @api.doc(security=[{'oauth2': ['read', 'write']}])
    def get(self):
        return {}

You can disable security on a given resource/method by passing None or an empty list as security parameter:

@api.route('/without-authorization/')
class WithoutAuthorization(Resource):
    @api.doc(security=[])
    def get(self):
        return {}

    @api.doc(security=None)
    def post(self):
        return {}

Export Swagger specifications

You can export the Swagger specififcations corresponding to your API.

from flask import json

from myapp import api

print(json.dumps(api.__schema__))

Swagger UI

By default flask-restplus provide a Swagger UI documentation on your API root.

from flask import Flask
from flask_restplus import Api, Resource, fields

app = Flask(__name__)
api = Api(app, version='1.0', title='Sample API',
    description='A sample API',
)

@api.route('/my-resource/<id>')
@api.doc(params={'id': 'An ID'})
class MyResource(Resource):
    def get(self, id):
        return {}

    @api.response(403, 'Not Authorized')
    def post(self, id):
        api.abort(403)


if __name__ == '__main__':
    app.run(debug=True)

If you run the code below and visit your API root URL (http://localhost:5000) you will have an automatically generated SwaggerUI documentation.

_images/screenshot-apidoc-quickstart.png

Customization

You can control the Swagger UI path with the doc parameter (default to the API root):

from flask import Flask, Blueprint
from flask_restplus import Api

app = Flask(__name__)
blueprint = Blueprint('api', __name__, url_prefix='/api')
api = Api(blueprint, doc='/doc/')

app.register_blueprint(blueprint)

assert url_for('api.doc') == '/api/doc/'

You can specify a custom validator url by setting config.SWAGGER_VALIDATOR_URL:

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)
app.config.SWAGGER_VALIDATOR_URL = 'http://domain.com/validator'

api = Api(app)

You can also specify the initial expansion state with the config.SWAGGER_UI_DOC_EXPANSION setting (none, list or full):

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)
app.config.SWAGGER_UI_DOC_EXPANSION = 'list'

api = Api(app)

Latest version of Swagger UI added an optionnal JSON editor which can be enabled with with the config.SWAGGER_UI_JSONEDITOR:

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)
app.config.SWAGGER_UI_JSONEDITOR = True

api = Api(app)

If you need a custom UI, you can register a custom view function with the documentation() decorator. You can provide a custom UI by reusing the apidoc blueprint or rolling your own from scratch.

from flask import Flask
from flask_restplus import API, apidoc

app = Flask(__name__)
api = Api(app)

@api.documentation
def custom_ui():
    return apidoc.ui_for(api)

Disabling the documentation

You can totally disable the generated Swagger UI by setting doc=False:

from flask import Flask
from flask_restplus import Api

app = Flask(__name__)
api = Api(app, doc=False)

Postman

To help you testing, you can export your API as a Postman collection.

from flask import json

from myapp import api

urlvars = False  # Build query strings in URLs
swagger = True  # Export Swagger specifications
data = api.as_postman(urlvars=urlvars, swagger=swagger)
print(json.dumps(data))

Scaling your project

This page covers building a slightly more complex Flask-RESTPlus app that will cover out some best practices when setting up a real-world Flask-RESTful-based API. The Quick start section is great for getting started with your first Flask-RESTplus app, so if you’re new to Flask-RESTPlus you’d be better off checking that out first.

Multiple namespaces

There are many different ways to organize your Flask-RESTPlus app, but here we’ll describe one that scales pretty well with larger apps and maintains a nice level organization.

Flask-RESTPlus provides a way to use almost the same pattern as Blueprint. The main idea is to split your app into reusables namespaces.

Here’s an example directory structure:

project/
├── app.py
├── core
│   ├── __init__.py
│   ├── utils.py
│   └── ...
└── apis
    ├── __init__.py
    ├── namespace1.py
    ├── namespace2.py
    ├── ...
    └── namespaceX.py

The app module will serve as a main application entry point following one of the classic Flask patterns (See Larger Applications and Application Factories).

The core module is an example, it caontains the business logic. In fact, you call it whatever you want, and there can be many packages.

The apis package will be your main API entry point that you need to import and register on the application, whereas the namespaces modules are reusables namespaces designed like you would do with blueprint.

A namespace module will contains models and resources declarations declaration. For example:

from flask_restplus import Namespace, Resource, fields

api = Namespace('cats', description='Cats related operations')

cat = api.model('Cat', {
    'id': fields.String(required=True, description='The cat identifier'),
    'name': fields.String(required=True, description='The cat name'),
})

CATS = [
    {'id': 'felix', 'name': 'Felix'},
]

@api.route('/')
class CatList(Resource):
    @api.doc('list_cats')
    @api.marshal_list_with(cat)
    def get(self):
        '''List all cats'''
        return CATS

@api.route('/<id>')
@api.param('id', 'The cat identifier')
@api.response(404, 'Cat not found')
class Cat(Resource):
    @api.doc('get_cat')
    @api.marshal_with(cat)
    def get(self, id):
        '''Fetch a cat given its identifier'''
        for cat in CATS:
            if cat['id'] == id:
                return cat
        api.abort(404)

The apis.__init__ module should aggregate them:

from flask_restplus import Api

from .namespace1 import api as ns1
from .namespace2 import api as ns2
# ...
from .namespaceX import api as nsX

api = Api(
    title='My Title',
    version='1.0',
    description='A description',
    # All API metadatas
)

api.add_namespace(ns1)
api.add_namespace(ns2)
# ...
api.add_namespace(nsX)

Using this pattern, you simple have to register your API in app.py like that:

from flask import Flask
from apis import api

app = Flask(__name__)
api.init_app(app)

app.run(debug=True)

Use With Blueprints

See Modular Applications with Blueprints in the Flask documentation for what blueprints are and why you should use them. Here’s an example of how to link an Api up to a Blueprint.

from flask import Blueprint
from flask_restplus import Api

blueprint = Blueprint('api', __name__)
api = Api(blueprint)
# ...

Using a blueprint will allow you to mount your API on any url prefix and/or subdomain in you application:

from flask import Flask
from apis import blueprint as api

app = Flask(__name__)
api.init_app(app)
app.register_blueprint(api, url_prefix='/api/1')
app.run(debug=True)

Note

Calling Api.init_app() is not required here because registering the blueprint with the app takes care of setting up the routing for the application.

Note

When using blueprints, remember to use the blueprint name with url_for():

# without blueprint
url_for('my_api_endpoint')

# with blueprint
url_for('api.my_api_endpoint')

Multiple APIs with reusable namespaces

Sometimes you need to maintain multiple versions of an API. If you built your API using namespaces composition, it’s quite simple to scale it to multiple APIs.

Given the previous layout, we can migrate it to the following directory structure:

project/
├── app.py
├── apiv1.py
├── apiv2.py
└── apis
    ├── __init__.py
    ├── namespace1.py
    ├── namespace2.py
    ├── ...
    └── namespaceX.py

Each apivX module will have the following pattern:

from flask import Blueprint
from flask_restplus import Api

api = Api(blueprint)

from .apis.namespace1 import api as ns1
from .apis.namespace2 import api as ns2
# ...
from .apis.namespaceX import api as nsX

blueprint = Blueprint('api', __name__, url_prefix='/api/1')
api = Api(blueprint
    title='My Title',
    version='1.0',
    description='A description',
    # All API metadatas
)

api.add_namespace(ns1)
api.add_namespace(ns2)
# ...
api.add_namespace(nsX)

And the app will simply mount them:

from flask import Flask
from api1 import blueprint as api1
from apiX import blueprint as apiX

app = Flask(__name__)
api.init_app(app)
app.register_blueprint(api1)
app.register_blueprint(apiX)
app.run(debug=True)

These are only proposals and you can do whatever suits your needs. Look at the github repository examples folder for more complete examples.

Full example

Here is a full example of a TodoMVC API.

from flask import Flask
from flask.ext.restplus import Api, Resource, fields
from werkzeug.contrib.fixers import ProxyFix

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
api = Api(app, version='1.0', title='TodoMVC API',
    description='A simple TodoMVC API',
)

ns = api.namespace('todos', description='TODO operations')

todo = api.model('Todo', {
    'id': fields.Integer(readOnly=True, description='The task unique identifier'),
    'task': fields.String(required=True, description='The task details')
})


class TodoDAO(object):
    def __init__(self):
        self.counter = 0
        self.todos = []

    def get(self, id):
        for todo in self.todos:
            if todo['id'] == id:
                return todo
        api.abort(404, "Todo {} doesn't exist".format(id))

    def create(self, data):
        todo = data
        todo['id'] = self.counter = self.counter + 1
        self.todos.append(todo)
        return todo

    def update(self, id, data):
        todo = self.get(id)
        todo.update(data)
        return todo

    def delete(self, id):
        todo = self.get(id)
        self.todos.remove(todo)


DAO = TodoDAO()
DAO.create({'task': 'Build an API'})
DAO.create({'task': '?????'})
DAO.create({'task': 'profit!'})


@ns.route('/')
class TodoList(Resource):
    '''Shows a list of all todos, and lets you POST to add new tasks'''
    @ns.doc('list_todos')
    @ns.marshal_list_with(todo)
    def get(self):
        '''List all tasks'''
        return DAO.todos

    @ns.doc('create_todo')
    @ns.expect(todo)
    @ns.marshal_with(todo, code=201)
    def post(self):
        '''Create a new task'''
        return DAO.create(api.payload), 201


@ns.route('/<int:id>')
@ns.response(404, 'Todo not found')
@ns.param('id', 'The task identifier')
class Todo(Resource):
    '''Show a single todo item and lets you delete them'''
    @ns.doc('get_todo')
    @ns.marshal_with(todo)
    def get(self, id):
        '''Fetch a given resource'''
        return DAO.get(id)

    @ns.doc('delete_todo')
    @ns.response(204, 'Todo deleted')
    def delete(self, id):
        '''Delete a task given its identifier'''
        DAO.delete(id)
        return '', 204

    @ns.expect(todo)
    @ns.marshal_with(todo)
    def put(self, id):
        '''Update a task given its identifier'''
        return DAO.update(id, api.payload)


if __name__ == '__main__':
    app.run(debug=True)

You can find other examples in the github repository examples folder.

API Reference

If you are looking for information on a specific function, class or method, this part of the documentation is for you.

API

Core

class flask_restplus.Api(app=None, version=u'1.0', title=None, description=None, terms_url=None, license=None, license_url=None, contact=None, contact_url=None, contact_email=None, authorizations=None, security=None, doc=u'/', default_id=<function default_id>, default=u'default', default_label=u'Default namespace', validate=None, tags=None, prefix=u'', default_mediatype=u'application/json', decorators=None, catch_all_404s=False, serve_challenge_on_401=False, **kwargs)[source]

The main entry point for the application. You need to initialize it with a Flask Application:

>>> app = Flask(__name__)
>>> api = Api(app)

Alternatively, you can use init_app() to set the Flask application after it has been constructed.

The endpoint parameter prefix all views and resources:

  • The API root/documentation will be {endpoint}.root
  • A resource registered as ‘resource’ will be available as {endpoint}.resource
Parameters:
  • app (flask.Flask|flask.Blueprint) – the Flask application object or a Blueprint
  • version (str) – The API version (used in Swagger documentation)
  • title (str) – The API title (used in Swagger documentation)
  • description (str) – The API description (used in Swagger documentation)
  • terms_url (str) – The API terms page URL (used in Swagger documentation)
  • contact (str) – A contact email for the API (used in Swagger documentation)
  • license (str) – The license associated to the API (used in Swagger documentation)
  • license_url (str) – The license page URL (used in Swagger documentation)
  • endpoint (str) – The API base endpoint (default to ‘api).
  • default (str) – The default namespace base name (default to ‘default’)
  • default_label (str) – The default namespace label (used in Swagger documentation)
  • default_mediatype (str) – The default media type to return
  • validate (bool) – Whether or not the API should perform input payload validation.
  • doc (str) – The documentation path. If set to a false value, documentation is disabled. (Default to ‘/’)
  • decorators (list) – Decorators to attach to every resource
  • catch_all_404s (bool) – Use handle_error() to handle 404 errors throughout your app
  • authorizations (dict) – A Swagger Authorizations declaration as dictionary
  • serve_challenge_on_401 (bool) – Serve basic authentication challenge with 401 responses (default ‘False’)
as_postman(urlvars=False, swagger=False)[source]

Serialize the API as Postman collection (v1)

Parameters:
  • urlvars (bool) – whether to include or not placeholders for query strings
  • swagger (bool) – whether to include or not the swagger.json specifications
base_path

The API path

Return type:str
base_url

The API base absolute url

Return type:str
default_endpoint(resource, namespace)[source]

Provide a default endpoint for a resource on a given namespace.

Endpoints are ensured not to collide.

Override this method specify a custom algoryhtm for default endpoint.

Parameters:
  • resource (Resource) – the resource for which we want an endpoint
  • namespace (Namespace) – the namespace holding the resource
Returns str:

An endpoint name

documentation(func)[source]

A decorator to specify a view funtion for the documentation

error_router(original_handler, e)[source]

This function decides whether the error occured in a flask-restful endpoint or not. If it happened in a flask-restful endpoint, our handler will be dispatched. If it happened in an unrelated view, the app’s original error handler will be dispatched. In the event that the error occurred in a flask-restful endpoint but the local handler can’t resolve the situation, the router will fall back onto the original_handler as last resort.

Parameters:
  • original_handler (function) – the original Flask error handler for the app
  • e (Exception) – the exception raised while handling the request
errorhandler(exception)[source]

A decorator to register an error handler for a given exception

handle_error(e)[source]

Error handler for the API transforms a raised exception into a Flask response, with the appropriate HTTP status code and body.

Parameters:e (Exception) – the raised Exception object
init_app(app, **kwargs)[source]

Allow to lazy register the API on a Flask application:

>>> app = Flask(__name__)
>>> api = Api()
>>> api.init_app(app)
Parameters:
  • app (flask.Flask) – the Flask application object
  • title (str) – The API title (used in Swagger documentation)
  • description (str) – The API description (used in Swagger documentation)
  • terms_url (str) – The API terms page URL (used in Swagger documentation)
  • contact (str) – A contact email for the API (used in Swagger documentation)
  • license (str) – The license associated to the API (used in Swagger documentation)
  • license_url (str) – The license page URL (used in Swagger documentation)
make_response(data, *args, **kwargs)[source]

Looks up the representation transformer for the requested media type, invoking the transformer to create a response object. This defaults to default_mediatype if no transformer is found for the requested mediatype. If default_mediatype is None, a 406 Not Acceptable response will be sent as per RFC 2616 section 14.1

Parameters:data – Python object containing response data to be transformed
mediatypes()[source]

Returns a list of requested mediatypes sent in the Accept header

mediatypes_method()[source]

Return a method that returns a list of mediatypes

namespace(*args, **kwargs)[source]

A namespace factory.

Returns Namespace:
 a new namespace instance
output(resource)[source]

Wraps a resource (as a flask view function), for cases where the resource does not directly return a response object

Parameters:resource – The resource as a flask view function
owns_endpoint(endpoint)[source]

Tests if an endpoint name (not path) belongs to this Api. Takes into account the Blueprint name part of the endpoint name.

Parameters:endpoint (str) – The name of the endpoint being checked
Returns:bool
payload

Store the input payload in the current request context

render_doc()[source]

Override this method to customize the documentation page

representation(mediatype)[source]

Allows additional representation transformers to be declared for the api. Transformers are functions that must be decorated with this method, passing the mediatype the transformer represents. Three arguments are passed to the transformer:

  • The data to be represented in the response body
  • The http status code
  • A dictionary of headers

The transformer should convert the data appropriately for the mediatype and return a Flask response object.

Ex:

@api.representation('application/xml')
def xml(data, code, headers):
    resp = make_response(convert_data_to_xml(data), code)
    resp.headers.extend(headers)
    return resp
specs_url

The Swagger specifications absolute url (ie. swagger.json)

Return type:str
unauthorized(response)[source]

Given a response, change it to ask for credentials

url_for(resource, **values)[source]

Generates a URL to the given resource.

Works like flask.url_for().

class flask_restplus.Namespace(name, description=None, path=None, decorators=None, validate=None, **kwargs)[source]

Group resources together.

Namespace is to API what flask.Blueprint is for flask.Flask.

Parameters:
  • name (str) – The namespace name
  • description (str) – An optionale short description
  • path (str) – An optional prefix path. If not provided, prefix is /+name
  • decorators (list) – A list of decorators to apply to each resources
  • validate (bool) – Whether or not to perform validation on this namespace
  • api (Api) – an optional API to attache to the namespace
abort(*args, **kwargs)[source]

Properly abort the current request

See: abort()

add_resource(resource, *urls, **kwargs)[source]

Register a Resource for a given API Namespace

Parameters:
  • resource (Resource) – the resource ro register
  • urls (str) – one or more url routes to match for the resource, standard flask routing rules apply. Any url variables will be passed to the resource method as args.
  • endpoint (str) – endpoint name (defaults to Resource.__name__.lower() Can be used to reference this route in fields.Url fields
  • resource_class_args (list|tuple) – args to be forwarded to the constructor of the resource.
  • resource_class_kwargs (dict) – kwargs to be forwarded to the constructor of the resource.

Additional keyword arguments not specified above will be passed as-is to flask.Flask.add_url_rule().

Examples:

namespace.add_resource(HelloWorld, '/', '/hello')
namespace.add_resource(Foo, '/foo', endpoint="foo")
namespace.add_resource(FooSpecial, '/special/foo', endpoint="foo")
as_list(field)[source]

Allow to specify nested lists for documentation

clone(name, *specs)[source]

Clone a model (Duplicate all fields)

Parameters:
  • name (str) – the resulting model name
  • specs – a list of models from which to clone the fields

See also

Model.clone()

deprecated(func)[source]

A decorator to mark a resource or a method as deprecated

doc(shortcut=None, **kwargs)[source]

A decorator to add some api documentation to the decorated object

errorhandler(exception)[source]

A decorator to register an error handler for a given exception

expect(*inputs, **kwargs)[source]

A decorator to Specify the expected input model

Parameters:
  • inputs (Model|Parse) – An expect model or request parser
  • validate (bool) – whether to perform validation or not
extend(name, parent, fields)[source]

Extend a model (Duplicate all fields)

Deprecated:since 0.9. Use clone() instead
header(name, description=None, **kwargs)[source]

A decorator to specify one of the expected headers

Parameters:
  • name (str) – the HTTP header name
  • description (str) – a description about the header
hide(func)[source]

A decorator to hide a resource or a method from specifications

inherit(name, *specs)[source]

Inherit a modal (use the Swagger composition pattern aka. allOf)

See also

Model.inherit()

marshal(*args, **kwargs)[source]

A shortcut to the marshal() helper

marshal_list_with(fields, **kwargs)[source]

A shortcut decorator for marshal_with() with as_list=True

marshal_with(fields, as_list=False, code=200, description=None, **kwargs)[source]

A decorator specifying the fields to use for serialization.

Parameters:
  • as_list (bool) – Indicate that the return type is a list (for the documentation)
  • code (int) – Optionnaly give the expected HTTP response code if its different from 200
model(name=None, model=None, mask=None, **kwargs)[source]

Register a model

See also

Model

param(name, description=None, _in=u'query', **kwargs)[source]

A decorator to specify one of the expected parameters

Parameters:
  • name (str) – the parameter name
  • description (str) – a small description
  • _in (str) – the parameter location (query|header|formData|body|cookie)
parser()[source]

Instanciate a RequestParser

response(code, description, model=None, **kwargs)[source]

A decorator to specify one of the expected responses

Parameters:
  • code (int) – the HTTP status code
  • description (str) – a small description about the response
  • model (Model) – an optional response model
route(*urls, **kwargs)[source]

A decorator to route resources.

class flask_restplus.Resource(api=None, *args, **kwargs)[source]

Represents an abstract RESTful resource.

Concrete resources should extend from this class and expose methods for each supported HTTP method. If a resource is invoked with an unsupported HTTP method, the API will return a response with status 405 Method Not Allowed. Otherwise the appropriate method is called and passed all arguments from the url rule used when adding the resource to an Api instance. See add_resource() for details.

as_view(name, *class_args, **class_kwargs)

Converts the class into an actual view function that can be used with the routing system. Internally this generates a function on the fly which will instantiate the View on each request and call the dispatch_request() method on it.

The arguments passed to as_view() are forwarded to the constructor of the class.

validate_payload(func)[source]

Perform a payload validation on expected model if necessary

Models

class flask_restplus.Model(name, *args, **kwargs)[source]

A thin wrapper on dict to store API doc metadata.

Parameters:
  • name (str) – The model public name
  • mask (str) – an optional default model mask
ancestors

Return the ancestors tree

classmethod clone(name, *parents)[source]

Clone these models (Duplicate all fields)

It can be used from the class

>>> model = Model.clone(fields_1, fields_2)

or from an Instanciated model

>>> new_model = model.clone(fields_1, fields_2)
Parameters:
  • name (str) – The new model name
  • parents (dict) – The new model extra fields
extend(name, fields)[source]

Extend this model (Duplicate all fields)

Parameters:
  • name (str) – The new model name
  • fields (dict) – The new model extra fields
Depreated:

since 0.9. Use clone() instead.

classmethod inherit(name, *parents)[source]

Inherit this model (use the Swagger composition pattern aka. allOf)

Parameters:
  • name (str) – The new model name
  • fields (dict) – The new model extra fields
resolved[source]

Resolve real fields before submitting them to upstream restful marshal

All fields accept a required boolean and a description string in kwargs.

class flask_restplus.fields.Raw(default=None, attribute=None, title=None, description=None, required=None, readonly=None, example=None, mask=None, **kwargs)[source]

Raw provides a base field class from which others should extend. It applies no formatting by default, and should only be used in cases where data does not need to be formatted before being serialized. Fields should throw a MarshallingError in case of parsing problem.

Parameters:
  • default – The default value for the field, if no value is specified.
  • attribute – If the public facing value differs from the internal value, use this to retrieve a different attribute from the response than the publicly named value.
  • title (str) – The field title (for documentation purpose)
  • description (str) – The field description (for documentation purpose)
  • required (bool) – Is the field required ?
  • readonly (bool) – Is the field read only ? (for documentation purpose)
  • example – An optional data example (for documentation purpose)
  • mask (callable) – An optional mask function to be applied to output
format(value)[source]

Formats a field’s value. No-op by default - field classes that modify how the value of existing object keys should be presented should override this and apply the appropriate formatting.

Parameters:value – The value to format
Raises:MarshallingError – In case of formatting problem

Ex:

class TitleCase(Raw):
    def format(self, value):
        return unicode(value).title()
output(key, obj)[source]

Pulls the value for the given key from the object, applies the field’s formatting and returns the result. If the key is not found in the object, returns the default value. Field classes that create values which do not require the existence of the key in the object should override this and return the desired value.

Raises:MarshallingError – In case of formatting problem
class flask_restplus.fields.String(*args, **kwargs)[source]

Marshal a value as a string. Uses six.text_type so values will be converted to unicode in python2 and str in python3.

class flask_restplus.fields.FormattedString(src_str, **kwargs)[source]

FormattedString is used to interpolate other values from the response into this field. The syntax for the source string is the same as the string format() method from the python stdlib.

Ex:

fields = {
    'name': fields.String,
    'greeting': fields.FormattedString("Hello {name}")
}
data = {
    'name': 'Doug',
}
marshal(data, fields)
Parameters:src_str (str) – the string to format with the other values from the response.
class flask_restplus.fields.Url(endpoint=None, absolute=False, scheme=None, **kwargs)[source]

A string representation of a Url

Parameters:
  • endpoint (str) – Endpoint name. If endpoint is None, request.endpoint is used instead
  • absolute (bool) – If True, ensures that the generated urls will have the hostname included
  • scheme (str) – URL scheme specifier (e.g. http, https)
class flask_restplus.fields.DateTime(dt_format=u'iso8601', **kwargs)[source]

Return a formatted datetime string in UTC. Supported formats are RFC 822 and ISO 8601.

See email.utils.formatdate() for more info on the RFC 822 format.

See datetime.datetime.isoformat() for more info on the ISO 8601 format.

Parameters:dt_format (str) – rfc822 or iso8601
format_iso8601(dt)[source]

Turn a datetime object into an ISO8601 formatted date.

Parameters:dt (datetime) – The datetime to transform
Returns:A ISO 8601 formatted date string
format_rfc822(dt)[source]

Turn a datetime object into a formatted date.

Parameters:dt (datetime) – The datetime to transform
Returns:A RFC 822 formatted date string
class flask_restplus.fields.Date(**kwargs)[source]

Return a formatted date string in UTC in ISO 8601.

See datetime.date.isoformat() for more info on the ISO 8601 format.

class flask_restplus.fields.Boolean(default=None, attribute=None, title=None, description=None, required=None, readonly=None, example=None, mask=None, **kwargs)[source]

Field for outputting a boolean value.

Empty collections such as "", {}, [], etc. will be converted to False.

class flask_restplus.fields.Integer(*args, **kwargs)[source]

Field for outputting an integer value.

Parameters:default (int) – The default value for the field, if no value is specified.
class flask_restplus.fields.Float(*args, **kwargs)[source]

A double as IEEE-754 double precision.

ex : 3.141592653589793 3.1415926535897933e-06 3.141592653589793e+24 nan inf -inf

class flask_restplus.fields.Arbitrary(*args, **kwargs)[source]

A floating point number with an arbitrary precision.

ex: 634271127864378216478362784632784678324.23432

class flask_restplus.fields.Fixed(decimals=5, **kwargs)[source]

A decimal number with a fixed precision.

class flask_restplus.fields.Nested(model, allow_null=False, as_list=False, **kwargs)[source]

Allows you to nest one set of fields inside another. See Nested Field for more information

Parameters:
  • model (dict) – The model dictionary to nest
  • allow_null (bool) – Whether to return None instead of a dictionary with null keys, if a nested dictionary has all-null keys
  • kwargs – If default keyword argument is present, a nested dictionary will be marshaled as its value if nested dictionary is all-null keys (e.g. lets you return an empty JSON object instead of null)
class flask_restplus.fields.List(cls_or_instance, **kwargs)[source]

Field for marshalling lists of other fields.

See List Field for more information.

Parameters:cls_or_instance – The field type the list will contain.
class flask_restplus.fields.ClassName(dash=False, **kwargs)[source]

Return the serialized object class name as string.

Parameters:dash (bool) – If True, transform CamelCase to kebab_case.
class flask_restplus.fields.Polymorph(mapping, required=False, **kwargs)[source]

A Nested field handling inheritance.

Allows you to specify a mapping between Python classes and fields specifications.

mapping = {
    Child1: child1_fields,
    Child2: child2_fields,
}

fields = api.model('Thing', {
    owner: fields.Polymorph(mapping)
})
Parameters:mapping (dict) – Maps classes to their model/fields representation
resolve_ancestor(models)[source]

Resolve the common ancestor for all models.

Assume there is only one common ancestor.

exception flask_restplus.fields.MarshallingError(underlying_exception)[source]

This is an encapsulating Exception in case of marshalling error.

Serialization

flask_restplus.marshal(data, fields, envelope=None, mask=None)[source]

Takes raw data (in the form of a dict, list, object) and a dict of fields to output and filters the data based on those fields.

Parameters:
  • data – the actual object(s) from which the fields are taken from
  • fields – a dict of whose keys will make up the final serialized response output
  • envelope – optional key that will be used to envelop the serialized response
>>> from flask_restplus import fields, marshal
>>> data = { 'a': 100, 'b': 'foo' }
>>> mfields = { 'a': fields.Raw }
>>> marshal(data, mfields)
OrderedDict([('a', 100)])
>>> marshal(data, mfields, envelope='data')
OrderedDict([('data', OrderedDict([('a', 100)]))])
flask_restplus.marshal_with(fields, envelope=None, mask=None)[source]

A decorator that apply marshalling to the return values of your methods.

>>> from flask_restplus import fields, marshal_with
>>> mfields = { 'a': fields.Raw }
>>> @marshal_with(mfields)
... def get():
...     return { 'a': 100, 'b': 'foo' }
...
...
>>> get()
OrderedDict([('a', 100)])
>>> @marshal_with(mfields, envelope='data')
... def get():
...     return { 'a': 100, 'b': 'foo' }
...
...
>>> get()
OrderedDict([('data', OrderedDict([('a', 100)]))])

see flask_restplus.marshal()

flask_restplus.marshal_with_field(field)[source]

A decorator that formats the return values of your methods with a single field.

>>> from flask_restplus import marshal_with_field, fields
>>> @marshal_with_field(fields.List(fields.Integer))
... def get():
...     return ['1', 2, 3.0]
...
>>> get()
[1, 2, 3]

see flask_restplus.marshal_with()

class flask_restplus.mask.Mask(mask=None, skip=False, **kwargs)[source]

Hold a parsed mask.

Parameters:
  • mask (str|dict|Mask) – A mask, parsed or not
  • skip (bool) – If True, missing fields won’t appear in result
apply(data)[source]

Apply a fields mask to the data.

Parameters:data – The data or model to apply mask on
Raises:MaskError – when unable to apply the mask
clean(mask)[source]

Remove unecessary characters

filter_data(data)[source]

Handle the data filtering given a parsed mask

Parameters:
  • data (dict) – the raw data to filter
  • mask (list) – a parsed mask tofilter against
  • skip (bool) – whether or not to skip missing fields
parse(mask)[source]

Parse a fields mask. Expect something in the form:

{field,nested{nested_field,another},last}

External brackets are optionals so it can also be written:

field,nested{nested_field,another},last

All extras characters will be ignored.

Parameters:mask (str) – the mask string to parse
Raises:ParseError – when a mask is unparseable/invalid
flask_restplus.mask.apply(data, mask, skip=False)[source]

Apply a fields mask to the data.

Parameters:
  • data – The data or model to apply mask on
  • mask (str|Mask) – the mask (parsed or not) to apply on data
  • skip (bool) – If rue, missing field won’t appear in result
Raises:

MaskError – when unable to apply the mask

Inputs

class flask_restplus.reqparse.Argument(name, default=None, dest=None, required=False, ignore=False, type=<function <lambda>>, location=(u'json', u'values'), choices=(), action=u'store', help=None, operators=(u'=', ), case_sensitive=True, store_missing=True, trim=False, nullable=True)[source]
Parameters:
  • name – Either a name or a list of option strings, e.g. foo or -f, –foo.
  • default – The value produced if the argument is absent from the request.
  • dest – The name of the attribute to be added to the object returned by parse_args().
  • required (bool) – Whether or not the argument may be omitted (optionals only).
  • action (string) – The basic type of action to be taken when this argument is encountered in the request. Valid options are “store” and “append”.
  • ignore (bool) – Whether to ignore cases where the argument fails type conversion
  • type – The type to which the request argument should be converted. If a type raises an exception, the message in the error will be returned in the response. Defaults to unicode in python2 and str in python3.
  • location – The attributes of the flask.Request object to source the arguments from (ex: headers, args, etc.), can be an iterator. The last item listed takes precedence in the result set.
  • choices – A container of the allowable values for the argument.
  • help – A brief description of the argument, returned in the response when the argument is invalid. May optionally contain an “{error_msg}” interpolation token, which will be replaced with the text of the error raised by the type converter.
  • case_sensitive (bool) – Whether argument values in the request are case sensitive or not (this will convert all values to lowercase)
  • store_missing (bool) – Whether the arguments default value should be stored if the argument is missing from the request.
  • trim (bool) – If enabled, trims whitespace around the argument.
  • nullable (bool) – If enabled, allows null value in argument.
handle_validation_error(error, bundle_errors)[source]

Called when an error is raised while parsing. Aborts the request with a 400 status and an error message

Parameters:
  • error – the error that was raised
  • bundle_errors (bool) – do not abort when first error occurs, return a dict with the name of the argument and the error message to be bundled
parse(request, bundle_errors=False)[source]

Parses argument value(s) from the request, converting according to the argument’s type.

Parameters:
  • request – The flask request object to parse arguments from
  • bundle_errors (bool) – do not abort when first error occurs, return a dict with the name of the argument and the error message to be bundled
source(request)[source]

Pulls values off the request in the provided location :param request: The flask request object to parse arguments from

flask_restplus.reqparse.LOCATIONS = {u'files': u'formData', u'form': u'formData', u'args': u'query', u'headers': u'header', u'json': u'body', u'values': u'query'}

Maps Flask-Restful RequestParser locations to Swagger ones

flask_restplus.reqparse.PY_TYPES = {<type 'str'>: u'string', <type 'int'>: u'integer', <type 'bool'>: u'boolean', None: u'void'}

Maps Pyton primitives types to Swagger ones

class flask_restplus.reqparse.ParseResult[source]

The default result container as an Object dict.

class flask_restplus.reqparse.RequestParser(argument_class=<class 'flask_restplus.reqparse.Argument'>, result_class=<class 'flask_restplus.reqparse.ParseResult'>, trim=False, bundle_errors=False)[source]

Enables adding and parsing of multiple arguments in the context of a single request. Ex:

from flask_restplus import RequestParser

parser = RequestParser()
parser.add_argument('foo')
parser.add_argument('int_bar', type=int)
args = parser.parse_args()
Parameters:
  • trim (bool) – If enabled, trims whitespace on all arguments in this parser
  • bundle_errors (bool) – If enabled, do not abort when first error occurs, return a dict with the name of the argument and the error message to be bundled and return all validation errors
add_argument(*args, **kwargs)[source]

Adds an argument to be parsed.

Accepts either a single instance of Argument or arguments to be passed into Argument‘s constructor.

See Argument‘s constructor for documentation on the available options.

copy()[source]

Creates a copy of this RequestParser with the same set of arguments

parse_args(req=None, strict=False)[source]

Parse all arguments from the provided request and return the results as a ParseResult

Parameters:strict (bool) – if req includes args not in parser, throw 400 BadRequest exception
Returns:the parsed results as ParseResult (or any class defined as result_class)
Return type:ParseResult
remove_argument(name)[source]

Remove the argument matching the given name.

replace_argument(name, *args, **kwargs)[source]

Replace the argument matching the given name with a new version.

flask_restplus.inputs.boolean(value)[source]

Parse the string "true" or "false" as a boolean (case insensitive).

Also accepts "1" and "0" as True/False (respectively).

If the input is from the request JSON body, the type is already a native python boolean, and will be passed through without further parsing.

Raises:ValueError – if the boolean value is invalid
flask_restplus.inputs.date(value)[source]

Parse a valid looking date in the format YYYY-mm-dd

flask_restplus.inputs.date_from_iso8601(value)[source]

Turns an ISO8601 formatted date into a date object.

Example:

inputs.date_from_iso8601("2012-01-01")
Parameters:value (str) – The ISO8601-complying string to transform
Returns:A date
Return type:date
Raises:ValueError – if value is an invalid date literal
flask_restplus.inputs.datetime_from_iso8601(value)[source]

Turns an ISO8601 formatted date into a datetime object.

Example:

inputs.datetime_from_iso8601("2012-01-01T23:30:00+02:00")
Parameters:value (str) – The ISO8601-complying string to transform
Returns:A datetime
Return type:datetime
Raises:ValueError – if value is an invalid date literal
flask_restplus.inputs.datetime_from_rfc822(value)[source]

Turns an RFC822 formatted date into a datetime object.

Example:

inputs.datetime_from_rfc822('Wed, 02 Oct 2002 08:00:00 EST')
Parameters:value (str) – The RFC822-complying string to transform
Returns:The parsed datetime
Return type:datetime
Raises:ValueError – if value is an invalid date literal
class flask_restplus.inputs.email(check=False, ip=False, local=False, domains=None, exclude=None)[source]

Validate an email.

Example:

parser = reqparse.RequestParser()
parser.add_argument('email', type=inputs.email(dns=True))

Input to the email argument will be rejected if it does not match an email and if domain does not exists.

Parameters:
  • check (bool) – Check the domain exists (perform a DNS resolution)
  • ip (bool) – Allow IP (both ipv4/ipv6) as domain
  • local (bool) – Allow localhost (both string or ip) as domain
  • domains (list|tuple) – Restrict valid domains to this list
  • exclude (list|tuple) – Exclude some domains
class flask_restplus.inputs.int_range(low, high, argument=u'argument')[source]

Restrict input to an integer in a range (inclusive)

flask_restplus.inputs.ip(value)[source]

Validate an IP address (both IPv4 and IPv6)

flask_restplus.inputs.ipv4(value)[source]

Validate an IPv4 address

flask_restplus.inputs.ipv6(value)[source]

Validate an IPv6 address

flask_restplus.inputs.iso8601interval(value, argument=u'argument')[source]

Parses ISO 8601-formatted datetime intervals into tuples of datetimes.

Accepts both a single date(time) or a full interval using either start/end or start/duration notation, with the following behavior:

  • Intervals are defined as inclusive start, exclusive end
  • Single datetimes are translated into the interval spanning the largest resolution not specified in the input value, up to the day.
  • The smallest accepted resolution is 1 second.
  • All timezones are accepted as values; returned datetimes are localized to UTC. Naive inputs and date inputs will are assumed UTC.

Examples:

"2013-01-01" -> datetime(2013, 1, 1), datetime(2013, 1, 2)
"2013-01-01T12" -> datetime(2013, 1, 1, 12), datetime(2013, 1, 1, 13)
"2013-01-01/2013-02-28" -> datetime(2013, 1, 1), datetime(2013, 2, 28)
"2013-01-01/P3D" -> datetime(2013, 1, 1), datetime(2013, 1, 4)
"2013-01-01T12:00/PT30M" -> datetime(2013, 1, 1, 12), datetime(2013, 1, 1, 12, 30)
"2013-01-01T06:00/2013-01-01T12:00" -> datetime(2013, 1, 1, 6), datetime(2013, 1, 1, 12)
Parameters:value (str) – The ISO8601 date time as a string
Returns:Two UTC datetimes, the start and the end of the specified interval
Return type:A tuple (datetime, datetime)
Raises:ValueError – if the interval is invalid.
flask_restplus.inputs.natural(value, argument=u'argument')[source]

Restrict input type to the natural numbers (0, 1, 2, 3...)

flask_restplus.inputs.positive(value, argument=u'argument')[source]

Restrict input type to the positive integers (1, 2, 3...)

class flask_restplus.inputs.regex(pattern)[source]

Validate a string based on a regular expression.

Example:

parser = reqparse.RequestParser()
parser.add_argument('example', type=inputs.regex('^[0-9]+$'))

Input to the example argument will be rejected if it contains anything but numbers.

Parameters:pattern (str) – The regular expression the input must match
flask_restplus.inputs.url(value)[source]

Validate a URL.

Parameters:value (str) – The URL to validate
Returns:The URL if valid.
Raises:ValueError

Errors

flask_restplus.errors.abort(code=500, message=None, **kwargs)[source]

Properly abort the current request.

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

Parameters:
  • code (int) – The associated HTTP status code
  • message (str) – An optional details message
  • kwargs – Any additionnal data to pass to the error payload
Raises:

HTTPException

exception flask_restplus.errors.RestError(msg)[source]

Base class for all Flask-Restplus Errors

exception flask_restplus.errors.ValidationError(msg)[source]

An helper class for validation errors.

exception flask_restplus.errors.SpecsError(msg)[source]

An helper class for incoherent specifications.

exception flask_restplus.fields.MarshallingError(underlying_exception)[source]

This is an encapsulating Exception in case of marshalling error.

exception flask_restplus.mask.MaskError(msg)[source]

Raised when an error occurs on mask

exception flask_restplus.mask.ParseError(msg)[source]

Raised when the mask parsing failed

Internals

These are internal classes or helpers. Most of the time you shouldn’t have to deal directly with them.

class flask_restplus.api.SwaggerView(api=None, *args, **kwargs)[source]

Render the Swagger specifications as JSON

class flask_restplus.swagger.Swagger(api)[source]

A Swagger documentation wrapper for an API instance.

class flask_restplus.postman.PostmanCollectionV1(api, swagger=False)[source]

Postman Collection (V1 format) serializer

flask_restplus.utils.merge(first, second)[source]

Recursively merges two dictionnaries.

Second dictionnary values will take precedance over those from the first one. Nested dictionnaries are merged too.

Parameters:
  • first (dict) – The first dictionnary
  • second (dict) – The second dictionnary
Returns:

the resulting merged dictionnary

Return type:

dict

flask_restplus.utils.camel_to_dash(value)[source]

Transform a CamelCase string into a low_dashed one

Parameters:value (str) – a CamelCase string to transform
Returns:the low_dashed string
Return type:str
flask_restplus.utils.default_id(resource, method)[source]

Default operation ID generator

flask_restplus.utils.not_none(data)[source]

Remove all keys where value is None

Parameters:data (dict) – A dictionnary with potentialy some values set to None
Returns:The same dictionnary without the keys with values to None
Return type:dict
flask_restplus.utils.not_none_sorted(data)[source]

Remove all keys where value is None

Parameters:data (OrderedDict) – A dictionnary with potentialy some values set to None
Returns:The same dictionnary without the keys with values to None
Return type:OrderedDict
flask_restplus.utils.unpack(response, default_code=200)[source]

Unpack a Flask standard response.

Flask response can be: - a single value - a 2-tuple (value, code) - a 3-tuple (value, code, headers)

Warning

When using this function, you must ensure that the tuple is not the reponse data. To do so, prefer returning list instead of tuple for listings.

Parameters:
  • response – A Flask style response
  • default_code (int) – The HTTP code to use as default if none is provided
Returns:

a 3-tuple (data, code, headers)

Return type:

tuple

Raises:

ValueError – if the response does not have one of the expected format

Additional Notes

Contributing

flask-restplus is open-source and very open to contributions.

Submitting issues

Issues are contributions in a way so don’t hesitate to submit reports on the official bugtracker.

Provide as much informations as possible to specify the issues:

  • the flask-restplus version used
  • a stacktrace
  • installed applications list
  • a code sample to reproduce the issue
  • ...

Submitting patches (bugfix, features, ...)

If you want to contribute some code:

  1. fork the official flask-restplus repository
  2. create a branch with an explicit name (like my-new-feature or issue-XX)
  3. do your work in it
  4. rebase it on the master branch from the official repository (cleanup your history by performing an interactive rebase)
  5. submit your pull-request

There are some rules to follow:

  • your contribution should be documented (if needed)
  • your contribution should be tested and the test suite should pass successfully
  • your code should be mostly PEP8 compatible with a 120 characters line length
  • your contribution should support both Python 2 and 3 (use tox to test)

You need to install some dependencies to develop on flask-restplus:

$ pip install -e .[dev]

An Invoke tasks.py is provided to simplify the common tasks:

$ inv -l
Available tasks:

  all      Run tests, reports and packaging
  assets   Fetch web assets
  clean    Cleanup all build artifacts
  cover    Run tests suite with coverage
  demo     Run the demo
  dist     Package for distribution
  doc      Build the documentation
  qa       Run a quality report
  test     Run tests suite
  tox      Run tests against Python versions

To ensure everything is fine before submission, use tox. It will run the test suite on all the supported Python version and ensure the documentation is generating.

$ tox

You also need to ensure your code is compliant with the flask-restplus coding standards:

$ inv qa

To ensure everything is fine before commiting, you can launch the all in one command:

$ inv qa tox

It will ensure the code meet the coding conventions, runs on every version on python and the documentation is properly generating.

Changelog

0.9.0 (2016-02-22)

0.8.6 (2015-12-26)

  • Handle callable on API infos

  • Handle documentation on error handlers

  • Drop/merge flask_restful flask_restful.RequestParser

  • Handle RequestParser into expect() decorator

  • Handle schema for inputs parsers

  • Added some inputs:

0.8.5 (2015-12-12)

0.8.4 (2015-12-07)

  • Drop/merge flask_restful.Resource resolving a recursion problem

  • Allow any callable as field default, min, max...

  • Added Date field

  • Improve error handling for inconsistent masks

  • Handle model level default mask

  • support colons and dashes in mask field names

  • Breaking changes:
    • Renamed exceptions module into errors
    • Renamed RestException into RestError
    • Renamed MarshallingException into MarshallingError
    • DateTime field always output datetime

0.8.3 (2015-12-05)

  • Drop/merge flask-restful fields
  • Drop/merge flask-restplus inputs
  • Update Swagger-UI to version 2.1.3
  • Use minified version of Swagger-UI if DEBUG=False
  • Blueprint subdomain support (static only)
  • Added support for default fields mask

0.8.2 (2015-12-01)

  • Skip unknown fields in mask when applied on a model
  • Added * token to fields mask (all remaining fields)
  • Ensure generated endpoints does not collide
  • Drop/merge flask-restful Api.handler_error()

0.8.1 (2015-11-27)

  • Refactor Swagger UI handling:
    • allow to register a custom view with @api.documentation
    • allow to register a custom URL with the doc parameter
    • allow to disable documentation with doc=False
  • Added fields mask support through header (see: Fields Masks Documentation)

  • Expose flask_restful.inputs module on flask_restplus.inputs

  • Added support for some missing fields and attributes:
    • host root field (filed only if SERVER_NAME config is set)
    • custom tags root field
    • exclusiveMinimum and exclusiveMaximum number field attributes
    • multipleOf number field attribute
    • minLength and maxLength string field attributes
    • pattern string field attribute
    • minItems and maxItems list field attributes
    • uniqueItems list field attribute
  • Allow to override the default error handler

  • Fixes

0.8.0

  • Added payload validation (initial implementation based on jsonschema)
  • Added @api.deprecated to mark resources or methods as deprecated
  • Added @api.header decorator shortcut to document headers
  • Added Postman export
  • Fix compatibility with flask-restful 0.3.4
  • Allow to specify an exemple a custom fields with __schema_example__
  • Added support for PATCH method in Swagger UI
  • Upgraded to Swagger UI 2.1.2
  • Handle enum as callable
  • Allow to configure docExpansion with the SWAGGER_UI_DOC_EXPANSION parameter

0.7.2

  • Compatibility with flask-restful 0.3.3
  • Fix action=append handling in RequestParser
  • Upgraded to SwaggerUI 2.1.8-M1
  • Miscellaneous fixes

0.7.1

  • Fix @api.marshal_with_list() keyword arguments handling.

0.7.0

  • Expose models and fields schema through the __schema__ attribute
  • Drop support for model as class
  • Added @api.errorhandler() to register custom error handlers
  • Added @api.response() shortcut decorator
  • Fix list nested models missing in definitions

0.6.0

  • Python 2.6 support

  • Experimental polymorphism support (single inheritance only)
    • Added Polymorph field
    • Added discriminator attribute support on String fields
    • Added api.inherit() method
  • Added ClassName field

0.5.1

  • Fix for parameter with schema (do not set type=string)

0.5.0

  • Allow shorter syntax to set operation id: @api.doc('my-operation')
  • Added a shortcut to specify the expected input model: @api.expect(my_fields)
  • Added title attribute to fields
  • Added @api.extend() to extend models
  • Ensure coherence between required and allow_null for NestedField
  • Support list of primitive types and list of models as body
  • Upgraded to latest version of Swagger UI
  • Fixes

0.4.2

  • Rename apidoc blueprint into restplus_doc to avoid collisions

0.4.1

  • Added SWAGGER_VALIDATOR_URL config parameter
  • Added readonly field parameter
  • Upgraded to latest version of Swagger UI

0.4.0

  • Port to Flask-Restful 0.3+
  • Use the default Blueprint/App mecanism
  • Allow to hide some ressources or methods using @api.doc(False) or @api.hide
  • Allow to globally customize the default operationId with the default_id callable parameter

0.3.0

  • Switch to Swagger 2.0 (Major breakage)
    • notes documentation is now description
    • nickname documentation is now id
    • new responses declaration format
  • Added missing body parameter to document body input

  • Last release before Flask-Restful 0.3+ compatibility switch

0.2.4

  • Handle description and required attributes on fields.List

0.2.3

  • Fix custom fields registeration

0.2.2

  • Fix model list in declaration

0.2.1

  • Allow to type custom fields with Api.model
  • Handle custom fields into fieds.List

0.2

  • Upgraded to SwaggerUI 0.2.22
  • Support additional field documentation attributes: required, description, enum, min, max and default
  • Initial support for model in RequestParser

0.1.3

  • Fix Api.marshal() shortcut

0.1.2

  • Added Api.marshal_with() and Api.marshal_list_with() decorators
  • Added Api.marshal() shortcut

0.1.1

  • Use zip_safe=False for proper packaging.

0.1

  • Initial release

Indices and tables