starlette_jsonapi.resource module

class starlette_jsonapi.resource.BaseResource(request, request_context, *args, **kwargs)

Bases: starlette_jsonapi.resource._BaseResourceHandler

A basic json:api resource implementation, data layer agnostic.

Subclasses can achieve basic functionality by implementing:

Additionally:

  • requests for compound documents (Example: GET /api/v1/articles?include=author) can be supported by overriding include_relations() to pre-populate the related objects before serializing.

  • requests for related objects (Example: GET /api/v1/articles/123/author), can be supported by overriding the get_related() handler. Related objects should be serialized with serialize_related().

By default, requests for sparse fields will be handled by the BaseResource implementation, without any effort required.

Example subclass:

class ExampleResource(BaseResource):
    type_ = 'examples'
    allowed_methods = {'GET'}

    async def get(self, id: str, *args, **kwargs) -> Response:
        obj = Example.objects.get(id)
        serialized_obj = await self.serialize(obj)
        return await self.to_response(serialized_obj)

    async def get_many(self, *args, **kwargs) -> Response:
        objects = Example.objects.all()
        serialized_objects = await self.serialize(objects, many=True)
        return await self.to_response(serialized_objects)
Parameters
  • request (starlette.requests.Request) –

  • request_context (dict) –

Return type

None

type_: str = ''

The json:api type, used to compute the path for this resource such that BaseResource.register_routes(app=app, base_path='/api/') will register the following routes:

  • GET /api/<type_>/

  • POST /api/<type_>/

  • GET /api/<type_>/{id:str}

  • PATCH /api/<type_>/{id:str}

  • DELETE /api/<type_>/{id:str}

schema

alias of starlette_jsonapi.schema.JSONAPISchema

id_mask: str = 'str'

By default str, but other options are documented in Starlette: 'str', 'int', 'float', 'uuid', 'path'

pagination_class: Optional[Type[starlette_jsonapi.pagination.BasePagination]] = None

Pagination class, subclass of BasePagination

register_as: str = ''

Optional, by default this will equal type_ and will be used as the mount name. Impacts the result of url_path_for, so it can be used to support multiple resource versions.

from starlette.applications import Starlette

class ExamplesResource(BaseResource):
    type_ = 'examples'
    register_as = 'v2-examples'

app = Starlette()
ExamplesResource.register_routes(app=app, base_path='/api/v2')
assert app.url_path_for('v2-examples:get_many') == '/api/v2/examples/'
mount: starlette.routing.Mount

The underlying starlette.routing.Mount object used for registering routes.

register_resource = False

Switch for controlling meta class registration. Being able to refer to another resource via its name, rather than directly passing it, will prevent circular imports in projects. By default, subclasses are registered.

openapi_info = {'handlers': {'delete': {'description': 'Delete an item by its id. Details: https://jsonapi.org/format/#crud-deleting', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}, 'get': {'description': 'Retrieve an item by its id. Details: https://jsonapi.org/format/#fetching-resources', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}, 'get_many': {'description': 'Retrieve a list of items. Details: https://jsonapi.org/format/#fetching-resources', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}, 'get_related': {'description': 'Retrieve a related item. Details: https://jsonapi.org/format/#fetching-resources', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}, 'patch': {'description': 'Update an item by its id. Details: https://jsonapi.org/format/#crud-updating', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}, 'post': {'description': 'Create an item. Details: https://jsonapi.org/format/#crud-creating', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}}}
get(id, *args, **kwargs)

Subclasses should implement this to handle GET /<id> requests.

Parameters

id (Any) –

Return type

starlette.responses.Response

patch(id, *args, **kwargs)

Subclasses should implement this to handle PATCH /<id> requests.

Parameters

id (Any) –

Return type

starlette.responses.Response

delete(id, *args, **kwargs)

Subclasses should implement this to handle DELETE /<id> requests.

Parameters

id (Any) –

Return type

starlette.responses.Response

get_many(*args, **kwargs)

Subclasses should implement this to handle GET / requests.

Return type

starlette.responses.Response

post(*args, **kwargs)

Subclasses should implement this to handle POST / requests.

Return type

starlette.responses.Response

Subclasses should implement this to handle GET /<id>/<relationship>[/<related_id>]. By default returns a 405 error.

Parameters
  • id (Any) – the resource id

  • relationship (str) – name of the relationship

  • related_id (Any) – optional, an id can be specified to identify a specific related resource, in case of one-to-many relationships.

Return type

starlette.responses.Response

async include_relations(obj, relations)

Subclasses should implement this to support requests for compound documents. https://jsonapi.org/format/#document-compound-documents

By default returns a 400 error, according to the json:api specification.

Example request URL: GET /?include=relationship1,relationship1.child_relationship Example relations: ['relationship1', 'relationship1.child_relationship']

Parameters
  • obj (Any) – an object that was passed to serialize()

  • relations (List[str]) – list of relations described above

Return type

None

async deserialize_body(partial=None)

Deserializes the request body according to schema.

Parameters

partial – Can be set to True during PATCH requests, to ignore missing fields. For more advanced uses, like a specific iterable of missing fields, you should check the marshmallow documentation.

Raises

starlette_jsonapi.exceptions.JSONAPIException

Return type

dict

async validate_body(partial=None)

Validates the raw request body, raising JSONAPIException 400 errors if the body is not valid according to schema. Otherwise, the whole request body is loaded as a dict and returned.

Parameters

partial – Can be set to True during PATCH requests, to ignore missing fields. For more advanced uses, like a specific iterable of missing fields, you should check the marshmallow documentation.

Raises

starlette_jsonapi.exceptions.JSONAPIException

Return type

dict

async serialize(data, many=False, paginate=False, pagination_kwargs=None, *args, **kwargs)

Serializes data as a JSON:API payload and returns a dict which can be passed when calling to_response().

Extra parameters can be sent inside the pagination process via pagination_kwargs Additional args and kwargs are passed when initializing a new schema.

Parameters
  • data (Any) – an object, or a sequence of objects to be serialized

  • many (bool) – whether data should be serialized as a collection

  • paginate (bool) – whether to apply pagination to the given data

  • pagination_kwargs (Optional[dict]) – additional parameters which are passed to paginate_request().

Return type

dict

Serializes related data as a JSON:API payload and returns a dict which can be passed when calling to_response().

When serializing related resources, the related items are passed as data, instead of the parent objects.

Additional args and kwargs are passed when initializing a new schema.

Parameters
  • data (Any) – an object, or a sequence of objects to be serialized

  • many – whether data should be serialized as a collection

Return type

dict

async paginate_request(object_list, pagination_kwargs=None)

Applies pagination using the helper class defined by pagination_class. Additional parameters can pe saved on the paginator instance using pagination_kwargs.

Parameters
  • object_list (Sequence) –

  • pagination_kwargs (Optional[dict]) –

Return type

starlette_jsonapi.pagination.Pagination

classmethod register_routes(app, base_path='')

Registers URL routes associated to this resource, using a starlette.routing.Mount. The mount name will be set based on type_, or register_as, if defined. All routes will then be registered under this mount.

If the configured schema defines relationships, then routes for related objects will also be registered.

Let’s take the articles resource as an example:.

Registered Routes

Name

URL

HTTP method

Description

articles:get_many

/articles/

GET

Retrieve articles

articles:post

/articles/

POST

Create an article

articles:get

/articles/<id>

GET

Retrieve an article by ID

articles:patch

/articles/<id>

PATCH

Update an article by ID

articles:delete

/articles/<id>

DELETE

Delete an article by ID

articles:author

/articles/<id>/author

GET

Retrieve an article’s author

articles:comments

/articles/<id>/comments

GET

Retrieve an article’s comments

articles:comments-id

/articles/<id>/comments/<related_id>

GET

Retrieve an article comment by ID

Parameters
  • app (starlette.applications.Starlette) –

  • base_path (str) –

__init__(request, request_context, *args, **kwargs)

A Resource instance is created for each HTTP request, and the starlette.requests.Request is passed, as well as the context, which can be used to store information without altering the request object.

Parameters
  • request (starlette.requests.Request) –

  • request_context (dict) –

Return type

None

async classmethod after_request(request, request_context, response)

Optional hook that can be implemented by subclasses to execute logic after a request is handled. This will not run if an exception is raised before handle_request() is called, or if before_request() throws an error.

For more advanced hooks, check starlette middleware.

Parameters
  • request (starlette.requests.Request) – The current HTTP request

  • request_context (dict) – The current request’s context.

  • response (starlette.responses.Response) – The Starlette Response object

Return type

None

allowed_methods = {'DELETE', 'GET', 'PATCH', 'POST'}

High level filter for HTTP requests. If you specify a smaller subset, any request with a method not listed here will result in a 405 error.

async classmethod before_request(request, request_context)

Optional hook that can be implemented by subclasses to execute logic before a request is handled. This will not run if an exception is raised before handle_request() is called.

For more advanced hooks, check starlette middleware.

Parameters
  • request (starlette.requests.Request) – The current HTTP request

  • request_context (dict) – The current request’s context.

Return type

None

async classmethod handle_error(request, request_context, exc)

Handles errors that may appear while a request is processed, taking care of serializing them to ensure the final response is json:api compliant.

Subclasses can override this to add custom error handling.

Parameters
  • request (starlette.requests.Request) – current HTTP request

  • request_context (dict) – current request context

  • exc (Exception) – encountered error

Return type

starlette_jsonapi.responses.JSONAPIResponse

async classmethod handle_request(handler_name, request, request_context=None, extract_params=None, *args, **kwargs)

Handles a request by calling the appropriate handler. Additional args and kwargs are passed to the handler method, which is usually one of: get(), patch(), delete(), get_many() or post().

Parameters
  • handler_name (str) –

  • request (starlette.requests.Request) –

  • request_context (Optional[dict]) –

  • extract_params (Optional[List[str]]) –

Return type

starlette.responses.Response

process_sparse_fields_request(serialized_data, many=False)

Processes sparse fields requests by calling starlette_jsonapi.utils.process_sparse_fields().

Can be overridden in subclasses if custom behavior is needed.

Parameters
  • serialized_data (dict) – The complete json:api dict representation.

  • many (bool) – Whether serialized_data should be treated as a collection.

Return type

dict

async to_response(data, meta=None, *args, **kwargs)

Wraps data in a starlette_jsonapi.responses.JSONAPIResponse object and returns it. If meta is specified, it will be included as the top level "meta" object in the json:api response. Additional args and kwargs are passed when instantiating a new JSONAPIResponse.

Parameters
  • data (dict) – Serialized resources / errors, as returned by serialize() or serialize_related().

  • meta (Optional[dict]) – Optional dictionary with meta information. Overwrites any existing top level meta in data.

Return type

starlette_jsonapi.responses.JSONAPIResponse

request: starlette.requests.Request

Instance attribute representing the current HTTP request.

request_context: dict

Instance attribute representing the context of the current HTTP request. Can be used to store additional information for the duration of a request.

class starlette_jsonapi.resource.BaseRelationshipResource(request, request_context, *args, **kwargs)

Bases: starlette_jsonapi.resource._BaseResourceHandler

A basic json:api relationships resource implementation, data layer agnostic.

Parameters
  • request (starlette.requests.Request) –

  • request_context (dict) –

Return type

None

parent_resource: Type[starlette_jsonapi.resource.BaseResource]

The parent resource that this relationship belongs to

relationship_name: str

The relationship name, as found on the parent resource schema

openapi_info = {'handlers': {'delete': {'description': 'Delete a relationship. Details: https://jsonapi.org/format/#crud-updating-relationships', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}, 'get': {'description': 'Retrieve a (list of) relationship(s). Details: https://jsonapi.org/format/#fetching-relationships', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}, 'patch': {'description': 'Update a relationship. Details: https://jsonapi.org/format/#crud-updating-relationships', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}, 'post': {'description': 'Create a relationship. Details: https://jsonapi.org/format/#crud-updating-relationships', 'responses': {'500': <class 'starlette_jsonapi.exceptions.JSONAPIException'>}}}}
post(parent_id, *args, **kwargs)

Subclasses should implement this to handle POST /<parent_id>/relationships/<relationship> requests.

Parameters

parent_id (Any) –

Return type

starlette.responses.Response

get(parent_id, *args, **kwargs)

Subclasses should implement this to handle GET /<parent_id>/relationships/<relationship> requests.

Parameters

parent_id (Any) –

Return type

starlette.responses.Response

patch(parent_id, *args, **kwargs)

Subclasses should implement this to handle PATCH /<parent_id>/relationships/<relationship> requests.

Parameters

parent_id (Any) –

Return type

starlette.responses.Response

delete(parent_id, *args, **kwargs)

Subclasses should implement this to handle DELETE /<parent_id>/relationships/<relationship> requests.

Parameters

parent_id (Any) –

Return type

starlette.responses.Response

async serialize(data)

Serializes the parent instance relationships as a JSON:API payload, returning a dict which can be passed to BaseRelationshipResource.to_response.

Parameters

data (Any) –

Return type

dict

async deserialize_ids()

Parses the request body to find relationship ids. Raises JSONAPIException with a 400 status code if the payload does not pass json:api validation.

Return type

Union[None, str, List[str]]

__init__(request, request_context, *args, **kwargs)

A Resource instance is created for each HTTP request, and the starlette.requests.Request is passed, as well as the context, which can be used to store information without altering the request object.

Parameters
  • request (starlette.requests.Request) –

  • request_context (dict) –

Return type

None

async classmethod after_request(request, request_context, response)

Optional hook that can be implemented by subclasses to execute logic after a request is handled. This will not run if an exception is raised before handle_request() is called, or if before_request() throws an error.

For more advanced hooks, check starlette middleware.

Parameters
  • request (starlette.requests.Request) – The current HTTP request

  • request_context (dict) – The current request’s context.

  • response (starlette.responses.Response) – The Starlette Response object

Return type

None

allowed_methods = {'DELETE', 'GET', 'PATCH', 'POST'}

High level filter for HTTP requests. If you specify a smaller subset, any request with a method not listed here will result in a 405 error.

async classmethod before_request(request, request_context)

Optional hook that can be implemented by subclasses to execute logic before a request is handled. This will not run if an exception is raised before handle_request() is called.

For more advanced hooks, check starlette middleware.

Parameters
  • request (starlette.requests.Request) – The current HTTP request

  • request_context (dict) – The current request’s context.

Return type

None

async classmethod handle_error(request, request_context, exc)

Handles errors that may appear while a request is processed, taking care of serializing them to ensure the final response is json:api compliant.

Subclasses can override this to add custom error handling.

Parameters
  • request (starlette.requests.Request) – current HTTP request

  • request_context (dict) – current request context

  • exc (Exception) – encountered error

Return type

starlette_jsonapi.responses.JSONAPIResponse

async classmethod handle_request(handler_name, request, request_context=None, extract_params=None, *args, **kwargs)

Handles a request by calling the appropriate handler. Additional args and kwargs are passed to the handler method, which is usually one of: get(), patch(), delete(), get_many() or post().

Parameters
  • handler_name (str) –

  • request (starlette.requests.Request) –

  • request_context (Optional[dict]) –

  • extract_params (Optional[List[str]]) –

Return type

starlette.responses.Response

process_sparse_fields_request(serialized_data, many=False)

Processes sparse fields requests by calling starlette_jsonapi.utils.process_sparse_fields().

Can be overridden in subclasses if custom behavior is needed.

Parameters
  • serialized_data (dict) – The complete json:api dict representation.

  • many (bool) – Whether serialized_data should be treated as a collection.

Return type

dict

classmethod register_routes(*args, **kwargs)

Registers URL routes associated to this resource. Should be called after calling register_routes for the parent resource.

The following URL routes will be registered, relative to parent_resource:

  • Relative name: relationships-<relationship_name>

  • Relative URL: /<parent_id>/relationships/<relationship_name>

For example, a relationship resource that would handle article authors would be registered relative to the articles resource as:

  • Relative name: relationships-author

  • Full name: articles:relationships-author

  • Relative URL: /<parent_id>/relationships/author

  • Full URL: /articles/<parent_id>/relationships/author

async to_response(data, meta=None, *args, **kwargs)

Wraps data in a starlette_jsonapi.responses.JSONAPIResponse object and returns it. If meta is specified, it will be included as the top level "meta" object in the json:api response. Additional args and kwargs are passed when instantiating a new JSONAPIResponse.

Parameters
  • data (dict) – Serialized resources / errors, as returned by serialize() or serialize_related().

  • meta (Optional[dict]) – Optional dictionary with meta information. Overwrites any existing top level meta in data.

Return type

starlette_jsonapi.responses.JSONAPIResponse

request: starlette.requests.Request

Instance attribute representing the current HTTP request.

request_context: dict

Instance attribute representing the context of the current HTTP request. Can be used to store additional information for the duration of a request.