API¶
Router¶
- class flask_resty.Api(app=None, prefix='')[source]¶
The Api object controls the Flask-RESTy extension.
This can either be bound to an individual Flask application passed in at initialization, or to multiple applications via
init_app()
.After initializing an application, use this object to register resources with
add_resource()
, either to the bound application by default or to an explicitly-specified application object via theapp
keyword argument. Useadd_ping()
to add a ping endpoint for health checks.Once registered, Flask-RESTy will convert all HTTP errors thrown by the application to JSON.
By default your API will be rooted at ‘/’. Pass
prefix
to specify a custom root.- Parameters
app (
flask.Flask
) – The Flask application object.prefix (str) – The API path prefix.
- init_app(app)[source]¶
Initialize an application for use with Flask-RESTy.
- Parameters
app (
flask.Flask
) – The Flask application object.
- add_resource(base_rule, base_view, alternate_view=None, *, alternate_rule=None, id_rule=None, app=None)[source]¶
Add a REST resource.
- Parameters
base_rule (str) – The URL rule for the resource. This will be prefixed by the API prefix.
base_view (ApiView) – Class-based view for the resource.
alternate_view (ApiView) – If specified, an alternate class-based view for the resource. Usually, this will be a detail view, when the base view is a list view.
alternate_rule (str or None) – If specified, the URL rule for the alternate view. This will be prefixed by the API prefix. This is mutually exclusive with
id_rule
, and must not be specified ifalternate_view
is not specified.id_rule (str or None) – If specified, a suffix to append to
base_rule
to get the alternate view URL rule. Ifalternate_view
is specified, andalternate_rule
is not, then this defaults to ‘<id>’. This is mutually exclusive withalternate_rule
, and must not be specified ifalternate_view
is not specified.app (
flask.Flask
) – If specified, the application to which to add the route(s). Otherwise, this will be the bound application, if present.
- Raises
AssertionError – If no Flask application is bound or specified.
- add_ping(rule, *, status_code=200, app=None)[source]¶
Add a ping route.
- Parameters
rule (str) – The URL rule. This will not use the API prefix, as the ping endpoint is not really part of the API.
status_code (int) – The ping response status code. The default is 200 rather than the more correct 204 because many health checks look for 200s.
app (
flask.Flask
) – If specified, the application to which to add the route. Otherwise, this will be the bound application, if present.
- Raises
AssertionError – If no Flask application is bound or specified.
Views¶
- class flask_resty.ApiView[source]¶
Base class for views that expose API endpoints.
ApiView
extendsflask.views.MethodView
exposes functionality to deserialize request bodies and serialize response bodies according to standard API semantics.- schema = None¶
The
marshmallow.Schema
for serialization and deserialization.
- id_fields = ('id',)¶
The identifying fields for the model.
- args_schema = None¶
The
marshmallow.Schema
for deserializing the query params in theflask.Request.args
.
- authentication = <flask_resty.authentication.NoOpAuthentication object>¶
The authentication component. See
AuthenticationBase
.
- authorization = <flask_resty.authorization.NoOpAuthorization object>¶
The authorization component. See
AuthorizationBase
.
- dispatch_request(*args, **kwargs)[source]¶
Handle an incoming request.
By default, this checks request-level authentication and authorization before calling the upstream request handler.
- serialize(item, **kwargs)[source]¶
Dump an item using the
serializer
.This doesn’t technically serialize the item; it instead uses marshmallow to dump the item into a native Python data type. The actual serialization is done in
make_response
.Any provided
**kwargs
will be passed tomarshmallow.Schema.dump()
.
- serializer¶
The
marshmallow.Schema
for serialization.By default, this is
ApiView.schema
. This can be overridden to use a different schema for serialization.
- make_items_response(items, *args)[source]¶
Build a response for a sequence of multiple items.
This serializes the items, then builds an response with the list of serialized items as its data.
This is useful when returning a list of items.
The response will have the items available as the
items
attribute.- Parameters
items (list) – The objects to serialize into the response body.
- Returns
The HTTP response
- Return type
- make_item_response(item, *args)[source]¶
Build a response for a single item.
This serializes the item, then builds an response with the serialized item as its data. If the response status code is 201, then it will also include a
Location
header with the canonical URL of the item, if available.The response will have the item available as the
item
attribute.- Parameters
item (object) – The object to serialize into the response body.
- Returns
The HTTP response
- Return type
- set_item_response_meta(item)[source]¶
Hook for setting additional metadata for an item.
This should call
meta.update_response_meta
to set any metadata values to add to the response.- Parameters
item (object) – The object for which to generate metadata.
- Returns
- make_response(data, *args, **kwargs)[source]¶
Build a response for arbitrary dumped data.
This builds the response body given the data and any metadata from the request context. It then serializes the response.
- Returns
The HTTP response
- Return type
- render_response_body(data, response_meta)[source]¶
Render the response data and metadata into a body.
This is the final step of building the response payload before serialization.
By default, this builds a dictionary with a
data
item for the response data and ameta
item for the response metadata, if any.
- make_raw_response(*args, **kwargs)[source]¶
Convenience method for creating a
flask.Response
.Any supplied keyword arguments are defined as attributes on the response object itself.
- Returns
The HTTP response
- Return type
- make_empty_response(**kwargs)[source]¶
Build an empty response.
This response has a status code of 204 and an empty body.
- Returns
The HTTP response
- Return type
- make_created_response(item)[source]¶
Build a response for a newly created item.
This response will be for the item data and will have a status code of 201. It will include a
Location
header with the canonical URL of the created item, if available.- Parameters
item (object) – The created item.
- Returns
The HTTP response
- Return type
- make_deleted_response(item)[source]¶
Build a response for a deleted item.
By default, this will be an empty response. The empty response will have the
item
attribute as with an item response.- Parameters
item (object) – The deleted item.
- Returns
The HTTP response
- Return type
- get_location(item)[source]¶
Get the canonical URL for an item.
Override this to return
None
if no such URL is available.
- get_request_data(**kwargs)[source]¶
Deserialize and load data from the body of the current request.
By default, this will look for the value under the
data
key in a JSON request body.- Returns
The deserialized request data
- Return type
- parse_request_data()[source]¶
Deserialize the data for the current request.
This will deserialize the request data from the request body into a native Python object that can be loaded by marshmallow.
- Returns
The deserialized request data.
- deserialize(data_raw, *, expected_id=None, **kwargs)[source]¶
Load data using the
deserializer
.This doesn’t technically deserialize the data; it instead uses marshmallow to load and validate the data. The actual deserialization happens in
parse_request_data
.Any provided
**kwargs
will be passed tomarshmallow.Schema.load()
.- Parameters
data_raw – The request data to load.
expected_id – The expected ID in the request data. See
validate_request_id
.
- Returns
The deserialized data
- Return type
- deserializer¶
The
marshmallow.Schema
for serialization.By default, this is
ApiView.schema
. This can be overridden to use a different schema for deserialization.
- format_validation_error(message, path)[source]¶
Convert marshmallow validation error data to a serializable form.
This converts marshmallow validation error data to a standard serializable representation. By default, it converts errors into a dictionary of the form:
{ "code": "invalid_data", "detail": "<error message>", "source": { "pointer": "/data/<field name>" } }
- validate_request_id(data, expected_id)[source]¶
Check that the request data has the expected ID.
This is generally used to assert that update operations include the correct item ID and that create operations do not include an ID.
This works in one of three modes:: - If
expected_id
isNone
, do no checking - Ifexpected_id
isFalse
, check that no ID is provided - Otherwise, check thatdata
has the expected ID- Parameters
data – The request data.
expected_id – The ID or ID tuple, or False, or None.
- Raises
ApiError – If the necessary IDs are not present and correct
- get_data_id(data)[source]¶
Get the ID as a scalar or tuple from request data.
The ID will be a scalar if
id_fields
contains a single field or a tuple if it contains multiple.- Returns
The ID scalar or tuple.
- property request_args¶
The query arguments for the current request.
This uses
args_schema
to load the current query args. This value is cached per request, and will be computed the first time it is called for any request.- Returns
The query arguments.
- Return type
- deserialize_args(data_raw, **kwargs)[source]¶
Load parsed query arg data using
args_schema
.As with
deserialize
, contra the name, this handles loading with a schema rather than deserialization per se.- Parameters
data_raw (dict) – The raw query data.
kwargs (dict) – Additional keyword arguments for
marshmallow.Schema.load
.
- Returns
The deserialized data
- Return type
- format_parameter_validation_error(message, parameter)[source]¶
Convert a parameter validation error to a serializable form.
This closely follows
format_validation_error
, but produces error dictionaries of the form:{ "code": "invalid_parameter", "detail": "<error message>", "source": { "parameter": "<parameter name>" } }
- get_id_dict(id)[source]¶
Convert an ID from
get_data_id
to dictionary form.This converts an ID from
get_data_id
into a dictionary where each ID value is keyed by the corresponding ID field name.- Parameters
id – An ID from
get_id_dict
- Type
- Returns
A mapping from ID field names to ID field values
- Return type
- class flask_resty.GenericModelView[source]¶
Base class for API views implementing CRUD methods.
GenericModelView
provides basic implementations of the standard CRUD HTTP methods using the methods implemented inModelView
.In simple APIs, most view classes will extend
GenericModelView
, and will declare methods that immediately call the methods here.class WidgetViewBase(GenericModelView): model = models.Widget schema = models.WidgetSchema() class WidgetListView(WidgetViewBase): def get(self): return self.list() def post(self): return self.create() class WidgetView(WidgetViewBase): def get(self, id): return self.retrieve(id) def patch(self, id): return self.update(id, partial=True) def delete(self, id): return self.destroy(id)
To extend or otherwise customize the behavior of the methods here, override the methods in
MethodView
.- list()[source]¶
Return a list of items.
This is the standard GET handler on a list view.
- Returns
An HTTP 200 response.
- Return type
- retrieve(id, *, create_transient_stub=False)[source]¶
Retrieve an item by ID.
This is the standard
GET
handler on a detail view.- Parameters
id – The item ID.
create_transient_stub (bool) – If set, create and retrieve a transient stub for the item if it is not found. This will not save the stub to the database.
- Returns
An HTTP 200 response.
- Return type
- create(*, allow_client_id=False)[source]¶
Create a new item using the request data.
This is the standard
POST
handler on a list view.- Parameters
allow_client_id (bool) – If set, allow the client to specify ID fields for the item.
- Returns
An HTTP 201 response.
- Return type
- update(id, *, with_for_update=False, partial=False)[source]¶
Update the item for the specified ID with the request data.
This is the standard
PUT
handler on a detail view ifpartial
is not set, or the standardPATCH
handler ifpartial
is set.- Parameters
- Returns
An HTTP 200 response.
- Return type
- upsert(id, *, with_for_update=False)[source]¶
Upsert the item for the specified ID with the request data.
This will update the item for the given ID, if that item exists. Otherwise, this will create a new item with the request data.
- Parameters
id – The item ID.
with_for_update (bool) – If set, lock the item row while updating using
FOR UPDATE
.
- Returns
An HTTP 200 or 201 response.
- Return type
- class flask_resty.ModelView[source]¶
Base class for API views tied to SQLAlchemy models.
ModelView
implements additional methods on top of those provided byApiView
to interact with SQLAlchemy models.The functionality in this class largely ties together the authorization and the model. It provides for access to the model query as appropriately filtered for authorized rows, and provides methods to create or update model instances from request data with authorization checks.
It also provides functionality to apply filtering, sorting, and pagination when getting lists of items, and for resolving related items when deserializing request data.
- model = None¶
A declarative SQLAlchemy model.
- filtering = None¶
An instance of
filtering.Filtering
.
- sorting = None¶
An instance of
sorting.SortingBase
.
- pagination = None¶
An instance of
pagination.PaginationBase
.
An instance of
related.Related
.
- session¶
Convenience property for the current SQLAlchemy session.
- query_raw¶
The raw SQLAlchemy query for the view.
This is the base query, without authorization filters or query options. By default, this is the query property on the model class. This can be overridden to remove filters attached to that query.
- query¶
The SQLAlchemy query for the view.
Override this to customize the query to fetch items in this view.
By default, this applies the filter from the view’s
authorization
and the query options frombase_query_options
andquery_options
.
- base_query_options = ()¶
Base query options to apply before
query_options
.Set this on a base class to define base query options for its subclasses, while still allowing those subclasses to define their own additional query options via
query_options
.For example, set this to
(raiseload('*', sql_only=True),)
to prevent all implicit SQL-emitting relationship loading, and force all relationship loading to be explicitly defined viaquery_options
.
- query_options¶
Options to apply to the query for the view.
Set this to configure relationship and column loading.
By default, this calls the
get_query_options
method on the serializer with aLoad
object bound to the model, if that serializer method exists.- Returns
A sequence of query options.
- Return type
- get_list()[source]¶
Retrieve a list of items.
This takes the output of
get_list_query
and applies pagination.- Returns
The list of items.
- Return type
- get_list_query()[source]¶
Build the query to retrieve a filtered and sorted list of items.
- Returns
The list query.
- Return type
- filter_list_query(query)[source]¶
Apply filtering as specified to the provided
query
.- Param
A SQL query
- Type
- Returns
The filtered query
- Return type
- sort_list_query(query)[source]¶
Apply sorting as specified to the provided
query
.- Param
A SQL query
- Type
- Returns
The sorted query
- Return type
- paginate_list_query(query)[source]¶
Retrieve the requested page from
query
.If
pagination
is configured, this will retrieve the page as specified by the request and the pagination configuration. Otherwise, this will retrieve all items from the query.- Param
A SQL query
- Type
- Returns
The paginated query
- Return type
- get_item_or_404(id, **kwargs)[source]¶
Get an item by ID; raise a 404 if it not found.
This will get an item by ID per
get_item
below. If no item is found, it will rethrow theNoResultFound
exception as an HTTP 404.- Parameters
id – The item ID.
- Returns
The item corresponding to the ID.
- Return type
- get_item(id, *, with_for_update=False, create_transient_stub=False)[source]¶
Get an item by ID.
The ID should be the scalar ID value if
id_fields
specifies a single field. Otherwise, it should be a tuple of each ID field value, corresponding to the elements ofid_fields
.- Parameters
id – The item ID.
with_for_update (bool) – If set, lock the item row for updating using
FOR UPDATE
.create_transient_stub (bool) – If set, create and return a transient stub for the item using
create_stub_item
if it is not found. This will not save the stub to the database.
- Returns
The item corresponding to the ID.
- Return type
- deserialize(data_raw, **kwargs)[source]¶
Load data using the
deserializer
.In addition to the functionality of
ApiView.deserialize()
, this will resolve related items using the configuredrelated
.
Resolve all related fields per
related
.
Retrieve the related item corresponding to the provided data stub.
This is used by
Related
when this view is set for a field.
Retrieve the related item corresponding to the provided ID.
This is used by
Related
when a field is specified as aRelatedId
.- Parameters
id – The item ID.
- Returns
The item corresponding to the ID.
- Return type
- create_stub_item(id)[source]¶
Create a stub item that corresponds to the provided ID.
This is used by
get_item
whencreate_transient_stub
is set.Override this to configure the creation of stub items.
- Parameters
id – The item ID.
- Returns
A transient stub item corresponding to the ID.
- Return type
- create_item(data)[source]¶
Create an item using the provided data.
This will invoke
authorize_create_item
on the created item.Override this to configure the creation of items, e.g. by adding additional entries to
data
.
- create_item_raw(data)[source]¶
As with
create_item
, but without the authorization check.This is used by
create_item
, which then applies the authorization check.Override this instead of
create_item
when applying other modifications to the item that should take place before running the authorization check.
- add_item(item)[source]¶
Add an item to the current session.
This will invoke
authorize_save_item
on the item to add.- Parameters
item (object) – The item to add.
- add_item_raw(item)[source]¶
As with
add_item
, but without the authorization check.This is used by
add_item
, which then applies the authorization check.- Parameters
item (object) – The item to add.
- create_and_add_item(data)[source]¶
Create an item using the provided data, then add it to the session.
This uses
create_item
andadd_item
. Correspondingly, it will invoke bothauthorize_create_item
andauthorize_save_item
on the item.
- update_item(item, data)[source]¶
Update an existing item with the provided data.
This will invoke
authorize_update_item
using the provided item and data before updating the item, thenauthorize_save_item
on the updated item afterward.Override this to configure the updating of items, e.g. by adding additional entries to
data
.
- update_item_raw(item, data)[source]¶
As with
update_item
, but without the authorization checks.Override this instead of
update_item
when applying other modifications to the item that should take place before and after the authorization checks in the above.
- upsert_item(id, data, with_for_update=False)[source]¶
Update an existing item with the matching id or if the item does not exist yet, create and insert it.
This combines
self.create_and_add_item
andself.update_item
depending on if the item exists or not.- Parameters
- Returns
a tuple consisting of the newly created or the updated item and True if the item was created, False otherwise.
- Return type
- delete_item(item)[source]¶
Delete an existing item.
This will run
authorize_delete_item
on the item before deleting it.
- delete_item_raw(item)[source]¶
As with
delete_item
, but without the authorization check.Override this to customize the delete behavior, e.g. by replacing the delete action with an update to mark the item deleted.
- Parameters
item (object) – The item to delete.
- flush(*, objects=None)[source]¶
Flush pending changes to the database.
This will check database level invariants, and will throw exceptions as with
commit
if any invariant violations are found.It’s a common pattern to call
flush
, then make external API calls, then callcommit
. Theflush
call will do a preliminary check on database-level invariants, making it less likely that thecommit
operation will fail, and reducing the risk of the external systems being left in an inconsistent state.- Parameters
objects – If specified, the specific objects to flush. Otherwise, all pending changes will be flushed.
- Returns
- commit()[source]¶
Commit changes to the database.
Any integrity errors that arise will be passed to
resolve_integrity_error
, which is expected to convert integrity errors corresponding to cross-row database-level invariant violations to HTTP 409 responses.- Raises
ApiError
if the commit fails with integrity errors arising from foreign key or unique constraint violations.
- resolve_integrity_error(error)[source]¶
Convert integrity errors to HTTP error responses as appropriate.
Certain kinds of database integrity errors cannot easily be caught by schema validation. These errors include violations of unique constraints and of foreign key constraints. While it’s sometimes possible to check for those in application code, it’s often best to let the database handle those. This will then convert those integrity errors to HTTP 409 responses.
On PostgreSQL, this uses additional integrity error details to not convert NOT NULL violations and CHECK constraint violations to HTTP 409 responses, as such checks should be done in the schema.
- Returns
The resolved error.
- Return type
- flask_resty.get_item_or_404(func=None, **decorator_kwargs)[source]¶
Make a view method receive an item rather than the item’s ID.
This decorator takes the ID fields per
id_fields
on the view class, then uses them to fetch the corresponding item using theget_item_or_404
on the view class.This function can be used directly as a decorator, or it can be called with keyword arguments and then used to decorate a method to pass those arguments to
get_item_or_404
:class MyView(ModelView): @get_item_or_404 def get(self, item): pass @get_item_or_404(with_for_update=True) def put(self, item): pass
- Parameters
func (function or None) – The function to decorate
- Returns
The decorated function or a decorator factory
- Return type
function
Authentication¶
- class flask_resty.AuthenticationBase[source]¶
Base class for API authentication components.
Authentication components are responsible for extracting the request credentials, if any. They should raise a 401 if the credentials are invalid, but should provide
None
for unauthenticated users.Flask-RESTy provides an implementation using JSON Web Tokens but you can use any authentication component by extending
AuthenticationBase
and implementingget_request_credentials()
.- authenticate_request()[source]¶
Store the request credentials in the
flask.ctx.AppContext
.Warning
No validation is performed by Flask-RESTy. It is up to the implementor to validate the request in
get_request_credentials()
.
- get_request_credentials()[source]¶
Get the credentials for the current request.
Typically this is done by inspecting
flask.request
.Warning
Implementing classes must raise an exception on authentication failure. A 401 Unauthorized
ApiError
is recommended.- Returns
The credentials for the current request.
- class flask_resty.NoOpAuthentication[source]¶
An authentication component that provides no credentials.
- class flask_resty.HeaderAuthenticationBase[source]¶
Base class for header authentication components.
These authentication components get their credentials from the
Authorization
request header. The Authorization header has the form:Authorization: <scheme> <token>
This class also supports fallback to a query parameter, for cases where API clients cannot set headers.
- header_scheme = 'Bearer'¶
Corresponds to the <scheme> in the Authorization request header.
- credentials_arg = None¶
A fallback query parameter. The value of this query parameter will be used as credentials if the Authorization request header is missing.
- get_request_credentials()[source]¶
Get the credentials for the current request.
Typically this is done by inspecting
flask.request
.Warning
Implementing classes must raise an exception on authentication failure. A 401 Unauthorized
ApiError
is recommended.- Returns
The credentials for the current request.
- class flask_resty.HeaderAuthentication[source]¶
Header authentication component where the token is the credential.
This authentication component is useful for simple applications where the token itself is the credential, such as when it is a fixed secret shared between the client and the server that uniquely identifies the client.
Relationships¶
- class flask_resty.Related(item_class=None, **kwargs)[source]¶
A component for resolving deserialized data fields to model instances.
The
Related
component is responsible for resolving related model instances by ID and for constructing nested model instances. It supports multiple related types of functionality. For a view with:related = Related( foo=RelatedId(FooView, "foo_id"), bar=BarView, baz=Related(models.Baz, qux=RelatedId(QuxView, "qux_id"), )
Given deserialized input data like:
{ "foo_id": "3", "bar": {"id": "4"}, "baz": {name: "Bob", "qux_id": "5"}, "other_field": "value", }
This component will resolve these data into something like:
{ "foo": <Foo(id=3)>, "bar": <Bar(id=4)>, "baz": <Baz(name="Bob", qux=<Qux(id=5)>>, "other_field": "value", }
In this case, the Foo, Bar, and Qux instances are fetched from the database, while the Baz instance is freshly constructed. If any of the Foo, Bar, or Qux instances do not exist, then the component will fail the request with a 422.
Formally, in this specification:
A
RelatedId
item will retrieve the existing object in the database with the ID from the specified scalar ID field using the specified view.A view class will retrieve the existing object in the database using the object stub containing the ID fields from the data field of the same name, using the specified view. This is generally used with the
RelatedItem
field class, and unlikeRelatedId
, supports composite IDs.Another
Related
item will apply the same resolution to a nested dictionary. Additionally, if theRelated
item is given a callable as its positional argument, it will construct a new instance given that callable, which can often be a model class.
Related
depends on the deserializer schema to function accordingly, and delegates validation beyond the database fetch to the schema.Related
also automatically supports cases where the fields are list fields or are configured withmany=True
. In those cases,Related
will iterate through the sequence and resolve each item in turn, using the rules as above.- Parameters
item_class – The SQLAlchemy mapper corresponding to the related item.
kwargs (dict) – A mapping from related fields to a callable resolver.
Resolve the related values in the request data.
This method will replace values in
data
with resolved model instances as described above. This operates in place and will mutatedata
.- Parameters
object (data) – The deserialized request data.
- Returns
The deserialized data with related fields resolved.
- Return type
- class flask_resty.RelatedItem(nested: SchemaABC | type | str | dict[str, Field | type] | typing.Callable[[], SchemaABC | dict[str, Field | type]], *, dump_default: typing.Any = <marshmallow.missing>, default: typing.Any = <marshmallow.missing>, only: types.StrSequenceOrSet | None = None, exclude: types.StrSequenceOrSet = (), many: bool = False, unknown: str | None = None, **kwargs)[source]¶
A nested object field that only requires the ID on load.
This class is a wrapper around
marshmallow.fields.Nested
that provides simplified semantics in the context of a normalized REST API.When dumping, this field will dump the nested object as normal. When loading, this field will do a partial load to retrieve just the ID. This is because, when interacting with a resource that has a relationship to existing instances of another resource, the ID is sufficient to uniquely identify instances of the other resource.
Filtering¶
- class flask_resty.ArgFilterBase[source]¶
An abstract specification of a filter from a query argument.
Implementing classes must provide
maybe_set_arg_name()
andfilter_query()
.- maybe_set_arg_name(arg_name)[source]¶
Set the name of the argument to which this filter is bound.
- Parameters
arg_name (str) – The name of the field to filter against.
- Raises
NotImplementedError
if no implementation is provided.
- filter_query(query, view, arg_value)[source]¶
Filter the query.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to filter.view (
ModelView
) – The view with the model we wish to filter for.arg_value (str) – The filter specification
- Returns
The filtered query
- Return type
- Raises
NotImplementedError
if no implementation is provided.
- class flask_resty.ColumnFilter(column_name=None, operator=None, *, required=False, missing=<marshmallow.missing>, validate=True, **kwargs)[source]¶
A filter that operates on the value of a database column.
This filter relies on the schema to deserialize the query argument values.
ColumnFilter
cannot normally be used for columns that do not appear on the schema, but such columns can be added to the schema with fields that have bothload_only
anddump_only
set.- Parameters
column_name (str) – The name of the column to filter against.
operator (func) – A callable that returns the filter expression given the column and the filter value.
required (bool) – If set, fail if this filter is not specified.
validate (bool) – If unset, bypass validation on the field. This is useful if the field specifies validation rule for inputs that are not relevant for filters.
- maybe_set_arg_name(arg_name)[source]¶
Set
arg_name
as the column name if no explicit value is available.- Parameters
arg_name (str) – The name of the column to filter against.
- get_field(view)[source]¶
Construct the marshmallow field for deserializing filter values.
This takes the field from the deserializer, then creates a copy with the desired semantics around missing values.
- Parameters
view (
ModelView
) – The view with the model we wish to filter for.
- get_filter_clause(view, value)[source]¶
Build the filter clause for the deserialized value.
- Parameters
- Raises
NotImplementedError
if no implementation is provided.
- deserialize(field, value_raw)[source]¶
Deserialize
value_raw
, optionally skipping validation.- Parameters
field (
marshmallow.fields.Field
) – The marshmallow field.value_raw – The value to deserialize.
- Returns
The deserialized value.
- filter_query(query, view, arg_value)¶
Filter the query.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to filter.view (
ModelView
) – The view with the model we wish to filter for.arg_value (str) – The filter specification
- Returns
The filtered query
- Return type
- Raises
NotImplementedError
if no implementation is provided.
- class flask_resty.FieldFilterBase(*, separator=',', allow_empty=False, skip_invalid=False)[source]¶
A filter that uses a marshmallow field to deserialize its value.
Implementing classes must provide
get_filter_field()
andget_filter_clause()
.- Parameters
- maybe_set_arg_name(arg_name)[source]¶
Set the name of the argument to which this filter is bound.
- Parameters
arg_name (str) – The name of the field to filter against.
- Raises
NotImplementedError
if no implementation is provided.
- filter_query(query, view, arg_value)[source]¶
Filter the query.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to filter.view (
ModelView
) – The view with the model we wish to filter for.arg_value (str) – The filter specification
- Returns
The filtered query
- Return type
- Raises
NotImplementedError
if no implementation is provided.
- deserialize(field, value_raw)[source]¶
Overridable hook for deserializing a value.
- Parameters
field (
marshmallow.fields.Field
) – The marshmallow field.value_raw – The value to deserialize.
- Returns
The deserialized value.
- get_field(view)[source]¶
Get the marshmallow field for deserializing filter values.
- Parameters
view (
ModelView
) – The view with the model we wish to filter for.- Raises
NotImplementedError
if no implementation is provided.
- get_filter_clause(view, value)[source]¶
Build the filter clause for the deserialized value.
- Parameters
- Raises
NotImplementedError
if no implementation is provided.
- class flask_resty.Filtering(**kwargs)[source]¶
Container for the arg filters on a
ModelView
.- Parameters
kwargs (dict) – A mapping from filter field names to filters.
- filter_query(query, view)[source]¶
Filter a query using the configured filters and the request args.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to filter.view (
ModelView
) – The view with the model we wish to filter for.
- Returns
The filtered query
- Return type
- flask_resty.model_filter(field, **kwargs)[source]¶
A convenience decorator for building a
ModelFilter
.This decorator allows building a
ModelFilter
around a named function:@model_filter(fields.String(required=True)) def filter_color(model, value): return model.color == value
- Parameters
field (
marshmallow.fields.Field
) – A marshmallow field for deserializing filter values.kwargs (dict) – Passed to
ModelFilter
.
- class flask_resty.ModelFilter(field, filter, **kwargs)[source]¶
An arbitrary filter against the model.
- Parameters
field (
marshmallow.fields.Field
) – A marshmallow field for deserializing filter values.filter – A callable that returns the filter expression given the model and the filter value.
kwargs (dict) – Passed to
FieldFilterBase
.
- get_field(view)[source]¶
Get the marshmallow field for deserializing filter values.
- Parameters
view (
ModelView
) – The view with the model we wish to filter for.- Raises
NotImplementedError
if no implementation is provided.
- get_filter_clause(view, value)[source]¶
Build the filter clause for the deserialized value.
- Parameters
- Raises
NotImplementedError
if no implementation is provided.
- deserialize(field, value_raw)¶
Overridable hook for deserializing a value.
- Parameters
field (
marshmallow.fields.Field
) – The marshmallow field.value_raw – The value to deserialize.
- Returns
The deserialized value.
- filter_query(query, view, arg_value)¶
Filter the query.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to filter.view (
ModelView
) – The view with the model we wish to filter for.arg_value (str) – The filter specification
- Returns
The filtered query
- Return type
- Raises
NotImplementedError
if no implementation is provided.
- maybe_set_arg_name(arg_name)¶
Set the name of the argument to which this filter is bound.
- Parameters
arg_name (str) – The name of the field to filter against.
- Raises
NotImplementedError
if no implementation is provided.
Pagination¶
- class flask_resty.CursorPaginationBase(*args, validate_values=True, **kwargs)[source]¶
The base class for pagination schemes that use cursors.
Unlike with offsets that identify items by relative position, cursors identify position by content. This allows continuous pagination without concerns about page shear on dynamic collections. This makes cursor-based pagination especially effective for lists with infinite scroll dynamics, as offset-based pagination can miss or duplicate items due to inserts or deletes.
It’s also more efficient against the database, as the cursor condition can be cheaply evaluated as a filter against an index.
- Parameters
validate (bool) – If unset, bypass validation on cursor values. This is useful if the deserializer field imposes validation that will fail for on cursor values for items actually present.
- cursor_arg = 'cursor'¶
The name of the query parameter to inspect for the cursor value.
- after_arg = 'after'¶
the name of the query parameter to inspect for explicit forward pagination
- before_arg = 'before'¶
the name of the query parameter to inspect for explicit backward pagination
- get_limit()[source]¶
Override this method to return the maximum number of returned items.
- Return type
- adjust_sort_ordering(view: flask_resty.view.ModelView, field_orderings) Tuple[Tuple[str, bool], ...] [source]¶
Ensure the query is sorted correctly and get the field orderings.
The implementation of cursor-based pagination in Flask-RESTy requires that the query be sorted in a fully deterministic manner. The timestamp columns usually used in sorting do not quite qualify, as two different rows can have the same timestamp. This method adds the ID fields to the sorting criterion, then returns the field orderings for use in the other methods, as in
get_field_orderings
below.- Parameters
view (
ModelView
) – The view with the model we wish to paginate.- Returns
The field orderings necessary to do cursor pagination deterministically
- Return type
FieldOrderings
- get_request_cursor(view, field_orderings)[source]¶
Get the cursor value specified in the request.
Given the view and the field_orderings as above, this method will read the encoded cursor from the query, then return the cursor as a tuple of the field values in the cursor.
This parsed cursor can then be used in
get_filter
.- Parameters
view (
ModelView
) – The view with the model we wish to paginate.field_orderings (seq) – A sequence of field_ordering tuples
- Returns
A cursor value
- Return type
- Raises
ApiError
if an invalid cursor is provided incursor_arg
.
- get_filter(view, field_orderings: Tuple[Tuple[str, bool], ...], cursor: Tuple[Any, ...])[source]¶
Build the filter clause corresponding to a cursor.
Given the field orderings and the cursor as above, this will construct a filter clause that can be used to filter a query to return only items after the specified cursor, per the specified field orderings. Use this to apply the equivalent of the offset specified by the cursor.
- Parameters
view (
ModelView
) – The view with the model we wish to paginate.field_orderings (seq) – A sequence of field_ordering tuples derived from the view’s Sorting with explicit id ordering
cursor (seq) – A set of values corresponding to the fields in
field_orderings
- Returns
A filter clause
- make_cursors(items, view, field_orderings)[source]¶
Build a cursor for each of many items.
This method creates a cursor for each item in
items
. It produces the same cursors asmake_cursor()
, but is slightly more efficient in cases where cursors for multiple items are required.- Parameters
items (seq) – A sequence of instances of
ApiView.model
view (
ModelView
) – The view we wish to paginate.field_orderings (seq) – A sequence of (field, asc?).
- Returns
A sequence of
marshmallow.Field
.- Return type
seq
- make_cursor(item, view, field_orderings)[source]¶
Build a cursor for a given item.
Given an item and the field orderings as above, this builds a cursor for the item. This cursor encodes the value for each field on the item per the specified field orderings.
This cursor should be returned in page or item metadata to allow pagination continuing after the cursor for the item.
- Parameters
item (obj) – An instance
ApiView.model
view (
ModelView
) – The view we wish to paginate.field_orderings (seq) – A sequence of (field, asc?).
- Returns
A sequence of
marshmallow.Field
.- Return type
seq
- get_item_meta(item, view)¶
Build pagination metadata for a single item.
- Parameters
item (obj) – An instance of the
ModelView.model
.view (
ModelView
) – The view with theModelView.model
.
- get_page(query, view) List ¶
Restrict the specified query to a single page.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to paginate.view (
ModelView
) – The view with the model we wish to paginate.
- Returns
The paginated query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- class flask_resty.LimitOffsetPagination(default_limit=None, max_limit=None)[source]¶
A pagination scheme that takes a user-specified limit and offset.
This pagination scheme takes a user-specified limit and offset. It will retrieve up to the specified number of items, beginning at the specified offset.
- offset_arg = 'offset'¶
The name of the query parameter to inspect for the OFFSET value.
- get_page(query, view)[source]¶
Restrict the specified query to a single page.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to paginate.view (
ModelView
) – The view with the model we wish to paginate.
- Returns
The paginated query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- get_item_meta(item, view)¶
Build pagination metadata for a single item.
- Parameters
item (obj) – An instance of the
ModelView.model
.view (
ModelView
) – The view with theModelView.model
.
- class flask_resty.LimitPagination(default_limit=None, max_limit=None)[source]¶
A pagination scheme that takes a user-specified limit.
This is not especially useful and is included only for completeness.
This pagination scheme uses the
limit_arg
query parameter to limit the number of items returned by the query.If no such limit is explicitly specified, this uses
default_limit
. Ifmax_limit
is specified, then the user-specified limit may not exceedmax_limit
.- Parameters
- limit_arg = 'limit'¶
The name of the query parameter to inspect for the LIMIT value.
- get_limit()[source]¶
Override this method to return the maximum number of returned items.
- Return type
- get_item_meta(item, view)¶
Build pagination metadata for a single item.
- Parameters
item (obj) – An instance of the
ModelView.model
.view (
ModelView
) – The view with theModelView.model
.
- get_page(query, view) List ¶
Restrict the specified query to a single page.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to paginate.view (
ModelView
) – The view with the model we wish to paginate.
- Returns
The paginated query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- class flask_resty.MaxLimitPagination(max_limit)[source]¶
Return up to a fixed maximum number of items.
This is not especially useful and is included only for completeness.
- Parameters
max_limit (int) – The maximum number of items to retrieve.
- get_limit()[source]¶
Override this method to return the maximum number of returned items.
- Return type
- get_item_meta(item, view)¶
Build pagination metadata for a single item.
- Parameters
item (obj) – An instance of the
ModelView.model
.view (
ModelView
) – The view with theModelView.model
.
- get_page(query, view) List ¶
Restrict the specified query to a single page.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to paginate.view (
ModelView
) – The view with the model we wish to paginate.
- Returns
The paginated query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- class flask_resty.PagePagination(page_size)[source]¶
A pagination scheme that fetches a particular fixed-size page.
This works similar to
LimitOffsetPagination
. The limit used will always be the fixed page size. The offset will be page * page_size.- Parameters
page_size (int) – The fixed number of items per page.
- page_arg = 'page'¶
The name of the query parameter to inspect for the page value.
- get_limit()[source]¶
Override this method to return the maximum number of returned items.
- Return type
- get_item_meta(item, view)¶
Build pagination metadata for a single item.
- Parameters
item (obj) – An instance of the
ModelView.model
.view (
ModelView
) – The view with theModelView.model
.
- get_page(query, view)¶
Restrict the specified query to a single page.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to paginate.view (
ModelView
) – The view with the model we wish to paginate.
- Returns
The paginated query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- class flask_resty.RelayCursorPagination(*args, page_info_arg=None, default_include_page_info=False, **kwargs)[source]¶
A pagination scheme that works with the Relay specification.
This pagination scheme assigns a cursor to each retrieved item. The page metadata will contain an array of cursors, one per item. The item metadata will include the cursor for the fetched item.
For Relay Cursor Connections Specification, see https://facebook.github.io/relay/graphql/connections.htm.
- get_page(query, view)[source]¶
Restrict the specified query to a single page.
- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to paginate.view (
ModelView
) – The view with the model we wish to paginate.
- Returns
The paginated query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- get_item_meta(item, view)[source]¶
Build pagination metadata for a single item.
- Parameters
item (obj) – An instance of the
ModelView.model
.view (
ModelView
) – The view with theModelView.model
.
- adjust_sort_ordering(view: flask_resty.view.ModelView, field_orderings) Tuple[Tuple[str, bool], ...] ¶
Ensure the query is sorted correctly and get the field orderings.
The implementation of cursor-based pagination in Flask-RESTy requires that the query be sorted in a fully deterministic manner. The timestamp columns usually used in sorting do not quite qualify, as two different rows can have the same timestamp. This method adds the ID fields to the sorting criterion, then returns the field orderings for use in the other methods, as in
get_field_orderings
below.- Parameters
view (
ModelView
) – The view with the model we wish to paginate.- Returns
The field orderings necessary to do cursor pagination deterministically
- Return type
FieldOrderings
- get_filter(view, field_orderings: Tuple[Tuple[str, bool], ...], cursor: Tuple[Any, ...])¶
Build the filter clause corresponding to a cursor.
Given the field orderings and the cursor as above, this will construct a filter clause that can be used to filter a query to return only items after the specified cursor, per the specified field orderings. Use this to apply the equivalent of the offset specified by the cursor.
- Parameters
view (
ModelView
) – The view with the model we wish to paginate.field_orderings (seq) – A sequence of field_ordering tuples derived from the view’s Sorting with explicit id ordering
cursor (seq) – A set of values corresponding to the fields in
field_orderings
- Returns
A filter clause
- get_request_cursor(view, field_orderings)¶
Get the cursor value specified in the request.
Given the view and the field_orderings as above, this method will read the encoded cursor from the query, then return the cursor as a tuple of the field values in the cursor.
This parsed cursor can then be used in
get_filter
.
- make_cursor(item, view, field_orderings)¶
Build a cursor for a given item.
Given an item and the field orderings as above, this builds a cursor for the item. This cursor encodes the value for each field on the item per the specified field orderings.
This cursor should be returned in page or item metadata to allow pagination continuing after the cursor for the item.
- Parameters
item (obj) – An instance
ApiView.model
view (
ModelView
) – The view we wish to paginate.field_orderings (seq) – A sequence of (field, asc?).
- Returns
A sequence of
marshmallow.Field
.- Return type
seq
- make_cursors(items, view, field_orderings)¶
Build a cursor for each of many items.
This method creates a cursor for each item in
items
. It produces the same cursors asmake_cursor()
, but is slightly more efficient in cases where cursors for multiple items are required.- Parameters
items (seq) – A sequence of instances of
ApiView.model
view (
ModelView
) – The view we wish to paginate.field_orderings (seq) – A sequence of (field, asc?).
- Returns
A sequence of
marshmallow.Field
.- Return type
seq
Sorting¶
- class flask_resty.FieldSortingBase[source]¶
The base class for sorting components that sort on model fields.
These sorting components work on JSON-API style sort field strings, which consist of a list of comma-separated field names, optionally prepended by
-
to indicate descending sort order.For example, the sort field string of
name,-date
will sort byname
ascending anddate
descending.Subclasses must implement
get_request_field_orderings()
to specify the actual field orderings to use.- sort_query(query, view)[source]¶
Sort the provided
query
.- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to sort.view (
ModelView
) – The view with the model we wish to sort.
- Returns
The sorted query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- get_request_field_orderings(view) Tuple[Tuple[str, bool], ...] [source]¶
Get the field orderings to use for the current request.
These should be created from a sort field string with
get_field_orderings
below.- Parameters
view (
ModelView
) – The view with the model containing the target fields- Returns
A sequence of field orderings. See
get_criterion()
.- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- get_field_orderings(fields)[source]¶
Given a sort field string, build the field orderings.
These field orders can then be used with
get_request_field_orderings
above. See the class documentation for details on sort field strings.
- class flask_resty.FixedSorting(fields)[source]¶
A sorting component that applies a fixed sort order.
For example, to sort queries by
name
ascending anddate
descending, specify the following in your view:sorting = FixedSorting('name,-date')
- Parameters
fields (str) – The formatted fields.
- get_request_field_orderings(view)[source]¶
Get the field orderings to use for the current request.
These should be created from a sort field string with
get_field_orderings
below.- Parameters
view (
ModelView
) – The view with the model containing the target fields- Returns
A sequence of field orderings. See
get_criterion()
.- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- get_field_orderings(fields)¶
Given a sort field string, build the field orderings.
These field orders can then be used with
get_request_field_orderings
above. See the class documentation for details on sort field strings.
- sort_query(query, view)¶
Sort the provided
query
.- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to sort.view (
ModelView
) – The view with the model we wish to sort.
- Returns
The sorted query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- class flask_resty.Sorting(*field_names, default=None, **kwargs)[source]¶
A sorting component that allows the user to specify sort fields.
For example, to allow users to sort by
title
and/orcontent_length
, specify the following in your view:sorting = Sorting( 'title', content_length=sql.func.length(Post.content) )
One or both of
title
orcontent_length
can be formatted in thesort_arg
request parameter to determine the sort order. For example, users can sort requests byname
ascending anddate
descending by making aGET
request to:/api/comments/?sort=title,-content_length
- Parameters
field_names (str) – The fields available for sorting. Names should match a column on your View’s
model
.default (str) – If provided, specifies a default sort order when the request does not specify an explicit sort order.
kwargs (dict) – Provide custom sort behavior by mapping a sort argument name to a model order_by expression.
- sort_arg = 'sort'¶
The request parameter from which the formatted sorting fields will be retrieved.
- get_request_field_orderings(view)[source]¶
Get the field orderings to use for the current request.
These should be created from a sort field string with
get_field_orderings
below.- Parameters
view (
ModelView
) – The view with the model containing the target fields- Returns
A sequence of field orderings. See
get_criterion()
.- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- get_field_orderings(fields)¶
Given a sort field string, build the field orderings.
These field orders can then be used with
get_request_field_orderings
above. See the class documentation for details on sort field strings.
- sort_query(query, view)¶
Sort the provided
query
.- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to sort.view (
ModelView
) – The view with the model we wish to sort.
- Returns
The sorted query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
- class flask_resty.SortingBase[source]¶
The base class for sorting components.
Sorting components control how list queries are sorted.
They also expose an API for cursor pagination components to get the sort fields, which are required to build cursors.
Subclasses must implement
sort_query()
to provide the sorting logic.- sort_query(query, view)[source]¶
Sort the provided
query
.- Parameters
query (
sqlalchemy.orm.query.Query
) – The query to sort.view (
ModelView
) – The view with the model we wish to sort.
- Returns
The sorted query
- Return type
- Raises
A
NotImplementedError
if no implementation is provided.
Exceptions¶
- class flask_resty.ApiError(status_code, *errors)[source]¶
An API exception.
When raised, Flask-RESTy will send an HTTP response with the provided
status_code
and the providederrors
under theerrors
property as JSON.If
flask.Flask.debug
orflask.Flask.testing
is True, the body will also contain the full traceback under thedebug
property.- Parameters
- update(additional)[source]¶
Add additional metadata to the error.
Can be chained with further updates.
- with_traceback()¶
Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.
Routing¶
- class flask_resty.StrictRule(string: str, defaults: Optional[Mapping[str, Any]] = None, subdomain: Optional[str] = None, methods: Optional[Iterable[str]] = None, build_only: bool = False, endpoint: Optional[str] = None, strict_slashes: Optional[bool] = None, merge_slashes: Optional[bool] = None, redirect_to: Optional[Union[str, Callable[[...], str]]] = None, alias: bool = False, host: Optional[str] = None, websocket: bool = False)[source]¶
A Werkzeug rule that does not append missing slashes to paths.
- match(path, method=None)[source]¶
Check if the rule matches a given path. Path is a string in the form
"subdomain|/path"
and is assembled by the map. If the map is doing host matching the subdomain part will be the host instead.If the rule matches a dict with the converted values is returned, otherwise the return value is
None
.- Internal
- bind(map: werkzeug.routing.Map, rebind: bool = False) None ¶
Bind the url to a map and create a regular expression based on the information from the rule itself and the defaults from the map.
- Internal
- build(values: Mapping[str, Any], append_unknown: bool = True) Optional[Tuple[str, str]] ¶
Assembles the relative url for that rule and the subdomain. If building doesn’t work for some reasons
None
is returned.- Internal
- empty() werkzeug.routing.Rule ¶
Return an unbound copy of this rule.
This can be useful if want to reuse an already bound URL for another map. See
get_empty_kwargs
to override what keyword arguments are provided to the new copy.
- get_converter(variable_name: str, converter_name: str, args: Tuple, kwargs: Mapping[str, Any]) werkzeug.routing.BaseConverter ¶
Looks up the converter for the given parameter.
New in version 0.9.
- get_empty_kwargs() Mapping[str, Any] ¶
Provides kwargs for instantiating empty copy with empty()
Use this method to provide custom keyword arguments to the subclass of
Rule
when callingsome_rule.empty()
. Helpful when the subclass has custom keyword arguments that are needed at instantiation.Must return a
dict
that will be provided as kwargs to the new instance ofRule
, following the initialself.rule
value which is always provided as the first, required positional argument.
- get_rules(map: werkzeug.routing.Map) Iterator[werkzeug.routing.Rule] ¶
Subclasses of
RuleFactory
have to override this method and return an iterable of rules.
- match_compare_key() Tuple[bool, int, Iterable[Tuple[int, int]], int, Iterable[int]] ¶
The match compare key for sorting.
Current implementation:
rules without any arguments come first for performance reasons only as we expect them to match faster and some common ones usually don’t have any arguments (index pages etc.)
rules with more static parts come first so the second argument is the negative length of the number of the static weights.
we order by static weights, which is a combination of index and length
The more complex rules come first so the next argument is the negative length of the number of argument weights.
lastly we order by the actual argument weights.
- Internal
- provides_defaults_for(rule: werkzeug.routing.Rule) bool ¶
Check if this rule has defaults for a given rule.
- Internal
Fields¶
- class flask_resty.RelatedItem(nested: SchemaABC | type | str | dict[str, Field | type] | typing.Callable[[], SchemaABC | dict[str, Field | type]], *, dump_default: typing.Any = <marshmallow.missing>, default: typing.Any = <marshmallow.missing>, only: types.StrSequenceOrSet | None = None, exclude: types.StrSequenceOrSet = (), many: bool = False, unknown: str | None = None, **kwargs)[source]¶
A nested object field that only requires the ID on load.
This class is a wrapper around
marshmallow.fields.Nested
that provides simplified semantics in the context of a normalized REST API.When dumping, this field will dump the nested object as normal. When loading, this field will do a partial load to retrieve just the ID. This is because, when interacting with a resource that has a relationship to existing instances of another resource, the ID is sufficient to uniquely identify instances of the other resource.
- class flask_resty.DelimitedList(cls_or_instance, delimiter=None, as_string=False, **kwargs)[source]¶
List represented as a comma-delimited string, for use with args_schema.
Same as
marshmallow.fields.List
, except can load from either a list or a delimited string (e.g. “foo,bar,baz”). Directly taken from webargs: https://github.com/marshmallow-code/webargs/blob/de061e037285fd08a42d73be95bc779f2a4e3c47/src/webargs/fields.py#L47
Testing¶
- class flask_resty.testing.ApiClient(*args: Any, **kwargs: Any)[source]¶
A
flask.testing.FlaskClient
with a few conveniences:Prefixes paths
Sets
Content-Type
to “application/json”Envelopes
data
within a “data” key in the request payload
- flask_resty.testing.assert_shape(actual, expected, key=None)[source]¶
Assert that
actual
andexpected
have the same data shape.
- flask_resty.testing.assert_response(response, expected_status_code, expected_data=<UNDEFINED>, *, get_data=<function get_data>, get_errors=<function get_errors>)[source]¶
Assert on the status and contents of a response.
If specified, expected_data is checked against either the data or the errors in the response body, depending on the response status. This check ignores extra dictionary items in the response contents.