API

This part of the documentation documents all the public classes and functions in Flask-Restless.

The API Manager class

class flask_restless.APIManager(app=None, session=None, flask_sqlalchemy_db=None, preprocessors=None, postprocessors=None, url_prefix=None)

Provides a method for creating a public ReSTful JSON API with respect to a given Flask application object.

The Flask object can either be specified in the constructor, or after instantiation time by calling the init_app() method.

app is the Flask object containing the user’s Flask application.

session is the Session object in which changes to the database will be made.

flask_sqlalchemy_db is the SQLAlchemy object with which app has been registered and which contains the database models for which API endpoints will be created.

If flask_sqlalchemy_db is not None, session will be ignored.

For example, to use this class with models defined in pure SQLAlchemy:

from flask import Flask
from flask_restless import APIManager
from sqlalchemy import create_engine
from sqlalchemy.orm.session import sessionmaker

engine = create_engine('sqlite:////tmp/mydb.sqlite')
Session = sessionmaker(bind=engine)
mysession = Session()
app = Flask(__name__)
apimanager = APIManager(app, session=mysession)

and with models defined with Flask-SQLAlchemy:

from flask import Flask
from flask_restless import APIManager
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLALchemy(app)
apimanager = APIManager(app, flask_sqlalchemy_db=db)

url_prefix is the URL prefix at which each API created by this instance will be accessible. For example, if this is set to 'foo', then this method creates endpoints of the form /foo/<collection_name> when create_api() is called. If the url_prefix is set in the create_api(), the URL prefix set in the constructor will be ignored for that endpoint.

postprocessors and preprocessors must be dictionaries as described in the section Request preprocessors and postprocessors. These preprocessors and postprocessors will be applied to all requests to and responses from APIs created using this APIManager object. The preprocessors and postprocessors given in these keyword arguments will be prepended to the list of processors given for each individual model when using the create_api_blueprint() method (more specifically, the functions listed here will be executed before any functions specified in the create_api_blueprint() method). For more information on using preprocessors and postprocessors, see Request preprocessors and postprocessors.

create_api(*args, **kw)

Creates and possibly registers a ReSTful API blueprint for the given SQLAlchemy model.

If a Flask application was provided in the constructor of this class, the created blueprint is immediately registered on that application. Otherwise, the blueprint is stored for later registration when the init_app() method is invoked. In that case, the blueprint will be registered each time the init_app() method is invoked.

The keyword arguments for this method are exactly the same as those for create_api_blueprint(), and are passed directly to that method. However, unlike that method, this method accepts only a single positional argument, model, the SQLAlchemy model for which to create the API. A UUID will be automatically generated for the blueprint name.

For example, if you only wish to create APIs on a single Flask application:

app = Flask(__name__)
session = ...  # create the SQLAlchemy session
manager = APIManager(app=app, session=session)
manager.create_api(User)

If you want to create APIs before having access to a Flask application, you can call this method before calling init_app():

session = ...  # create the SQLAlchemy session
manager = APIManager(session=session)
manager.create_api(User)

# later...
app = Flask(__name__)
manager.init_app(app)

If you want to create an API and register it on multiple Flask applications, you can call this method once and init_app() multiple times with different app arguments:

session = ...  # create the SQLAlchemy session
manager = APIManager(session=session)
manager.create_api(User)

# later...
app1 = Flask('application1')
app2 = Flask('application2')
manager.init_app(app1)
manager.init_app(app2)
create_api_blueprint(name, model, methods=frozenset({'GET'}), url_prefix=None, collection_name=None, allow_functions=False, only=None, exclude=None, additional_attributes=None, validation_exceptions=None, page_size=10, max_page_size=100, preprocessors=None, postprocessors=None, primary_key=None, serializer_class=None, deserializer_class=None, includes=None, allow_to_many_replacement=False, allow_delete_from_to_many_relationships=False, allow_client_generated_ids=False)

Creates and returns a ReSTful API interface as a blueprint, but does not register it on any flask.Flask application.

The endpoints for the API for model will be available at <url_prefix>/<collection_name>. If collection_name is None, the lowercase name of the provided model class will be used instead, as accessed by model.__table__.name. (If any black magic was performed on model.__table__, this will be reflected in the endpoint URL.) For more information, see Collection name.

This function must be called at most once for each model for which you wish to create a ReSTful API. Its behavior (for now) is undefined if called more than once.

This function returns the flask.Blueprint object that handles the endpoints for the model. The returned Blueprint has not been registered with the Flask application object specified in the constructor of this class, so you will need to register it yourself to make it available on the application. If you don’t need access to the Blueprint object, use create_api_blueprint() instead, which handles registration automatically.

name is the name of the blueprint that will be created.

model is the SQLAlchemy model class for which a ReSTful interface will be created.

app is the Flask object on which we expect the blueprint created in this method to be eventually registered. If not specified, the Flask application specified in the constructor of this class is used.

methods is a list of strings specifying the HTTP methods that will be made available on the ReSTful API for the specified model.

  • If 'GET' is in the list, GET requests will be allowed at endpoints for collections of resources, resources, to-many and to-one relations of resources, and particular members of a to-many relation. Furthermore, relationship information will be accessible. For more information, see Fetching resources and relationships.

  • If 'POST' is in the list, POST requests will be allowed at endpoints for collections of resources. For more information, see Creating resources.

  • If 'DELETE' is in the list, DELETE requests will be allowed at endpoints for individual resources. For more information, see Deleting resources.

  • If 'PATCH' is in the list, PATCH requests will be allowed at endpoints for individual resources. Replacing a to-many relationship when issuing a request to update a resource can be enabled by setting allow_to_many_replacement to True.

    Furthermore, to-one relationships can be updated at the relationship endpoints under an individual resource via PATCH requests. This also allows you to add to a to-many relationship via the POST method, delete from a to-many relationship via the DELETE method (if allow_delete_from_to_many_relationships is set to True), and replace a to-many relationship via the PATCH method (if allow_to_many_replacement is set to True). For more information, see Updating resources and Updating relationships.

The default set of methods provides a read-only interface (that is, only GET requests are allowed).

url_prefix is the URL prefix at which this API will be accessible. For example, if this is set to '/foo', then this method creates endpoints of the form /foo/<collection_name>. If not set, the default URL prefix specified in the constructor of this class will be used. If that was not set either, the default '/api' will be used.

collection_name is the name of the collection specified by the given model class to be used in the URL for the ReSTful API created. If this is not specified, the lowercase name of the model will be used. For example, if this is set to 'foo', then this method creates endpoints of the form /api/foo, /api/foo/<id>, etc.

If allow_functions is True, then GET requests to /api/eval/<collection_name> will return the result of evaluating SQL functions specified in the body of the request. For information on the request format, see Function evaluation. This is False by default.

Warning

If allow_functions is True, you must not create an API for a model whose name is 'eval'.

If only is not None, it must be a list of columns and/or relationships of the specified model, given either as strings or as the attributes themselves. If it is a list, only these fields will appear in the resource object representation of an instance of model. In other words, only is a whitelist of fields. The id and type elements of the resource object will always be present regardless of the value of this argument. If only contains a string that does not name a column in model, it will be ignored.

If additional_attributes is a list of strings, these attributes of the model will appear in the JSON representation of an instance of the model. This is useful if your model has an attribute that is not a SQLAlchemy column but you want it to be exposed. If any of the attributes does not exist on the model, a AttributeError is raised.

If exclude is not None, it must be a list of columns and/or relationships of the specified model, given either as strings or as the attributes themselves. If it is a list, all fields except these will appear in the resource object representation of an instance of model. In other words, exclude is a blacklist of fields. The id and type elements of the resource object will always be present regardless of the value of this argument. If exclude contains a string that does not name a column in model, it will be ignored.

If either only or exclude is not None, exactly one of them must be specified; if both are not None, then this function will raise a IllegalArgumentError.

See Specifying which fields appear in responses for more information on specifying which fields will be included in the resource object representation.

validation_exceptions is the tuple of possible exceptions raised by validation of your database models. If this is specified, validation errors will be captured and forwarded to the client in the format described by the JSON API specification. For more information on how to use validation, see Capturing validation errors.

page_size must be a positive integer that represents the default page size for responses that consist of a collection of resources. Requests made by clients may override this default by specifying page_size as a query parameter. max_page_size must be a positive integer that represents the maximum page size that a client can request. Even if a client specifies that greater than max_page_size should be returned, at most max_page_size results will be returned. For more information, see Pagination.

serializer_class and deserializer_class are custom serializer and deserializer classes. The former must be a subclass of DefaultSerializer and the latter a subclass of DefaultDeserializer. For more information on using these, see Custom serialization.

preprocessors is a dictionary mapping strings to lists of functions. Each key represents a type of endpoint (for example, 'GET_RESOURCE' or 'GET_COLLECTION'). Each value is a list of functions, each of which will be called before any other code is executed when this API receives the corresponding HTTP request. The functions will be called in the order given here. The postprocessors keyword argument is essentially the same, except the given functions are called after all other code. For more information on preprocessors and postprocessors, see Request preprocessors and postprocessors.

primary_key is a string specifying the name of the column of model to use as the primary key for the purposes of creating URLs. If the model has exactly one primary key, there is no need to provide a value for this. If model has two or more primary keys, you must specify which one to use. For more information, see Specifying one of many primary keys.

includes must be a list of strings specifying which related resources will be included in a compound document by default when fetching a resource object representation of an instance of model. Each element of includes is the name of a field of model (that is, either an attribute or a relationship). For more information, see Inclusion of related resources.

If allow_to_many_replacement is True and this API allows PATCH requests, the server will allow two types of requests. First, it allows the client to replace the entire collection of resources in a to-many relationship when updating an individual instance of the model. Second, it allows the client to replace the entire to-many relationship when making a PATCH request to a to-many relationship endpoint. This is False by default. For more information, see Updating resources and Updating relationships.

If allow_delete_from_to_many_relationships is True and this API allows PATCH requests, the server will allow the client to delete resources from any to-many relationship of the model. This is False by default. For more information, see Updating relationships.

If allow_client_generated_ids is True and this API allows POST requests, the server will allow the client to specify the ID for the resource to create. JSON API recommends that this be a UUID. This is False by default. For more information, see Creating resources.

init_app(app)

Registers any created APIs on the given Flask application.

This function should only be called if no Flask application was provided in the app keyword argument to the constructor of this class.

When this function is invoked, any blueprint created by a previous invocation of create_api() will be registered on app by calling the register_blueprint() method.

To use this method with pure SQLAlchemy, for example:

from flask import Flask
from flask_restless import APIManager
from sqlalchemy import create_engine
from sqlalchemy.orm.session import sessionmaker

engine = create_engine('sqlite:////tmp/mydb.sqlite')
Session = sessionmaker(bind=engine)
mysession = Session()

# Here create model classes, for example User, Comment, etc.
...

# Create the API manager and create the APIs.
apimanager = APIManager(session=mysession)
apimanager.create_api(User)
apimanager.create_api(Comment)

# Later, call `init_app` to register the blueprints for the
# APIs created earlier.
app = Flask(__name__)
apimanager.init_app(app)

and with models defined with Flask-SQLAlchemy:

from flask import Flask
from flask_restless import APIManager
from flask_sqlalchemy import SQLAlchemy

db = SQLALchemy(app)

# Here create model classes, for example User, Comment, etc.
...

# Create the API manager and create the APIs.
apimanager = APIManager(flask_sqlalchemy_db=db)
apimanager.create_api(User)
apimanager.create_api(Comment)

# Later, call `init_app` to register the blueprints for the
# APIs created earlier.
app = Flask(__name__)
apimanager.init_app(app)
class flask_restless.IllegalArgumentError

This exception is raised when a calling function has provided illegal arguments to a function or method.

Search helper functions

flask_restless.register_operator(name, op)

Register an operator so the system can create expressions involving it.

name is a string naming the operator and op is a function that takes up to two arguments as input. If the name provided is one of the built-in operators (see Operators), it will override the default behavior of that operator. For example, calling

register_operator('gt', myfunc)

will cause myfunc() to be invoked in the SQLAlchemy expression created for this operator instead of the default “greater than” operator.

Global helper functions

flask_restless.collection_name(model, _apimanager=None)

Returns the collection name for the specified model, as specified by the collection_name keyword argument to APIManager.create_api() when it was previously invoked on the model.

model is a SQLAlchemy model class. This should be a model on which APIManager.create_api_blueprint() (or APIManager.create_api()) has been invoked previously. If no API has been created for it, this function raises a ValueError.

If _apimanager is not None, it must be an instance of APIManager. Restrict our search for endpoints exposing model to only endpoints created by the specified APIManager instance.

For example, suppose you have a model class Person and have created the appropriate Flask application and SQLAlchemy session:

>>> from mymodels import Person
>>> manager = APIManager(app, session=session)
>>> manager.create_api(Person, collection_name='people')
>>> collection_name(Person)
'people'

This function is the inverse of model_for():

>>> manager.collection_name(manager.model_for('people'))
'people'
>>> manager.model_for(manager.collection_name(Person))
<class 'mymodels.Person'>
flask_restless.model_for(collection_name, _apimanager=None)

Returns the model corresponding to the given collection name, as specified by the collection_name keyword argument to APIManager.create_api() when it was previously invoked on the model.

collection_name is a string corresponding to the “type” of a model. This should be a model on which APIManager.create_api_blueprint() (or APIManager.create_api()) has been invoked previously. If no API has been created for it, this function raises a ValueError.

If _apimanager is not None, it must be an instance of APIManager. Restrict our search for endpoints exposing model to only endpoints created by the specified APIManager instance.

For example, suppose you have a model class Person and have created the appropriate Flask application and SQLAlchemy session:

>>> from mymodels import Person
>>> manager = APIManager(app, session=session)
>>> manager.create_api(Person, collection_name='people')
>>> model_for('people')
<class 'mymodels.Person'>

This function is the inverse of collection_name():

>>> manager.collection_name(manager.model_for('people'))
'people'
>>> manager.model_for(manager.collection_name(Person))
<class 'mymodels.Person'>
flask_restless.serializer_for(model, _apimanager=None)

Returns the callable serializer object for the specified model, as specified by the serializer keyword argument to APIManager.create_api() when it was previously invoked on the model.

model is a SQLAlchemy model class. This should be a model on which APIManager.create_api_blueprint() (or APIManager.create_api()) has been invoked previously. If no API has been created for it, this function raises a ValueError.

If _apimanager is not None, it must be an instance of APIManager. Restrict our search for endpoints exposing model to only endpoints created by the specified APIManager instance.

For example, suppose you have a model class Person and have created the appropriate Flask application and SQLAlchemy session:

>>> from mymodels import Person
>>> def my_serializer(model, *args, **kw):
...     # return something cool here...
...     return {}
...
>>> manager = APIManager(app, session=session)
>>> manager.create_api(Person, serializer=my_serializer)
>>> serializer_for(Person)
<function my_serializer at 0x...>
flask_restless.primary_key_for(model, _apimanager=None)

Returns the primary key to be used for the given model or model instance, as specified by the primary_key keyword argument to APIManager.create_api() when it was previously invoked on the model.

primary_key is a string corresponding to the primary key identifier to be used by flask-restless for a model. If no primary key has been set at the flask-restless level (by using the primary_key keyword argument when calling APIManager.create_api_blueprint(), the model’s primary key will be returned. If no API has been created for the model, this function raises a ValueError.

If _apimanager is not None, it must be an instance of APIManager. Restrict our search for endpoints exposing model to only endpoints created by the specified APIManager instance.

For example, suppose you have a model class Person and have created the appropriate Flask application and SQLAlchemy session:

>>> from mymodels import Person
>>> manager = APIManager(app, session=session)
>>> manager.create_api(Person, primary_key='name')
>>> primary_key_for(Person)
'name'
>>> my_person = Person(name="Bob")
>>> primary_key_for(my_person)
'name'

This is in contrast to the typical default:

>>> manager = APIManager(app, session=session)
>>> manager.create_api(Person)
>>> primary_key_for(Person)
'id'
flask_restless.url_for(model, instid=None, relationname=None, relationinstid=None, _apimanager=None, **kw)

Returns the URL for the specified model, similar to flask.url_for().

model is a SQLAlchemy model class. This should be a model on which APIManager.create_api_blueprint() (or APIManager.create_api()) has been invoked previously. If no API has been created for it, this function raises a ValueError.

If _apimanager is not None, it must be an instance of APIManager. Restrict our search for endpoints exposing model to only endpoints created by the specified APIManager instance.

The resource_id, relation_name, and relationresource_id keyword arguments allow you to get the URL for a more specific sub-resource.

For example, suppose you have a model class Person and have created the appropriate Flask application and SQLAlchemy session:

>>> manager = APIManager(app, session=session)
>>> manager.create_api(Person, collection_name='people')
>>> url_for(Person, resource_id=3)
'http://example.com/api/people/3'
>>> url_for(Person, resource_id=3, relation_name=computers)
'http://example.com/api/people/3/computers'
>>> url_for(Person, resource_id=3, relation_name=computers,
...         related_resource_id=9)
'http://example.com/api/people/3/computers/9'

If a resource_id and a relation_name are provided, and you wish to determine the relationship endpoint URL instead of the related resource URL, set the relationship keyword argument to True:

>>> url_for(Person, resource_id=3, relation_name=computers,
...         relationship=True)
'http://example.com/api/people/3/relatonships/computers'

The remaining keyword arguments, kw, are passed directly on to flask.url_for().

Since this function creates absolute URLs to resources linked to the given instance, it must be called within a Flask request context.

Serialization and deserialization

class flask_restless.DefaultSerializer(only=None, exclude=None, additional_attributes=None, **kw)

A default implementation of a JSON API serializer for SQLAlchemy models.

The serialize() method of this class returns a complete JSON API document as a dictionary containing the resource object representation of the given instance of a SQLAlchemy model as its primary data. Similarly, the serialize_many() method returns a JSON API document containing a a list of resource objects as its primary data.

If only is a list, only these fields and relationships will in the returned dictionary. The only exception is that the keys 'id' and 'type' will always appear, regardless of whether they appear in only. These settings take higher priority than the only list provided to the serialize() or serialize_many() methods: if an attribute or relationship appears in the only argument to those method but not here in the constructor, it will not appear in the returned dictionary.

If exclude is a list, these fields and relationships will not appear in the returned dictionary.

If additional_attributes is a list, these attributes of the instance to be serialized will appear in the returned dictionary. This is useful if your model has an attribute that is not a SQLAlchemy column but you want it to be exposed.

You must not specify both only and exclude lists; if you do, the behavior of this function is undefined.

You must not specify a field in both exclude and in additional_attributes; if you do, the behavior of this function is undefined.

serialize(instance, only=None)

Returns a complete JSON API document as a dictionary containing the resource object representation of the given instance of a SQLAlchemy model as its primary data.

The returned dictionary is suitable as an argument to flask.json.jsonify(). Specifically, date and time objects (datetime.date, datetime.time, datetime.datetime, and datetime.timedelta) as well as uuid.UUID objects are converted to string representations, so no special JSON encoder behavior is required.

If only is a list, only the fields and relationships whose names appear as strings in only will appear in the resulting dictionary. This filter is applied after the default fields specified in the only keyword argument to the constructor of this class, so only fields that appear in both only keyword arguments will appear in the returned dictionary. The only exception is that the keys 'id' and 'type' will always appear, regardless of whether they appear in only.

Since this method creates absolute URLs to resources linked to the given instance, it must be called within a Flask request context.

serialize_many(instances, only=None)

Serializes each instance using its model-specific serializer.

This method works for heterogeneous collections of instances (that is, collections in which each instance is of a different type).

The only keyword argument must be a dictionary mapping resource type name to list of fields representing a sparse fieldset. The values in this dictionary must be valid values for the only keyword argument in the DefaultSerializer.serialize() method.

class flask_restless.DefaultDeserializer(session, model, allow_client_generated_ids=False, **kw)

A default implementation of a deserializer for SQLAlchemy models.

When called, this object returns an instance of a SQLAlchemy model with fields and relations specified by the provided dictionary.

deserialize(document)

Creates and returns a new instance of the SQLAlchemy model specified in the constructor whose attributes are given in the JSON API document.

document must be a dictionary representation of a JSON API document containing a single resource as primary data, as specified in the JSON API specification. For more information, see the Resource Objects section of the JSON API specification.

Implementation note: everything in the document other than the data element is ignored.

class flask_restless.SerializationException(instance, message=None, resource=None, *args, **kw)

Raised when there is a problem serializing an instance of a SQLAlchemy model to a dictionary representation.

instance is the (problematic) instance on which DefaultSerializer.serialize() was invoked.

message is an optional string describing the problem in more detail.

resource is an optional partially-constructed serialized representation of instance.

Each of these keyword arguments is stored in a corresponding instance attribute so client code can access them.

class flask_restless.DeserializationException(status=400, detail=None, *args, **kw)

Raised when there is a problem deserializing a Python dictionary to an instance of a SQLAlchemy model.

status is an integer representing the HTTP status code that corresponds to this error. If not specified, it is set to 400, representing 400 Bad Request.

detail is a string describing the problem in more detail. If provided, this will be incorporated in the return value of message().

Each of the keyword arguments status and detail are assigned directly to instance-level attributes status and detail.

detail = None

A string describing the problem in more detail.

message()

Returns a more detailed description of the problem as a string.

status = None

The HTTP status code corresponding to this error.

flask_restless.simple_serialize(self, instance, only=None)

Provides basic, uncustomized serialization functionality as provided by the DefaultSerializer.serialize() method.

This function is suitable for calling on its own, no other instantiation or customization necessary.

flask_restless.simple_serialize_many(self, instances, only=None)

Provides basic, uncustomized serialization functionality as provided by the DefaultSerializer.serialize_many() method.

This function is suitable for calling on its own, no other instantiation or customization necessary.

class flask_restless.MultipleExceptions(exceptions, *args, **kw)

Raised when there are multiple problems in serialization or deserialization.

exceptions is a non-empty sequence of other exceptions that have been raised in the code.

You may wish to raise this exception when implementing the DefaultSerializer.serialize_many() method, for example, if there are multiple exceptions

Pre- and postprocessor helpers

class flask_restless.ProcessingException(id_=None, links=None, status=400, code=None, title=None, detail=None, source=None, meta=None, *args, **kw)

Raised when a preprocessor or postprocessor encounters a problem.

This exception should be raised by functions supplied in the preprocessors and postprocessors keyword arguments to APIManager.create_api. When this exception is raised, all preprocessing or postprocessing halts, so any processors appearing later in the list will not be invoked.

The keyword arguments id_, href status, code, title, detail, links, paths correspond to the elements of the JSON API error object; the values of these keyword arguments will appear in the error object returned to the client.

Any additional positional or keyword arguments are supplied directly to the superclass, werkzeug.exceptions.HTTPException.