paperap.resources.base module

Provide base resource classes for interacting with Paperless-NgX API endpoints.

This module contains the foundation classes for all API resources in Paperap. Resources handle communication with the Paperless-NgX API, including request formatting, response parsing, and model instantiation.

Each resource corresponds to an API endpoint in Paperless-NgX and provides methods for retrieving, creating, updating, and deleting resources.

class paperap.resources.base.BaseResource(client)[source]

Bases: ABC, Generic[_BaseModel, _BaseQuerySet]

Base class for API resources.

Provides the foundation for all API resources in Paperap. Handles communication with the Paperless-NgX API, including request formatting, response parsing, and model instantiation.

Each resource corresponds to an API endpoint in Paperless-NgX and provides methods for retrieving, creating, updating, and deleting resources.

Parameters:

client (PaperlessClient) – PaperlessClient instance for making API requests.

model_class

Model class for this resource.

queryset_class

QuerySet class for this resource.

client

PaperlessClient instance.

name

Name of the resource (defaults to model name + ‘s’).

endpoints

Dictionary of API endpoint templates.

Examples

>>> from paperap import PaperlessClient
>>> client = PaperlessClient()
>>> resource = DocumentResource(client)
>>> documents = resource.all()
>>> for doc in documents[:5]:  # Get first 5 documents
...     print(doc.title)
model_class: type[_BaseModel]
queryset_class: type[_BaseQuerySet]
endpoints: ClassVar[Endpoints]
__init__(client)[source]

Initialize the resource with a client instance.

Sets up the resource with the client, configures endpoints, and establishes the relationship between the resource and its model class.

Parameters:

client (PaperlessClient) – PaperlessClient instance for making API requests.

client: PaperlessClient
name: str
classmethod __init_subclass__(**kwargs)[source]

Initialize the subclass with required attributes.

Validates that subclasses define required attributes like model_class and sets up default endpoints if not explicitly defined.

Parameters:

**kwargs (Any) – Arbitrary keyword arguments passed to parent __init_subclass__.

Raises:

ConfigurationError – If model_class is not defined in the subclass.

Return type:

None

get_endpoint(name, **kwargs)[source]

Get a fully-formed URL for the specified endpoint.

Retrieves the endpoint template, substitutes any parameters, and ensures the URL is properly formatted with the base URL if needed.

Parameters:
  • name (str) – Name of the endpoint (e.g., “list”, “detail”).

  • **kwargs (Any) – Parameters to substitute in the endpoint template.

Return type:

str | HttpUrl

Returns:

Fully-formed URL for the endpoint.

Raises:

ConfigurationError – If the requested endpoint is not defined.

Examples

>>> resource.get_endpoint("detail", pk=123)
'https://paperless.example.com/api/documents/123/'
all()[source]

Return a QuerySet representing all objects of this resource type.

Creates a new QuerySet instance for this resource without any filters.

Return type:

TypeVar(_BaseQuerySet, bound= BaseQuerySet[Any])

Returns:

QuerySet for this resource.

Examples

>>> all_documents = client.documents.all()
>>> for doc in all_documents:
...     print(doc.title)
filter(**kwargs)[source]

Return a QuerySet filtered by the given parameters.

Creates a new QuerySet with filters applied. Filters use Django-style field lookups (e.g., field__contains, field__gt).

Parameters:

**kwargs (Any) – Filter parameters as field=value pairs.

Return type:

TypeVar(_BaseQuerySet, bound= BaseQuerySet[Any])

Returns:

Filtered QuerySet.

Examples

>>> invoices = client.documents.filter(
...     title__contains="invoice",
...     created__gt="2023-01-01"
... )
get(*args, **kwargs)[source]

Get a model by ID.

This is a base method that raises NotImplementedError. Subclasses should implement this method to retrieve a specific model by ID.

Parameters:
  • *args (Any) – Positional arguments (typically model_id).

  • **kwargs (Any) – Additional keyword arguments.

Return type:

TypeVar(_BaseModel, bound= BaseModel)

Returns:

Retrieved model.

Raises:

NotImplementedError – This base method is not implemented.

create(**kwargs)[source]

Create a new resource.

Sends a POST request to the API to create a new resource with the provided data. Emits signals before and after the creation.

Parameters:

**kwargs (Any) – Resource data as field=value pairs.

Return type:

TypeVar(_BaseModel, bound= BaseModel)

Returns:

Newly created model instance.

Raises:

Examples

>>> tag = client.tags.create(
...     name="Invoices",
...     color="#ff0000"
... )
update(model)[source]

Update a resource.

This is a base method that raises NotImplementedError. Subclasses should implement this method to update a model.

Parameters:

model (TypeVar(_BaseModel, bound= BaseModel)) – Model instance to update.

Return type:

TypeVar(_BaseModel, bound= BaseModel)

Returns:

Updated model instance.

Raises:

NotImplementedError – This base method is not implemented.

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

Update a resource using a dictionary of values.

This is a base method that raises NotImplementedError. Subclasses should implement this method to update a model using a dictionary.

Parameters:
  • *args (Any) – Positional arguments (typically model_id).

  • **kwargs (Any) – Field values to update.

Return type:

TypeVar(_BaseModel, bound= BaseModel)

Returns:

Updated model instance.

Raises:

NotImplementedError – This base method is not implemented.

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

Delete a resource.

This is a base method that raises NotImplementedError. Subclasses should implement this method to delete a model.

Parameters:
  • *args (Any) – Positional arguments (typically model_id).

  • **kwargs (Any) – Additional keyword arguments.

Raises:

NotImplementedError – This base method is not implemented.

Return type:

None

parse_to_model(item)[source]

Parse an item dictionary into a model instance.

Transforms the raw API data and validates it against the model class.

Parameters:

item (dict[str, Any]) – Dictionary of data from the API.

Return type:

TypeVar(_BaseModel, bound= BaseModel)

Returns:

Validated model instance.

Raises:

ResponseParsingError – If the data cannot be parsed into a valid model.

transform_data_input(**data)[source]

Transform data after receiving it from the API.

Maps API field names to model field names using the field_map defined in the model’s Meta class.

Parameters:

**data (Any) – Raw data from the API.

Return type:

dict[str, Any]

Returns:

Transformed data ready for model validation.

transform_data_output(model=None, exclude_unset=True, **data)[source]

Transform data before sending it to the API.

Maps model field names to API field names using the field_map defined in the model’s Meta class.

Parameters:
  • model (Optional[TypeVar(_BaseModel, bound= BaseModel)]) – Model instance to transform. If provided, its to_dict() method is used.

  • exclude_unset (bool) – If model is provided, whether to exclude unset fields.

  • **data (Any) – Raw data to transform if no model is provided.

Return type:

dict[str, Any]

Returns:

Transformed data ready to send to the API.

Raises:

ValueError – If both model and data are provided.

create_model(**kwargs)[source]

Create a new model instance without saving to the API.

Instantiates a new model with the provided field values and associates it with this resource.

Parameters:

**kwargs (Any) – Model field values.

Return type:

TypeVar(_BaseModel, bound= BaseModel)

Returns:

New, unsaved model instance.

Examples

>>> doc = client.documents.create_model(
...     title="New Document",
...     correspondent_id=5
... )
>>> doc.save()  # Save to the API
request_raw(url=None, method='GET', params=None, data=None)[source]

Make an HTTP request to the API and return the raw JSON response.

A low-level method to send requests to the API without processing the response into model instances.

Parameters:
  • url (str | Template | HttpUrl | None) – URL to request. If None, uses the list endpoint.

  • method (str) – HTTP method to use (GET, POST, PUT, DELETE).

  • params (dict[str, Any] | None) – Query parameters to include in the request.

  • data (dict[str, Any] | None) – Request body data for POST/PUT requests.

Return type:

dict[str, Any] | list[dict[str, Any]] | None

Returns:

JSON-decoded response from the API.

Raises:

ConfigurationError – If no URL is provided and the list endpoint is not defined.

Examples

>>> # Get raw data from a custom endpoint
>>> response = resource.request_raw(
...     url="https://paperless.example.com/api/custom/",
...     params={"filter": "value"}
... )
handle_response(response)[source]

Process API response and yield model instances.

Handles different response formats (list or dict) and emits signals before and after processing.

Parameters:

response (Any) – API response to process.

Yields:

Model instances created from the response data.

Raises:

ResponseParsingError – If the response format is unexpected.

Return type:

Iterator[TypeVar(_BaseModel, bound= BaseModel)]

handle_dict_response(**response)[source]

Handle a dictionary response from the API and yield model instances.

Processes responses that are dictionaries, which may contain a ‘results’ key with a list of items or may be a single item directly.

Parameters:

**response (dict[str, Any]) – Dictionary response from the API.

Yields:

Model instances created from the response data.

Raises:

ResponseParsingError – If the response format is unexpected.

Return type:

Iterator[TypeVar(_BaseModel, bound= BaseModel)]

handle_results(results)[source]

Yield parsed models from a list of results.

Processes a list of dictionaries into model instances, emitting signals for each item.

Parameters:

results (list[dict[str, Any]]) – List of dictionaries from the API.

Yields:

Model instances created from the results.

Raises:

ResponseParsingError – If the results format is unexpected.

Return type:

Iterator[TypeVar(_BaseModel, bound= BaseModel)]

__call__(*args, **keywords)[source]

Make the resource callable to get a filtered QuerySet.

This allows for a shorthand syntax when filtering resources.

Parameters:
  • *args (Any) – Unused positional arguments.

  • **keywords (Any) – Filter parameters as field=value pairs.

Return type:

TypeVar(_BaseQuerySet, bound= BaseQuerySet[Any])

Returns:

Filtered QuerySet.

Examples

>>> # These are equivalent:
>>> client.documents(title__contains='invoice')
>>> client.documents.filter(title__contains='invoice')
class paperap.resources.base.StandardResource(client)[source]

Bases: BaseResource[_StandardModel, _StandardQuerySet]

Base class for API resources with standard ID-based operations.

Extends BaseResource with implementations for get, update, and delete operations that work with models having an ‘id’ field.

This class is used for most Paperless-NgX resources that follow the standard REST pattern with unique integer IDs.

Parameters:

client (PaperlessClient) – PaperlessClient instance for making API requests.

Examples

>>> from paperap import PaperlessClient
>>> client = PaperlessClient()
>>> resource = TagResource(client)
>>> tag = resource.get(5)  # Get tag with ID 5
>>> tag.name = "New Name"
>>> resource.update(tag)   # Update the tag
get(model_id, *args, **kwargs)[source]

Get a model within this resource by ID.

Retrieves a specific model by its ID, emitting signals before and after the operation.

Parameters:
  • model_id (int) – ID of the model to retrieve.

  • *args (Any) – Additional positional arguments.

  • **kwargs (Any) – Additional keyword arguments.

Return type:

TypeVar(_StandardModel, bound= StandardModel)

Returns:

Retrieved model instance.

Raises:

Examples

>>> document = client.documents.get(123)
>>> print(document.title)
update(model)[source]

Update a model in the API.

Converts the model to a dictionary and sends it to the API for updating.

Parameters:

model (TypeVar(_StandardModel, bound= StandardModel)) – Model instance to update.

Return type:

TypeVar(_StandardModel, bound= StandardModel)

Returns:

Updated model instance.

Examples

>>> tag = client.tags.get(5)
>>> tag.name = "Updated Name"
>>> updated_tag = client.tags.update(tag)
delete(model_id)[source]

Delete a resource from the API.

Sends a DELETE request to remove the resource, emitting signals before and after the operation.

Parameters:

model_id (Union[int, TypeVar(_StandardModel, bound= StandardModel)]) – ID of the resource or the model instance to delete.

Raises:
Return type:

None

Examples

>>> # Delete by ID
>>> client.tags.delete(5)
>>>
>>> # Delete by model instance
>>> tag = client.tags.get(5)
>>> client.tags.delete(tag)
update_dict(model_id, **data)[source]

Update a resource using a dictionary of values.

Sends a PUT request to update the resource with the provided data, emitting signals before and after the operation.

Parameters:
  • model_id (int) – ID of the resource to update.

  • **data (dict[str, Any]) – Field values to update.

Return type:

TypeVar(_StandardModel, bound= StandardModel)

Returns:

Updated model instance.

Raises:

Examples

>>> updated_tag = client.tags.update_dict(
...     5,
...     name="New Name",
...     color="#ff0000"
... )
class paperap.resources.base.BulkEditing[source]

Bases: object

bulk_edit_objects(object_type, ids, operation, permissions=None, owner_id=None, merge=False)[source]

Bulk edit non-document objects in the API.

Performs operations on multiple objects of the same type in a single request. Currently supports permission setting and deletion operations.

Parameters:
  • object_type (str) – Type of objects to edit (‘tags’, ‘correspondents’, ‘document_types’, ‘storage_paths’).

  • ids (list[int]) – List of object IDs to edit.

  • operation (str) – Operation to perform (‘set_permissions’ or ‘delete’).

  • permissions (dict[str, Any] | None) – Permissions object for ‘set_permissions’ operation.

  • owner_id (int | None) – Owner ID to assign.

  • merge (bool) – Whether to merge permissions with existing ones (True) or replace them (False).

Return type:

dict[str, Any]

Returns:

API response dictionary.

Raises:

ValueError – If operation is not valid.

Examples

>>> # Delete multiple tags
>>> client.tags.bulk_edit_objects(
...     object_type="tags",
...     ids=[1, 2, 3],
...     operation="delete"
... )
>>>
>>> # Set permissions on multiple document types
>>> client.document_types.bulk_edit_objects(
...     object_type="document_types",
...     ids=[4, 5],
...     operation="set_permissions",
...     permissions={"view": {"users": [1]}, "change": {"groups": [2]}},
...     owner_id=1
... )
Parameters:

self (BaseResource)