paperap.models package

class paperap.models.BaseModel(**data)[source]

Bases: BaseModel, ABC

Base model for all Paperless-ngx API objects.

Provide automatic serialization, deserialization, and API interactions with minimal configuration. This abstract class serves as the foundation for all models in the Paperap library, handling data validation, dirty tracking, and API communication.

_meta

Metadata for the model, including filtering and resource information.

_save_lock

Lock for saving operations to prevent race conditions.

_pending_save

Future object for pending save operations.

_save_executor

Executor for asynchronous save operations.

_status

Current status of the model (INITIALIZING, READY, UPDATING, SAVING).

_original_data

Original data from the server for dirty checking.

_saved_data

Data last sent to the database during save operations.

_resource

Associated resource for API interactions.

Raises:

ValueError – If resource is not provided during initialization.

Examples

Models are typically accessed through the client interface:

>>> document = client.documents.get(123)
>>> print(document.title)
>>> document.title = "New Title"
>>> document.save()
Parameters:

data (Any)

class Meta(model)[source]

Bases: Generic

Metadata for the Model.

Define model behavior, filtering capabilities, and API interaction rules. Each model class has its own Meta instance that controls how the model interacts with the Paperless-ngx API.

model

Reference to the model class this metadata belongs to.

name

The name of the model, used in API paths and error messages.

read_only_fields

Fields that should not be modified by the client.

filtering_disabled

Fields that cannot be used for filtering.

filtering_fields

Fields allowed for filtering operations.

supported_filtering_params

Specific filter parameters allowed during queryset filtering (e.g., “content__icontains”, “id__gt”).

blacklist_filtering_params

Filter parameters explicitly disallowed.

filtering_strategies

Strategies that determine how filtering is handled (ALLOW_ALL, ALLOW_NONE, WHITELIST, BLACKLIST).

field_map

Map of API field names to model attribute names.

save_on_write

If True, updating attributes triggers automatic save. If None, follows client.settings.save_on_write.

save_timeout

Timeout in seconds for save operations.

Raises:

ValueError – If both ALLOW_ALL and ALLOW_NONE filtering strategies are set, which would create contradictory behavior.

Examples

Defining a custom Meta for a model:

>>> class Document(StandardModel):
>>>     class Meta(StandardModel.Meta):
>>>         read_only_fields = {"content", "checksum"}
>>>         filtering_strategies = {FilteringStrategies.WHITELIST}
>>>         supported_filtering_params = {"title__icontains", "created__gt"}
Parameters:

model (type[_Self])

__init__(model)[source]
Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filter_allowed(filter_param)[source]

Check if a filter parameter is allowed based on the filtering strategies.

Evaluate whether a given filter parameter can be used with this model based on the configured filtering strategies and rules. This method implements the filtering logic defined by the model’s filtering_strategies.

Parameters:

filter_param (str) – The filter parameter to check (e.g., “title__contains”).

Returns:

True if the filter is allowed, False otherwise.

Return type:

bool

Examples

>>> meta.filter_allowed("title__contains")
True
>>> meta.filter_allowed("content__exact")
False  # If content is in filtering_disabled
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {}
filtering_strategies: ClassVar[set[FilteringStrategies]] = {FilteringStrategies.BLACKLIST}
read_only_fields: ClassVar[set[str]] = {}
save_on_write: bool | None = None
save_timeout: int = ModelPrivateAttr(default=60)
supported_filtering_params: ClassVar[set[str]] = {'limit'}
model: type[TypeVar(_Self, bound= BaseModel)]
name: str
__init__(**data)[source]

Initialize the model with resource and data.

Set up the model with the provided resource and initialize it with field values from the API response or user input.

Parameters:

**data (Any) – Field values to initialize the model with.

Raises:

ValueError – If resource is not provided or properly initialized.

Notes

Models should typically be created through their resource’s methods rather than directly instantiated.

classmethod __init_subclass__(**kwargs)[source]

Initialize subclass and set up metadata.

Ensure that each subclass has its own Meta definition and properly inherits metadata attributes from parent classes. This method handles the automatic creation and configuration of model metadata.

Parameters:

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

Raises:

ConfigurationError – If no Meta class is found in the class hierarchy.

Return type:

None

Notes

This method automatically: - Creates a Meta class for the subclass if not explicitly defined - Inherits and merges metadata from parent classes - Initializes the _meta instance for the subclass

__str__()[source]

Human-readable string representation.

Provide a string representation of the model that includes the model type and ID, typically used for logging and debugging purposes.

Returns:

A string representation of the model (e.g., “Document #123”).

Return type:

str

cleanup()[source]

Clean up resources used by the model.

Shut down the save executor to release resources. Call this method when the model is no longer needed to prevent resource leaks.

Return type:

None

classmethod create(**kwargs)[source]

Create a new model instance and save it to the server.

Create a new instance of the model with the specified field values and immediately save it to the Paperless NGX server. This is a convenience method that delegates to the resource’s create method.

Parameters:

**kwargs (Any) – Field values to set on the new model instance.

Returns:

A new model instance that has been saved to the server.

Return type:

Self

Examples

>>> tag = Tag.create(name="Invoices", color="#ff0000")
>>> correspondent = Correspondent.create(name="Electric Company")
>>> doc_type = DocumentType.create(name="Bill")
delete()[source]

Delete this model from the Paperless NGX server.

Remove the model from the server. After calling this method, the model instance should not be used anymore as it no longer represents a valid server object.

Raises:
Return type:

None

dirty_fields(comparison='both')[source]

Show which fields have changed since last update from the Paperless NGX database.

Compare the current model data with the last saved or retrieved data to identify changes. This method helps determine what will be sent to the server on the next save operation.

Parameters:

comparison (Literal['saved', 'db', 'both']) – Specify the data to compare against: - “saved”: Compare against the last data sent to Paperless NGX - “db”: Compare against the last data retrieved from Paperless NGX - “both”: Compare against both saved and db data (default)

Returns:

A dictionary mapping field names to tuples of

(original_value, current_value) for all fields that have changed.

Return type:

dict[str, tuple[Any, Any]]

Examples

>>> doc = client.documents.get(123)
>>> doc.title = "New Title"
>>> doc.dirty_fields()
{'title': ('Original Title', 'New Title')}
disable_save_on_write()[source]

Disable automatic saving on attribute write.

Set the model’s meta configuration to prevent automatic saving whenever an attribute is modified, overriding the client’s default setting. This affects only this specific model instance. :rtype: None

Examples

>>> doc = client.documents.get(123)
>>> doc.disable_save_on_write()
>>> doc.title = "New Title"  # This won't trigger an automatic save
>>> doc.save()  # Manual save required
enable_save_on_write()[source]

Enable automatic saving on attribute write.

Set the model’s meta configuration to allow automatic saving whenever an attribute is modified, overriding the client’s default setting. This affects only this specific model instance. :rtype: None

Examples

>>> doc = client.documents.get(123)
>>> doc.enable_save_on_write()
>>> doc.title = "New Title"  # This will trigger an automatic save
classmethod from_dict(data)[source]

Create a model instance from API response data.

Instantiate a model from a dictionary of API response data, handling field mapping and type conversion through the resource’s parse_to_model method.

Parameters:

data (dict[str, Any]) – Dictionary containing the API response data.

Returns:

A model instance initialized with the provided data.

Return type:

Self

Examples

>>> api_data = {"id": 123, "title": "Invoice", "created": "2023-01-01T00:00:00Z"}
>>> doc = Document.from_dict(api_data)
>>> print(doc.id, doc.title)
123 Invoice
is_dirty(comparison='both')[source]

Check if any field has changed since last update from the Paperless NGX database.

Determine if the model has unsaved changes by comparing current data with the last saved or retrieved data. New models are always considered dirty.

Parameters:

comparison (Literal['saved', 'db', 'both']) – Specify the data to compare against: - “saved”: Compare against the last data sent to Paperless NGX - “db”: Compare against the last data retrieved from Paperless NGX - “both”: Compare against both saved and db data (default)

Returns:

True if any field has changed, False otherwise.

Return type:

bool

Examples

>>> doc = client.documents.get(123)
>>> doc.is_dirty()
False
>>> doc.title = "New Title"
>>> doc.is_dirty()
True
abstractmethod is_new()[source]

Check if this model represents a new (unsaved) object.

Determine if the model has been saved to the server. Subclasses must implement this method, typically by checking if the model has a valid ID or other server-assigned identifier.

Returns:

True if the model is new (not yet saved), False otherwise.

Return type:

bool

Examples

>>> doc = Document.create(title="New Document")
>>> doc.is_new()  # Returns False after creation
>>>
>>> # When creating a model instance manually:
>>> doc = Document(title="Draft Document")
>>> doc.is_new()  # Returns True
matches_dict(data)[source]

Check if the model matches the provided data.

Compare the model’s current data with a given dictionary to determine if they are equivalent. This is useful for checking if a model needs to be updated based on new data from the server.

Parameters:

data (dict[str, Any]) – Dictionary containing the data to compare against.

Returns:

True if the model matches the data, False otherwise.

Return type:

bool

Examples

>>> doc = client.documents.get(123)
>>> new_data = {"id": 123, "title": "Invoice", "correspondent_id": 5}
>>> doc.matches_dict(new_data)
False  # If any values differ
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

property resource: BaseResource[Self]

Get the resource associated with this model.

Provide access to the resource instance that handles API interactions for this model type, such as retrieving, creating, updating, and deleting objects.

Returns:

The resource instance for this model type.

Return type:

BaseResource[Self]

property save_executor: ThreadPoolExecutor

Get the thread pool executor for asynchronous save operations.

Provide access to the thread pool that handles asynchronous save operations, creating a new executor if one doesn’t exist yet.

Returns:

The executor for handling

asynchronous save operations.

Return type:

concurrent.futures.ThreadPoolExecutor

should_save_on_write()[source]

Check if the model should save on attribute write.

Determine if changes to model attributes should trigger an automatic save operation based on configuration settings. This method considers both the model’s meta settings and the client settings, with the model’s setting taking precedence.

Returns:

True if the model should save on write, False otherwise.

Return type:

bool

to_dict(*, include_read_only=True, exclude_none=False, exclude_unset=True)[source]

Convert the model to a dictionary for API requests.

Prepare the model data for submission to the API, with options to control which fields are included based on their properties and values.

Parameters:
  • include_read_only (bool) – Whether to include read-only fields in the output. Set to False when preparing data for update operations.

  • exclude_none (bool) – Whether to exclude fields with None values.

  • exclude_unset (bool) – Whether to exclude fields that were not explicitly set. Useful for partial updates.

Returns:

A dictionary with model data ready for API submission.

Return type:

dict[str, Any]

Examples

>>> # Full representation including all fields
>>> data = doc.to_dict()
>>>
>>> # Only include fields that can be modified
>>> update_data = doc.to_dict(include_read_only=False)
>>>
>>> # Only include fields that have been explicitly set
>>> partial_data = doc.to_dict(exclude_unset=True)
update(**kwargs)[source]

Update this model with new values.

Update the model with the provided field values. In BaseModel, this simply calls update_locally without saving. Subclasses (like StandardModel) may implement automatic saving.

Parameters:

**kwargs (Any) – New field values to set on the model.

Return type:

None

Examples

>>> model.update(name="New Name", description="Updated description")
update_locally(*, from_db=None, skip_changed_fields=False, **kwargs)[source]

Update model attributes without triggering automatic save.

Update the model’s attributes with the provided values without sending changes to the server, regardless of the save_on_write setting. This is useful for local modifications or when applying server updates.

Parameters:
  • from_db (bool | None) – Whether the update is from the database. If True, resets the dirty tracking to consider the model clean after the update.

  • skip_changed_fields (bool) – Whether to skip updating fields that have unsaved changes. Useful when merging updates from the server with local changes.

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

Raises:

ReadOnlyFieldError – If attempting to change a read-only field when from_db is False.

Return type:

None

Examples

>>> doc = client.documents.get(123)
>>> # Update without saving to server
>>> doc.update_locally(title="New Title", correspondent_id=5)
>>> # Update from server data
>>> doc.update_locally(from_db=True, **server_data)
class paperap.models.StandardModel(**data)[source]

Bases: BaseModel, ABC

Standard model for Paperless-ngx API objects with an ID field.

Extend BaseModel to include a unique identifier and additional functionality for API objects that require an ID. Most Paperless-ngx resources are represented by StandardModel subclasses.

This class adds functionality for: - Tracking whether an object is new or existing - Automatic saving of changes to the server - Refreshing data from the server - Synchronous and asynchronous save operations

id

Unique identifier for the model from Paperless-ngx.

_resource

Associated resource for API interactions.

Examples

StandardModel subclasses are typically accessed through the client:

>>> doc = client.documents.get(123)
>>> tag = client.tags.create(name="Important")
>>> correspondent = client.correspondents.all()[0]
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the StandardModel.

Define metadata specific to StandardModel, including read-only fields and filtering parameters common to all standard Paperless-ngx resources.

read_only_fields

Fields that should not be modified, including the ‘id’ field which is set by the server.

supported_filtering_params

Common filtering parameters supported for all standard models, including id-based lookups.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'id'}
read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
__setattr__(name, value)[source]

Override attribute setting to automatically trigger save.

Intercept attribute assignments and trigger an automatic save operation if appropriate based on the save_on_write setting. This enables the “save on write” functionality that makes the model automatically sync changes to the server.

Parameters:
  • name (str) – Attribute name to set

  • value (Any) – New attribute value

Return type:

None

Notes

  • Private attributes (starting with ‘_’) never trigger autosave

  • Autosave only happens when model status is READY

  • Autosave is skipped for new models or when save_on_write is False

__str__()[source]

Human-readable string representation.

This method returns a string representation of the model, typically used for logging and debugging purposes.

Returns:

A string representation of the model.

Return type:

str

is_new()[source]

Check if this model represents a new (unsaved) object.

Determine if the model has been saved to the server by checking if it has a valid ID (non-zero). StandardModel implements this method by checking the id attribute.

Returns:

True if the model is new (not yet saved), False otherwise.

Return type:

bool

Examples

>>> doc = Document(title="Draft")  # No ID yet
>>> doc.is_new()
True
>>> saved_doc = client.documents.get(123)
>>> saved_doc.is_new()
False
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

refresh()[source]

Refresh the model with the latest data from the server.

Retrieve the latest data for the model from the server and update the model instance with any changes. This is useful when you suspect the server data may have changed due to actions by other users or automated processes.

Returns:

True if the model data changed, False if the data is identical

or the refresh failed.

Return type:

bool

Raises:

ResourceNotFoundError – If the model is not found on the server (e.g., it was deleted remotely).

Examples

>>> doc = client.documents.get(123)
>>> # After some time or operations by other users
>>> doc.refresh()  # Update with latest data from server
property resource: StandardResource[Self]

Get the resource associated with this model.

Provide access to the StandardResource instance that handles API interactions for this model type, with support for ID-based operations.

Returns:

The resource instance for this model type.

Return type:

StandardResource[Self]

save(*, force=False)[source]

Save this model to the Paperless NGX server.

Send the current model state to the server, creating a new object or updating an existing one. This is a convenience method that calls save_sync.

Parameters:

force (bool) – Whether to force the save operation even if the model is not dirty or is already saving.

Returns:

True if the save was successful, False otherwise.

Return type:

bool

Examples

>>> doc = client.documents.get(123)
>>> doc.title = "New Title"
>>> doc.save()
>>>
>>> # Force save even if no changes
>>> doc.save(force=True)
save_async(*, force=False)[source]

Save this model instance asynchronously.

Send changes to the server in a background thread, allowing other operations to continue while waiting for the server response. The model will be updated with the server’s response when the save completes.

Parameters:

force (bool) – Whether to force the save operation even if the model is not dirty or is already saving.

Returns:

True if the save was successfully submitted to the background

thread, False otherwise (e.g., if there are no changes to save).

Return type:

bool

Examples

>>> doc = client.documents.get(123)
>>> doc.title = "New Title"
>>> # Continue execution immediately while save happens in background
>>> doc.save_async()
>>> # Do other work...
save_sync(*, force=False)[source]

Save this model instance synchronously.

Send changes to the server immediately and update the model when the server responds. This method blocks until the save operation is complete.

Parameters:

force (bool) – Whether to force the save operation even if the model is not dirty or is already saving.

Returns:

True if the save was successful, False otherwise.

Return type:

bool

Raises:

Examples

>>> doc = client.documents.get(123)
>>> doc.title = "New Title"
>>> success = doc.save_sync()
>>> print(f"Save {'succeeded' if success else 'failed'}")
update(**kwargs)[source]

Update this model with new values and save changes.

Update the model with the provided field values and automatically save the changes to the server if the model is not new. This method combines update_locally and save for convenience.

Parameters:

**kwargs (Any) – New field values to set on the model.

Return type:

None

Note

New (unsaved) instances will be updated locally but not saved automatically. Use create() to save new instances.

Examples

>>> doc = client.documents.get(123)
>>> doc.update(title="New Title", correspondent_id=5)
>>> # Changes are immediately saved to the server
id: int
class paperap.models.DocumentNote(**data)[source]

Bases: StandardModel

Represent a note on a Paperless-ngx document.

This class models user-created notes that can be attached to documents in the Paperless-ngx system. Notes include information about when they were created, who created them, and their content.

deleted_at

Timestamp when the note was deleted, or None if not deleted.

Type:

datetime | None

restored_at

Timestamp when the note was restored after deletion, or None.

Type:

datetime | None

transaction_id

ID of the transaction that created or modified this note.

Type:

int | None

note

The text content of the note.

Type:

str

created

Timestamp when the note was created.

Type:

datetime

document

ID of the document this note is attached to.

Type:

int

user

ID of the user who created this note.

Type:

int

Examples

>>> note = client.document_notes().get(1)
>>> print(note.note)
'This is an important document'
>>> print(note.created)
2023-01-15 14:30:22
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'created', 'deleted_at', 'document', 'id', 'note', 'restored_at', 'transaction_id', 'user'}
read_only_fields: ClassVar[set[str]] = {'created', 'deleted_at', 'id', 'restored_at', 'transaction_id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
get_document()[source]

Get the document associated with this note.

Retrieves the full Document object that this note is attached to by making an API request using the document ID.

Returns:

The document associated with this note.

Return type:

Document

Example

>>> note = client.document_notes().get(1)
>>> document = note.get_document()
>>> print(document.title)
'Invoice #12345'
get_user()[source]

Get the user who created this note.

Retrieves the full User object for the user who created this note by making an API request using the user ID.

Returns:

The user who created this note.

Return type:

User

Example

>>> note = client.document_notes().get(1)
>>> user = note.get_user()
>>> print(user.username)
'admin'
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

serialize_datetime(value)[source]

Serialize datetime fields to ISO format.

Converts datetime objects to ISO 8601 formatted strings for JSON serialization. Returns None if the input value is None.

Parameters:

value (datetime | None) – The datetime value to serialize.

Returns:

The serialized datetime value as an ISO 8601 string, or None if the value is None.

Return type:

str | None

deleted_at: datetime | None
restored_at: datetime | None
transaction_id: int | None
note: str
created: datetime
document: int
user: int
class paperap.models.Document(**data)[source]

Bases: StandardModel

Represent a Paperless-ngx document.

This class models documents stored in the Paperless-ngx system, providing access to document metadata, content, and related objects. It supports operations like downloading, updating metadata, and managing tags and custom fields.

added

Timestamp when the document was added to the system.

Type:

datetime | None

archive_checksum

Checksum of the archived version of the document.

Type:

str | None

archive_filename

Filename of the archived version.

Type:

str | None

archive_serial_number

Serial number in the archive system.

Type:

int | None

archived_file_name

Original name of the archived file.

Type:

str | None

checksum

Checksum of the original document.

Type:

str | None

content

Full text content of the document.

Type:

str

correspondent_id

ID of the associated correspondent.

Type:

int | None

created

Timestamp when the document was created.

Type:

datetime | None

created_date

Creation date as a string.

Type:

str | None

custom_field_dicts

Custom fields associated with the document.

Type:

list[CustomFieldValues]

deleted_at

Timestamp when the document was deleted, or None.

Type:

datetime | None

document_type_id

ID of the document type.

Type:

int | None

filename

Current filename in the system.

Type:

str | None

is_shared_by_requester

Whether the document is shared by the requester.

Type:

bool

notes

Notes attached to this document.

Type:

list[DocumentNote]

original_filename

Original filename when uploaded.

Type:

str | None

owner

ID of the document owner.

Type:

int | None

page_count

Number of pages in the document.

Type:

int | None

storage_path_id

ID of the storage path.

Type:

int | None

storage_type

Type of storage used.

Type:

DocumentStorageType | None

tag_ids

List of tag IDs associated with this document.

Type:

list[int]

title

Title of the document.

Type:

str

user_can_change

Whether the current user can modify this document.

Type:

bool | None

Examples

>>> document = client.documents().get(pk=1)
>>> document.title = 'Example Document'
>>> document.save()
>>> document.title
'Example Document'

# Get document metadata >>> metadata = document.get_metadata() >>> print(metadata.original_mime_type) ‘application/pdf’

# Download document >>> download = document.download() >>> with open(download.disposition_filename, ‘wb’) as f: … f.write(download.content)

# Get document suggestions >>> suggestions = document.get_suggestions() >>> print(suggestions.tags) [‘Invoice’, ‘Tax’, ‘2023’]

Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {'correspondent': 'correspondent_id', 'custom_fields': 'custom_field_dicts', 'document_type': 'document_type_id', 'storage_path': 'storage_path_id', 'tags': 'tag_ids'}
filtering_disabled: ClassVar[set[str]] = {'deleted_at', 'is_shared_by_requester', 'page_count'}
filtering_fields: ClassVar[set[str]] = {'__search_hit__', '_correspondent', '_document_type', '_resource', '_storage_path', 'added', 'archive_checksum', 'archive_filename', 'archive_serial_number', 'archived_file_name', 'checksum', 'content', 'correspondent_id', 'created', 'created_date', 'custom_field_dicts', 'document_type_id', 'filename', 'id', 'notes', 'original_filename', 'owner', 'storage_path_id', 'storage_type', 'tag_ids', 'title', 'user_can_change'}
filtering_strategies: ClassVar[set[FilteringStrategies]] = {FilteringStrategies.WHITELIST}
read_only_fields: ClassVar[set[str]] = {'archived_file_name', 'deleted_at', 'id', 'is_shared_by_requester', 'page_count'}
supported_filtering_params: ClassVar[set[str]] = {'added__date__gt', 'added__date__lt', 'added__day', 'added__gt', 'added__lt', 'added__month', 'added__year', 'archive_serial_number', 'archive_serial_number__gt', 'archive_serial_number__gte', 'archive_serial_number__isnull', 'archive_serial_number__lt', 'archive_serial_number__lte', 'checksum__icontains', 'checksum__iendswith', 'checksum__iexact', 'checksum__istartswith', 'content__contains', 'content__icontains', 'content__iendswith', 'content__iexact', 'content__istartswith', 'correspondent__id', 'correspondent__id__in', 'correspondent__id__none', 'correspondent__isnull', 'correspondent__name__icontains', 'correspondent__name__iendswith', 'correspondent__name__iexact', 'correspondent__name__istartswith', 'correspondent__slug__iexact', 'created__date__gt', 'created__date__lt', 'created__day', 'created__gt', 'created__lt', 'created__month', 'created__year', 'custom_field_query', 'custom_fields__icontains', 'custom_fields__id__all', 'custom_fields__id__in', 'custom_fields__id__none', 'document_type__id', 'document_type__id__in', 'document_type__id__none', 'document_type__isnull', 'document_type__name__icontains', 'document_type__name__iendswith', 'document_type__name__iexact', 'document_type__name__istartswith', 'has_custom_fields', 'id', 'id__in', 'is_in_inbox', 'is_tagged', 'limit', 'original_filename__icontains', 'original_filename__iendswith', 'original_filename__iexact', 'original_filename__istartswith', 'owner__id', 'owner__id__in', 'owner__id__none', 'owner__isnull', 'shared_by__id', 'shared_by__id__in', 'storage_path__id', 'storage_path__id__in', 'storage_path__id__none', 'storage_path__isnull', 'storage_path__name__icontains', 'storage_path__name__iendswith', 'storage_path__name__iexact', 'storage_path__name__istartswith', 'tags__id', 'tags__id__all', 'tags__id__in', 'tags__id__none', 'tags__name__icontains', 'tags__name__iendswith', 'tags__name__iexact', 'tags__name__istartswith', 'title__icontains', 'title__iendswith', 'title__iexact', 'title__istartswith', 'title_content'}
add_tag(tag)[source]

Add a tag to the document.

Adds a tag to the document’s tag_ids list. The tag can be specified as a Tag object, a tag ID, or a tag name. If a tag name is provided, the method will look up the corresponding tag ID.

Parameters:

tag (Tag | int | str) – The tag to add. Can be a Tag object, a tag ID, or a tag name.

Raises:
  • TypeError – If the input value is not a Tag object, an integer, or a string.

  • ResourceNotFoundError – If a tag name is provided but no matching tag is found.

Return type:

None

Example

>>> document = client.documents().get(1)
>>> # Add tag by ID
>>> document.add_tag(5)
>>> # Add tag by object
>>> tag = client.tags().get(3)
>>> document.add_tag(tag)
>>> # Add tag by name
>>> document.add_tag("Invoice")
append_content(value)[source]

Append content to the document.

Adds the specified text to the end of the document’s content, separated by a newline.

Parameters:

value (str) – The content to append.

Return type:

None

Example

>>> document = client.documents().get(1)
>>> document.append_content("Additional notes about this document")
>>> document.save()
property correspondent: Correspondent | None

Get the correspondent for this document.

Retrieves the Correspondent object associated with this document. Uses caching to minimize API requests when accessing the same correspondent multiple times.

Returns:

The correspondent object or None if not set.

Return type:

Correspondent | None

Examples

>>> document = client.documents().get(pk=1)
>>> if document.correspondent:
...     print(document.correspondent.name)
Example Correspondent
property custom_field_ids: list[int]

Get the IDs of the custom fields for this document.

Returns:

A list of custom field IDs associated with this document.

Return type:

list[int]

Example

>>> document = client.documents().get(1)
>>> field_ids = document.custom_field_ids
>>> print(field_ids)
[1, 3, 5]
custom_field_value(field_id, default=None, *, raise_errors=False)[source]

Get the value of a custom field by ID.

Retrieves the value of a specific custom field associated with this document.

Parameters:
  • field_id (int) – The ID of the custom field to retrieve.

  • default (Any, optional) – The value to return if the field is not found. Defaults to None.

  • raise_errors (bool, optional) – Whether to raise an error if the field is not found. Defaults to False.

Returns:

The value of the custom field or the default value if not found.

Return type:

Any

Raises:

ValueError – If raise_errors is True and the field is not found.

Example

>>> document = client.documents().get(1)
>>> # Get value with default
>>> due_date = document.custom_field_value(3, default="Not set")
>>> # Get value with error handling
>>> try:
...     reference = document.custom_field_value(5, raise_errors=True)
... except ValueError:
...     print("Reference field not found")
Reference field not found
property custom_field_values: list[Any]

Get the values of the custom fields for this document.

Returns:

A list of values for the custom fields associated with this document.

Return type:

list[Any]

Example

>>> document = client.documents().get(1)
>>> values = document.custom_field_values
>>> print(values)
['2023-01-15', 'INV-12345', True]
property custom_fields: CustomFieldQuerySet

Get the custom fields for this document.

Returns a QuerySet of CustomField objects associated with this document. The QuerySet is lazily loaded, so API requests are only made when the custom fields are actually accessed.

Returns:

QuerySet of custom fields associated with this document.

Return type:

CustomFieldQuerySet

Example

>>> document = client.documents().get(1)
>>> for field in document.custom_fields:
...     print(f'{field.name}: {field.value}')
Due Date: 2023-04-15
Reference: INV-12345
property document_type: DocumentType | None

Get the document type for this document.

Retrieves the DocumentType object associated with this document. Uses caching to minimize API requests when accessing the same document type multiple times.

Returns:

The document type object or None if not set.

Return type:

DocumentType | None

Examples

>>> document = client.documents().get(pk=1)
>>> if document.document_type:
...     print(document.document_type.name)
Example Document Type
download(original=False)[source]

Download the document file.

Downloads either the archived version (default) or the original version of the document from the Paperless-ngx server.

Parameters:

original (bool, optional) – Whether to download the original file instead of the archived version. Defaults to False (download the archived version).

Returns:

An object containing the downloaded document content

and metadata.

Return type:

DownloadedDocument

Examples

>>> # Download archived version
>>> download = document.download()
>>> with open(download.disposition_filename, 'wb') as f:
...     f.write(download.content)
>>> # Download original version
>>> original = document.download(original=True)
>>> print(f"Downloaded {len(original.content)} bytes")
Downloaded 245367 bytes
get_metadata()[source]

Get the metadata for this document.

Retrieves detailed metadata about the document from the Paperless-ngx API. This includes information like the original file format, creation date, modification date, and other technical details.

Returns:

The document metadata object.

Return type:

DocumentMetadata

Examples

>>> metadata = document.get_metadata()
>>> print(metadata.original_mime_type)
application/pdf
>>> print(metadata.media_filename)
document.pdf
get_suggestions()[source]

Get suggestions for this document.

Retrieves AI-generated suggestions for document metadata from the Paperless-ngx server. This can include suggested tags, correspondent, document type, and other metadata based on the document’s content.

Returns:

An object containing suggested metadata for the document.

Return type:

DocumentSuggestions

Examples

>>> suggestions = document.get_suggestions()
>>> print(f"Suggested tags: {suggestions.tags}")
Suggested tags: [{'name': 'Invoice', 'score': 0.95}, {'name': 'Utility', 'score': 0.87}]
>>> print(f"Suggested correspondent: {suggestions.correspondent}")
Suggested correspondent: {'name': 'Electric Company', 'score': 0.92}
>>> print(f"Suggested document type: {suggestions.document_type}")
Suggested document type: {'name': 'Bill', 'score': 0.89}
property has_search_hit: bool

Check if this document has search hit information.

Returns:

True if this document was returned as part of a search result

and has search hit information, False otherwise.

Return type:

bool

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

preview(original=False)[source]

Get a preview of the document.

Retrieves a preview version of the document from the Paperless-ngx server. This is typically a web-friendly version (e.g., PDF) that can be displayed in a browser.

Parameters:

original (bool, optional) – Whether to preview the original file instead of the archived version. Defaults to False (preview the archived version).

Returns:

An object containing the preview document content

and metadata.

Return type:

DownloadedDocument

Example

>>> preview = document.preview()
>>> with open('preview.pdf', 'wb') as f:
...     f.write(preview.content)
remove_tag(tag)[source]

Remove a tag from the document.

Removes a tag from the document’s tag_ids list. The tag can be specified as a Tag object, a tag ID, or a tag name. If a tag name is provided, the method will look up the corresponding tag ID.

Parameters:

tag (Tag | int | str) – The tag to remove. Can be a Tag object, a tag ID, or a tag name.

Raises:
  • TypeError – If the input value is not a Tag object, an integer, or a string.

  • ResourceNotFoundError – If a tag name is provided but no matching tag is found.

  • ValueError – If the tag is not associated with this document.

Return type:

None

Example

>>> document = client.documents().get(1)
>>> # Remove tag by ID
>>> document.remove_tag(5)
>>> # Remove tag by object
>>> tag = client.tags().get(3)
>>> document.remove_tag(tag)
>>> # Remove tag by name
>>> document.remove_tag("Invoice")
property search_hit: dict[str, Any] | None

Get the search hit information for this document.

When a document is returned as part of a search result, this property contains additional information about the search match.

Returns:

Dictionary with search hit information or None

if this document was not part of a search result.

Return type:

dict[str, Any] | None

serialize_datetime(value)[source]

Serialize datetime fields to ISO format.

Converts datetime objects to ISO 8601 formatted strings for JSON serialization. Returns None if the input value is None.

Parameters:

value (datetime | None) – The datetime value to serialize.

Returns:

The serialized datetime value as an ISO 8601 string, or None.

Return type:

str | None

serialize_notes(value)[source]

Serialize notes to a list of dictionaries.

Converts DocumentNote objects to dictionaries for JSON serialization. Returns an empty list if the input value is None or empty.

Parameters:

value (list[DocumentNote]) – The list of DocumentNote objects to serialize.

Returns:

A list of dictionaries representing the notes.

Return type:

list[dict[str, Any]]

property storage_path: StoragePath | None

Get the storage path for this document.

Retrieves the StoragePath object associated with this document. Uses caching to minimize API requests when accessing the same storage path multiple times.

Returns:

The storage path object or None if not set.

Return type:

StoragePath | None

Examples

>>> document = client.documents().get(pk=1)
>>> if document.storage_path:
...     print(document.storage_path.name)
Example Storage Path
property tag_names: list[str]

Get the names of the tags for this document.

Returns:

A list of tag names associated with this document.

Return type:

list[str]

Example

>>> document = client.documents().get(1)
>>> names = document.tag_names
>>> print(names)
['Invoice', 'Tax', 'Important']
property tags: TagQuerySet

Get the tags for this document.

Returns a QuerySet of Tag objects associated with this document. The QuerySet is lazily loaded, so API requests are only made when the tags are actually accessed.

Returns:

QuerySet of tags associated with this document.

Return type:

TagQuerySet

Examples

>>> document = client.documents().get(pk=1)
>>> for tag in document.tags:
...     print(f'{tag.name} # {tag.id}')
Tag 1 # 1
Tag 2 # 2
Tag 3 # 3
>>> if 5 in document.tags:
...     print('Tag ID #5 is associated with this document')
>>> tag = client.tags().get(pk=1)
>>> if tag in document.tags:
...     print('Tag ID #1 is associated with this document')
>>> filtered_tags = document.tags.filter(name__icontains='example')
>>> for tag in filtered_tags:
...     print(f'{tag.name} # {tag.id}')
thumbnail(original=False)[source]

Get the document thumbnail.

Retrieves a thumbnail image of the document from the Paperless-ngx server. This is typically a small image representation of the first page.

Parameters:

original (bool, optional) – Whether to get the thumbnail of the original file instead of the archived version. Defaults to False (get thumbnail of archived version).

Returns:

An object containing the thumbnail image content

and metadata.

Return type:

DownloadedDocument

Example

>>> thumbnail = document.thumbnail()
>>> with open('thumbnail.png', 'wb') as f:
...     f.write(thumbnail.content)
update_locally(from_db=None, **kwargs)[source]

Update the document locally with the provided data.

Updates the document’s attributes with the provided data without sending an API request. Handles special cases for notes and tags, which cannot be set to None in Paperless-ngx if they already have values.

Parameters:
  • from_db (bool | None, optional) – Whether the update is coming from the database. If True, bypasses certain validation checks. Defaults to None.

  • **kwargs (Any) – Additional data to update the document with.

Raises:

NotImplementedError – If attempting to set notes or tags to None when they are not already None and from_db is False.

Return type:

None

Example

>>> document = client.documents().get(1)
>>> document.update_locally(title="New Title", correspondent_id=5)
>>> document.save()
classmethod validate_custom_fields(value)[source]

Validate and return custom field dictionaries.

Ensures custom fields are properly formatted as a list of CustomFieldValues. Returns an empty list if the input value is None.

Parameters:

value (Any) – The list of custom field dictionaries to validate.

Returns:

A list of validated custom field dictionaries.

Return type:

list[CustomFieldValues]

Raises:

TypeError – If the input value is not None or a list.

classmethod validate_is_shared_by_requester(value)[source]

Validate and return the is_shared_by_requester flag.

Ensures the is_shared_by_requester flag is properly formatted as a boolean. Returns False if the input value is None.

Parameters:

value (Any) – The flag to validate.

Returns:

The validated flag.

Return type:

bool

Raises:

TypeError – If the input value is not None or a boolean.

classmethod validate_notes(value)[source]

Validate and return the list of notes.

Ensures notes are properly formatted as a list of DocumentNote objects. Handles various input formats including None, single DocumentNote objects, and lists.

Parameters:

value (Any) – The list of notes to validate.

Returns:

The validated list of notes.

Return type:

list[Any]

Raises:

TypeError – If the input value is not None, a DocumentNote, or a list.

classmethod validate_tags(value)[source]

Validate and convert tag IDs to a list of integers.

Ensures tag IDs are properly formatted as a list of integers. Handles various input formats including None, single integers, and lists.

Parameters:

value (Any) – The tag IDs to validate, which can be None, an integer, or a list.

Returns:

A list of validated tag IDs.

Return type:

list[int]

Raises:

TypeError – If the input value is not None, an integer, or a list.

Examples

>>> Document.validate_tags(None)
[]
>>> Document.validate_tags(5)
[5]
>>> Document.validate_tags([1, 2, 3])
[1, 2, 3]
classmethod validate_text(value)[source]

Validate and return a text field.

Ensures text fields are properly formatted as strings. Converts integers to strings and returns an empty string if the input value is None.

Parameters:

value (Any) – The value of the text field to validate.

Returns:

The validated text value.

Return type:

str

Raises:

TypeError – If the input value is not None, a string, or an integer.

Examples

>>> Document.validate_text(None)
''
>>> Document.validate_text("Hello")
'Hello'
>>> Document.validate_text(123)
'123'
added: datetime | None
archive_checksum: str | None
archive_filename: str | None
archive_serial_number: int | None
archived_file_name: str | None
checksum: str | None
content: str
correspondent_id: int | None
created: datetime | None
created_date: str | None
custom_field_dicts: Annotated[list[CustomFieldValues], Field(default_factory=list)]
deleted_at: datetime | None
document_type_id: int | None
filename: str | None
is_shared_by_requester: bool
notes: list[DocumentNote]
original_filename: str | None
owner: int | None
page_count: int | None
storage_path_id: int | None
storage_type: DocumentStorageType | None
tag_ids: Annotated[list[int], Field(default_factory=list)]
title: str
user_can_change: bool | None
class paperap.models.Correspondent(**data)[source]

Bases: StandardModel, MatcherMixin

Represent a correspondent in Paperless-NgX.

A correspondent typically represents a person, company, or organization that sends or receives documents. Correspondents can be assigned to documents to help with organization and searching.

slug

URL-friendly identifier for the correspondent, auto-generated.

name

Display name of the correspondent.

document_count

Number of documents associated with this correspondent.

owner

ID of the user who owns this correspondent.

user_can_change

Whether the current user has permission to modify this correspondent.

Examples

Create a new correspondent:
>>> correspondent = client.correspondents.create(name="Electric Company")
Assign a correspondent to a document:
>>> document = client.documents.get(123)
>>> document.correspondent = correspondent.id
>>> document.save()
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Define metadata for the Correspondent model.

Specifies read-only fields and the associated queryset class for the Correspondent model.

read_only_fields

Set of field names that cannot be modified.

queryset

The queryset class to use for this model.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'document_count', 'id', 'name', 'owner', 'slug', 'user_can_change'}
queryset

alias of CorrespondentQuerySet

read_only_fields: ClassVar[set[str]] = {'document_count', 'id', 'slug'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
property documents: DocumentQuerySet

Get all documents associated with this correspondent.

Provides a convenient way to access all documents that have been assigned to this correspondent without having to construct a filter.

Returns:

A queryset containing all documents associated with this correspondent.

Examples

Get all documents for a correspondent:
>>> correspondent = client.correspondents.get(5)
>>> docs = correspondent.documents
>>> print(f"Found {docs.count()} documents")
Filter documents further:
>>> recent_docs = correspondent.documents.filter(created__gt="2023-01-01")
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

slug: str | None
name: str | None
document_count: int
owner: int | None
user_can_change: bool | None
class paperap.models.Tag(**data)[source]

Bases: StandardModel, MatcherMixin

Represent a tag in Paperless-NgX for document categorization.

Tags are used to categorize and organize documents in Paperless-NgX. Each tag has a name, color, and can be designated as an inbox tag. Tags can be assigned to documents and used for filtering and searching.

This class provides methods for interacting with tags, including retrieving associated documents and managing tag properties.

name

The display name of the tag.

Type:

str, optional

slug

The URL-friendly version of the name (auto-generated).

Type:

str, optional

colour

The color of the tag (hex string or integer).

Type:

str or int, optional

is_inbox_tag

Whether this tag is used to mark documents for review.

Type:

bool, optional

document_count

The number of documents with this tag (read-only).

Type:

int

owner

The ID of the user who owns this tag.

Type:

int, optional

user_can_change

Whether the current user has permission to modify this tag.

Type:

bool, optional

Examples

Create a new tag: ```python tag = client.tags.create(

name=”Tax Documents”, color=”#ff0000”, is_inbox_tag=False

Update an existing tag: `python tag = client.tags.get(5) tag.name = "Important Tax Documents" tag.color = "#00ff00" tag.save() `

Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Define metadata for the Tag model.

Specify model-specific metadata including read-only fields and the associated queryset class.

read_only_fields

Fields that cannot be modified by the client.

Type:

set

queryset

The queryset class used for querying tags.

Type:

TagQuerySet

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'colour', 'document_count', 'id', 'is_inbox_tag', 'name', 'owner', 'slug', 'user_can_change'}
queryset

alias of TagQuerySet

read_only_fields: ClassVar[set[str]] = {'document_count', 'id', 'slug'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
property color: str | int | None

Get the tag color (alias for the colour field).

Provide American English spelling alternative for the British ‘colour’ field.

Returns:

The color value as a string (hex code) or integer.

Return type:

str | int | None

property documents: DocumentQuerySet

Get all documents associated with this tag.

Retrieve a queryset of all documents that have been tagged with this tag. The queryset is lazy-loaded, so no API requests are made until the queryset is evaluated.

Returns:

A queryset containing all documents with this tag.

Return type:

DocumentQuerySet

Examples

Get documents with a specific tag: ```python # Get a tag tax_tag = client.tags.get(5)

# Get all documents with this tag tax_documents = tax_tag.documents

# Count documents with this tag count = tax_tag.documents.count()

# Filter documents with this tag further recent_tax_docs = tax_tag.documents.filter(created__gt=”2023-01-01”) ```

classmethod handle_text_color_alias(data)[source]

Handle ‘text_color’ as an alias for ‘colour’.

Ensure compatibility with different API versions by accepting ‘text_color’ as an alternative field name for the tag color.

Parameters:

data (dict[str, Any]) – The input data dictionary to validate.

Returns:

The modified data dictionary with normalized color field.

Return type:

dict[str, Any]

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

name: str | None
slug: str | None
colour: str | int | None
is_inbox_tag: bool | None
document_count: int
owner: int | None
user_can_change: bool | None
class paperap.models.DocumentType(**data)[source]

Bases: StandardModel, MatcherMixin

Represents a document type in Paperless-NgX.

Document types are used to categorize documents and can be configured with matching rules for automatic classification of new documents during consumption.

The MatcherMixin provides functionality for pattern matching against document content or metadata.

name

The name of the document type.

Type:

str

slug

A unique identifier for the document type, auto-generated from name if not provided.

Type:

str, optional

match

The pattern used for matching documents. Only available when using the MatcherMixin methods.

Type:

str, optional

matching_algorithm

The algorithm used for matching. Only available when using the MatcherMixin methods.

Type:

MatchingAlgorithmType, optional

is_insensitive

Whether the matching is case insensitive. Only available when using the MatcherMixin methods.

Type:

bool, optional

document_count

The number of documents of this type (read-only).

Type:

int

owner

The ID of the user who owns this document type.

Type:

int, optional

user_can_change

Whether the current user can modify this document type.

Type:

bool, optional

Examples

Create a new document type:

>>> doc_type = client.document_types.create(
...     name="Invoice",
...     matching_algorithm="auto",
...     match="invoice"
... )

Update an existing document type:

>>> doc_type = client.document_types.get(1)
>>> doc_type.name = "Receipt"
>>> doc_type.save()
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the DocumentType model.

Defines read-only fields and the associated queryset class.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'document_count', 'id', 'name', 'owner', 'slug', 'user_can_change'}
queryset

alias of DocumentTypeQuerySet

read_only_fields: ClassVar[set[str]] = {'document_count', 'id', 'slug'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
property documents: DocumentQuerySet

Get all documents associated with this document type.

Returns:

A queryset containing all documents that have

this document type assigned.

Return type:

DocumentQuerySet

Examples

Get all documents of this type:

>>> documents = doc_type.documents
>>> for doc in documents:
...     print(doc.title)

Filter documents of this type:

>>> recent_docs = doc_type.documents.filter(created__gt="2023-01-01")
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

name: str
slug: str | None
document_count: int
owner: int | None
user_can_change: bool | None
class paperap.models.StoragePath(**data)[source]

Bases: StandardModel, MatcherMixin

Represent a storage path in Paperless-NgX.

A storage path defines where documents are physically stored in the Paperless-NgX file system. Each document can be assigned to a specific storage path, allowing for organized file storage based on document type, date, or other criteria.

Storage paths can also be configured with matching rules to automatically assign documents to specific paths based on their content or metadata.

name

The display name of the storage path.

slug

The URL-friendly version of the name (auto-generated, read-only).

path

The actual filesystem path where documents will be stored.

document_count

The number of documents using this storage path (read-only).

owner

The ID of the user who owns this storage path, if applicable.

user_can_change

Whether the current user has permission to modify this path.

Examples

Create a new storage path:
>>> tax_path = client.storage_paths.create(
...     name="Tax Documents",
...     path="/documents/taxes/"
... )
Assign a storage path to a document:
>>> doc = client.documents.get(123)
>>> doc.storage_path = tax_path.id
>>> doc.save()
Create a storage path with automatic matching:
>>> invoice_path = client.storage_paths.create(
...     name="Invoices",
...     path="/documents/invoices/",
...     matching_algorithm="auto",
...     match="invoice bill receipt"
... )
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Define metadata for the StoragePath model.

This class defines metadata properties that control how the StoragePath model interacts with the Paperless-NgX API, including which fields are read-only and which QuerySet class to use for queries.

read_only_fields

Set of field names that cannot be modified by the client.

queryset

The QuerySet class to use for this model.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'document_count', 'id', 'name', 'owner', 'path', 'slug', 'user_can_change'}
queryset

alias of StoragePathQuerySet

read_only_fields: ClassVar[set[str]] = {'document_count', 'id', 'slug'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
property documents: DocumentQuerySet

Get all documents assigned to this storage path.

Retrieve a queryset containing all documents that use this storage path. The queryset is lazy-loaded, meaning API requests are only made when the results are actually needed (when iterating, slicing, or calling terminal methods like count() or get()).

Returns:

A queryset containing all documents that use this

storage path. The queryset can be further filtered or ordered.

Return type:

DocumentQuerySet

Examples

Get all documents in a storage path:
>>> tax_path = client.storage_paths.get(5)
>>> tax_docs = tax_path.documents
>>> print(f"Found {tax_docs.count()} tax documents")
Filter documents in a storage path:
>>> recent_tax_docs = tax_path.documents.filter(
...     created__gt="2023-01-01"
... )
>>> for doc in recent_tax_docs:
...     print(f"{doc.title} - {doc.created}")
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

name: str
slug: str | None
path: str | None
document_count: int
owner: int | None
user_can_change: bool | None
class paperap.models.CustomField(**data)[source]

Bases: StandardModel

Represents a custom field in Paperless-NgX.

Custom fields allow adding additional metadata to documents beyond the standard fields provided by Paperless-NgX. Each custom field has a name, data type, and can be applied to multiple documents.

name

The display name of the custom field.

data_type

The data type of the custom field (string, integer, boolean, etc.).

extra_data

Additional data associated with the custom field.

document_count

Number of documents using this custom field.

Examples

>>> # Create a new custom field
>>> date_field = client.custom_fields.create(
...     name="Due Date",
...     data_type="date"
... )
>>>
>>> # Set custom field on a document
>>> doc = client.documents.get(123)
>>> doc.custom_fields = {date_field.id: "2023-04-15"}
>>> doc.save()
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the CustomField model.

Defines read-only fields and other metadata for the CustomField model.

read_only_fields

Set of field names that should not be modified by the client.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'data_type', 'document_count', 'extra_data', 'id', 'name'}
read_only_fields: ClassVar[set[str]] = {'id', 'slug'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
property documents: DocumentQuerySet

Get documents that have this custom field.

Returns:

A DocumentQuerySet containing all documents that have this custom field.

Examples

>>> # Get all documents with a specific custom field
>>> field = client.custom_fields.get(5)
>>> for doc in field.documents:
...     print(doc.title)
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

classmethod validate_data_type(v)[source]

Validate the data_type field.

Converts string values to the appropriate CustomFieldTypes enum value and validates that the data type is supported.

Parameters:

v (Any) – The value to validate, can be a string, CustomFieldTypes enum, or None.

Return type:

CustomFieldTypes | None

Returns:

The validated CustomFieldTypes enum value or None.

Raises:

ValueError – If the value is not a valid data type.

name: str
data_type: CustomFieldTypes | None
extra_data: dict[str, Any]
document_count: int
class paperap.models.User(**data)[source]

Bases: StandardModel

Represent a user in Paperless-NgX.

Models a user account in the Paperless-NgX system, including authentication details, personal information, and permission settings. Users can belong to groups and have both direct and inherited permissions.

username

The user’s login username.

Type:

str, optional

email

The user’s email address.

Type:

str, optional

password

The user’s password (only used when creating new users).

Type:

str, optional

first_name

The user’s first name.

Type:

str, optional

last_name

The user’s last name.

Type:

str, optional

date_joined

ISO 8601 formatted date when the user joined.

Type:

str, optional

is_staff

Whether the user has staff privileges.

Type:

bool, optional

is_active

Whether the user account is active.

Type:

bool, optional

is_superuser

Whether the user has superuser privileges.

Type:

bool, optional

groups

List of group IDs the user belongs to.

Type:

list[int]

user_permissions

List of permission strings directly assigned to the user.

Type:

list[str]

inherited_permissions

List of permission strings inherited from groups.

Type:

list[str]

Examples

Get all active users:

active_users = client.users().filter(is_active=True)

Create a new user:

new_user = client.users().create(
    username="jsmith",
    email="jsmith@example.com",
    password="secure_password",
    first_name="John",
    last_name="Smith",
    is_active=True
)
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'date_joined', 'email', 'first_name', 'groups', 'id', 'inherited_permissions', 'is_active', 'is_staff', 'is_superuser', 'last_name', 'password', 'user_permissions', 'username'}
queryset

alias of UserQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
get_groups()[source]

Get all groups this user is a member of.

Returns a queryset containing all the groups that this user belongs to, allowing for further filtering and operations on those groups.

Returns:

A queryset containing all groups this user is a member of.

Return type:

GroupQuerySet

Examples

Find admin groups a user belongs to:

user = client.users().get(1)  # Get user with ID 1
admin_groups = user.get_groups().filter(name__icontains="admin")
print(f"User {user.username} belongs to {user.get_groups().count()} groups")
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

username: str | None
email: str | None
password: str | None
first_name: str | None
last_name: str | None
date_joined: str | None
is_staff: bool | None
is_active: bool | None
is_superuser: bool | None
groups: list[int]
user_permissions: list[str]
inherited_permissions: list[str]
class paperap.models.Group(**data)[source]

Bases: StandardModel

Represent a user group in Paperless-NgX.

A group is a collection of users that share the same permissions. Groups are used to simplify permission management by assigning permissions to groups rather than individual users.

name

The name of the group.

Type:

str, optional

permissions

A list of permission strings assigned to this group.

Type:

list[str]

Examples

Get all admin groups:

admin_groups = client.groups().filter(name__icontains="admin")

Create a new group:

new_group = client.groups().create(
    name="Finance",
    permissions=["view_document"]
)
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'id', 'name', 'permissions'}
queryset

alias of GroupQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

property users: UserQuerySet

Get all users that are members of this group.

Returns a queryset of all users that belong to this group, allowing for further filtering and operations on those users.

Returns:

A queryset containing all users that are members of this group.

Return type:

UserQuerySet

Examples

Get active users in a group:

group = client.groups().get(1)  # Get group with ID 1
active_users = group.users.filter(is_active=True)
print(f"Group {group.name} has {active_users.count()} active users")
name: str | None
permissions: list[str]
class paperap.models.Task(**data)[source]

Bases: StandardModel

Represents a background task in Paperless-NgX.

Tasks are used for tracking long-running operations in Paperless-NgX, such as document processing, OCR, classification, and bulk operations. This model provides access to task status, progress, and results.

task_id

Unique identifier for the task in the task queue system.

task_file_name

Name of the file being processed, if applicable.

task_name

Human-readable name of the task type.

date_created

When the task was created.

date_started

When the task started execution.

date_done

When the task completed (successfully or with error).

type

The type of task being performed.

status

Current status of the task (pending, running, success, failure).

result

Result data from the task, often a JSON string.

acknowledged

Whether the task has been acknowledged by a user.

related_document

ID of the document related to this task, if any.

Examples

>>> # Get a specific task
>>> task = client.tasks.get(5)
>>> print(f"Task status: {task.status}")
>>>
>>> # Wait for a task to complete
>>> document = client.tasks.wait_for_task(task.task_id)
>>> print(f"Document {document.id} ready")
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the Task model.

Defines the queryset class to use for task queries.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'acknowledged', 'date_created', 'date_done', 'date_started', 'id', 'related_document', 'result', 'status', 'task_file_name', 'task_id', 'task_name', 'type'}
queryset

alias of TaskQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

task_id: str
task_file_name: str | None
task_name: TaskNameType | None
date_created: datetime | None
date_started: datetime | None
date_done: datetime | None
type: TaskTypeType | None
status: TaskStatusType | None
result: str | None
acknowledged: bool
related_document: int | None
class paperap.models.SavedView(**data)[source]

Bases: StandardModel

Represents a saved view configuration in Paperless-NgX.

A saved view stores filter rules, sorting preferences, display settings, and other view configuration that can be saved and reused. Saved views can appear on the dashboard and/or sidebar for quick access.

name

The display name of the saved view.

show_on_dashboard

Whether this view should be shown on the dashboard.

show_in_sidebar

Whether this view should be shown in the sidebar.

sort_field

The field to sort results by (e.g., “created”, “title”).

sort_reverse

Whether to sort in reverse/descending order.

filter_rules

List of filter rules to apply to documents.

page_size

Number of documents to show per page.

display_mode

How to display documents (e.g., list, grid).

display_fields

Which fields to display in the view.

owner

ID of the user who owns this saved view.

user_can_change

Whether the current user can modify this saved view.

Examples

>>> # Create a new saved view for tax documents
>>> tax_view = client.saved_views.create(
...     name="Tax Documents",
...     show_on_dashboard=True,
...     show_in_sidebar=True,
...     filter_rules=[
...         {"rule_type": "document_type", "value": "5"}
...     ]
... )
>>>
>>> # Update an existing saved view
>>> view = client.saved_views.get(3)
>>> view.filter_rules.append({"rule_type": "correspondent", "value": "7"})
>>> view.save()
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the SavedView model.

This class defines metadata for the SavedView model, including read-only fields and the associated queryset class.

read_only_fields

Set of field names that cannot be modified by the client.

queryset

The queryset class to use for this model.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'display_fields', 'display_mode', 'filter_rules', 'id', 'name', 'owner', 'page_size', 'show_in_sidebar', 'show_on_dashboard', 'sort_field', 'sort_reverse', 'user_can_change'}
queryset

alias of SavedViewQuerySet

read_only_fields: ClassVar[set[str]] = {'id', 'owner', 'user_can_change'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

name: str
show_on_dashboard: bool | None
show_in_sidebar: bool | None
sort_field: str | None
sort_reverse: bool | None
filter_rules: list[SavedViewFilterRuleType]
page_size: int | None
display_mode: SavedViewDisplayModeType | None
display_fields: list[SavedViewDisplayFieldType]
owner: int | None
user_can_change: bool | None
class paperap.models.UISettings(**data)[source]

Bases: StandardModel

Represents UI settings in Paperless-NgX.

This model provides access to user-specific UI settings and permissions in Paperless-NgX. Unlike most other models, there is typically only one UI settings object per user, and it contains all customizable aspects of the user interface.

user

Dictionary containing user information such as username and ID.

settings

Dictionary containing all UI settings like theme preferences, display options, and other customizable UI elements.

permissions

List of permission strings indicating what actions the current user is allowed to perform in the Paperless-NgX system.

Examples

Get and modify UI settings: ```python # Get current UI settings ui_settings = client.ui_settings.get()

# Check if dark mode is enabled is_dark_mode = ui_settings.settings.get(“dark_mode”, False)

# Enable dark mode ui_settings.settings[“dark_mode”] = True ui_settings.save()

# Check user permissions if “view_document” in ui_settings.permissions:

print(“User can view documents”)

```

Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the UISettings model.

This class defines metadata for the UISettings model, including the associated queryset class.

queryset

The UISettingsQuerySet class used for querying UI settings.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'id', 'permissions', 'settings', 'user'}
queryset

alias of UISettingsQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

user: dict[str, Any]
settings: dict[str, Any]
permissions: list[str]
class paperap.models.Workflow(**data)[source]

Bases: StandardModel

Represents a workflow in Paperless-NgX.

A workflow is a combination of triggers and actions that automate document processing in Paperless-NgX. When a trigger condition is met, the associated actions are executed.

name

The name of the workflow.

order

The execution order of this workflow relative to others.

enabled

Whether this workflow is currently active.

triggers

List of trigger configurations for this workflow.

actions

List of action configurations for this workflow.

Examples

>>> # Create a simple workflow
>>> workflow = Workflow(
...     name="Tag Invoices",
...     enabled=True,
...     triggers=[{"type": "document_added", "filter_filename": "invoice"}],
...     actions=[{"type": "assign", "assign_tags": [5]}]
... )
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the Workflow model.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'actions', 'enabled', 'id', 'name', 'order', 'triggers'}
queryset

alias of WorkflowQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

name: str
order: int | None
enabled: bool | None
triggers: list[dict[str, Any]]
actions: list[dict[str, Any]]
class paperap.models.WorkflowTrigger(**data)[source]

Bases: StandardModel, MatcherMixin

Represents a workflow trigger in Paperless-NgX.

A workflow trigger defines the conditions under which a workflow will be executed. Triggers can be based on document creation, modification, scheduled events, or other system events.

sources

List of source types that can activate this trigger.

type

The type of trigger (e.g., document added, scheduled).

filter_path

Path filter for file-based triggers.

filter_filename

Filename filter for file-based triggers.

filter_mailrule

Mail rule filter for email-based triggers.

filter_has_tags

List of tag IDs that documents must have to trigger.

filter_has_correspondent

Correspondent ID that documents must have.

filter_has_document_type

Document type ID that documents must have.

schedule_date_field

Field to use for date-based scheduling.

schedule_date_custom_field

Custom field ID to use for date-based scheduling.

schedule_offset_days

Days to offset from the scheduled date.

schedule_is_recurring

Whether this trigger recurs on a schedule.

schedule_recurring_interval_days

Interval in days for recurring triggers.

Examples

>>> # Create a trigger for new documents with a specific tag
>>> trigger = WorkflowTrigger(
...     sources=["source_document"],
...     type="document_added",
...     filter_has_tags=[5]  # Tag ID 5
... )
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the WorkflowTrigger model.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'filter_filename', 'filter_has_correspondent', 'filter_has_document_type', 'filter_has_tags', 'filter_mailrule', 'filter_path', 'id', 'schedule_date_custom_field', 'schedule_date_field', 'schedule_is_recurring', 'schedule_offset_days', 'schedule_recurring_interval_days', 'sources', 'type'}
queryset

alias of WorkflowTriggerQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

sources: list[WorkflowTriggerSourceType]
type: WorkflowTriggerType | None
filter_path: str | None
filter_filename: str | None
filter_mailrule: str | None
filter_has_tags: list[int]
filter_has_correspondent: int | None
filter_has_document_type: int | None
schedule_date_field: ScheduleDateFieldType | None
schedule_date_custom_field: int | None
schedule_offset_days: int
schedule_is_recurring: bool
schedule_recurring_interval_days: int
class paperap.models.WorkflowAction(**data)[source]

Bases: StandardModel

Represents a workflow action in Paperless-NgX.

A workflow action defines an operation to be performed when a workflow is triggered. Actions can include assigning metadata to documents, removing metadata, sending emails, or triggering webhooks.

type

The type of action to perform.

# Assignment action attributes
assign_title

Title to assign to the document.

assign_tags

List of tag IDs to assign to the document.

assign_correspondent

Correspondent ID to assign to the document.

assign_document_type

Document type ID to assign to the document.

assign_storage_path

Storage path ID to assign to the document.

assign_owner

Owner ID to assign to the document.

assign_view_users

List of user IDs to grant view permissions.

assign_view_groups

List of group IDs to grant view permissions.

assign_change_users

List of user IDs to grant change permissions.

assign_change_groups

List of group IDs to grant change permissions.

assign_custom_fields

List of custom field IDs to assign.

assign_custom_fields_values

Dictionary mapping custom field IDs to values.

# Removal action attributes
remove_all_tags

Whether to remove all tags from the document.

remove_tags

List of tag IDs to remove from the document.

remove_all_correspondents

Whether to remove all correspondents.

remove_correspondents

List of correspondent IDs to remove.

remove_all_document_types

Whether to remove all document types.

remove_document_types

List of document type IDs to remove.

remove_all_storage_paths

Whether to remove all storage paths.

remove_storage_paths

List of storage path IDs to remove.

remove_custom_fields

List of custom field IDs to remove.

remove_all_custom_fields

Whether to remove all custom fields.

remove_all_owners

Whether to remove all owners.

remove_owners

List of owner IDs to remove.

remove_all_permissions

Whether to remove all permissions.

remove_view_users

List of user IDs to remove view permissions.

remove_view_groups

List of group IDs to remove view permissions.

remove_change_users

List of user IDs to remove change permissions.

remove_change_groups

List of group IDs to remove change permissions.

# Email and webhook action attributes
email

Configuration for email actions.

webhook

Configuration for webhook actions.

Examples

>>> # Create an action to assign tags and a document type
>>> action = WorkflowAction(
...     type="assign",
...     assign_tags=[1, 2],
...     assign_document_type=5
... )
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the WorkflowAction model.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'assign_change_groups', 'assign_change_users', 'assign_correspondent', 'assign_custom_fields', 'assign_custom_fields_values', 'assign_document_type', 'assign_owner', 'assign_storage_path', 'assign_tags', 'assign_title', 'assign_view_groups', 'assign_view_users', 'email', 'id', 'remove_all_correspondents', 'remove_all_custom_fields', 'remove_all_document_types', 'remove_all_owners', 'remove_all_permissions', 'remove_all_storage_paths', 'remove_all_tags', 'remove_change_groups', 'remove_change_users', 'remove_correspondents', 'remove_custom_fields', 'remove_document_types', 'remove_owners', 'remove_storage_paths', 'remove_tags', 'remove_view_groups', 'remove_view_users', 'type', 'webhook'}
queryset

alias of WorkflowActionQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

type: WorkflowActionType | None
assign_title: str | None
assign_tags: list[int]
assign_correspondent: int | None
assign_document_type: int | None
assign_storage_path: int | None
assign_owner: int | None
assign_view_users: list[int]
assign_view_groups: list[int]
assign_change_users: list[int]
assign_change_groups: list[int]
assign_custom_fields: list[int]
assign_custom_fields_values: dict[str, Any]
remove_all_tags: bool | None
remove_tags: list[int]
remove_all_correspondents: bool | None
remove_correspondents: list[int]
remove_all_document_types: bool | None
remove_document_types: list[int]
remove_all_storage_paths: bool | None
remove_storage_paths: list[int]
remove_custom_fields: list[int]
remove_all_custom_fields: bool | None
remove_all_owners: bool | None
remove_owners: list[int]
remove_all_permissions: bool | None
remove_view_users: list[int]
remove_view_groups: list[int]
remove_change_users: list[int]
remove_change_groups: list[int]
email: dict[str, Any] | None
webhook: dict[str, Any] | None
class paperap.models.Profile(**data)[source]

Bases: StandardModel

Represents a user profile in the Paperless-NGX system.

This model corresponds to the user profile endpoint in the Paperless-NGX API and contains information about users, including their personal details and authentication information.

email

The email address of the user.

Type:

str, optional

password

The password for the user. This is write-only and will not be returned in API responses.

Type:

str, optional

first_name

The first name of the user.

Type:

str, optional

last_name

The last name of the user.

Type:

str, optional

auth_token

The authentication token for the user. This can be used for API authentication.

Type:

str, optional

social_accounts

A list of social accounts associated with the user for third-party authentication.

Type:

list

has_usable_password

Indicates if the user has a usable password. False if the user can only log in via social authentication or tokens.

Type:

bool

Examples

>>> # Create a new profile
>>> profile = Profile(
...     email="user@example.com",
...     first_name="John",
...     last_name="Doe",
...     has_usable_password=True
... )
>>>
>>> # Access profile information
>>> print(f"{profile.first_name} {profile.last_name} <{profile.email}>")
John Doe <user@example.com>
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the Profile model.

This class defines metadata for the Profile model, including the associated queryset class for performing queries on profiles.

queryset

The queryset class to use for profile queries.

Type:

type[ProfileQuerySet]

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'auth_token', 'email', 'first_name', 'has_usable_password', 'id', 'last_name', 'password', 'social_accounts'}
queryset

alias of ProfileQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

email: str | None
password: str | None
first_name: str | None
last_name: str | None
auth_token: str | None
social_accounts: list[Any]
has_usable_password: bool

Bases: StandardModel

Model representing a share link in Paperless-NgX.

Share links allow documents to be shared with users who don’t have access to the Paperless-NgX instance. Each share link has a unique slug that can be used to access the document without authentication.

expiration

When the share link expires. If None, the link never expires.

Type:

datetime | None

slug

Unique identifier for the share link URL.

Type:

str | None

document

ID of the document being shared.

Type:

int | None

created

When the share link was created.

Type:

datetime | None

file_version

Which version of the document to share.

Type:

ShareLinkFileVersionType | None

owner

ID of the user who created the share link.

Type:

int | None

Examples

>>> # Create a new share link for document with ID 123
>>> share_link = client.share_links.create(document=123)
>>> print(f"Share link created: {share_link.slug}")
>>>
>>> # Create a share link that expires in 7 days
>>> from datetime import datetime, timedelta
>>> expiry = datetime.now() + timedelta(days=7)
>>> share_link = client.share_links.create(
...     document=123,
...     expiration=expiry
... )
Parameters:

data (Any)

class Meta(model)[source]

Bases: Meta

Metadata for the ShareLinks model.

This class defines the queryset class to use for ShareLinks queries.

Parameters:

model (type[_Self])

blacklist_filtering_params: ClassVar[set[str]] = {}
field_map: dict[str, str] = {}
filtering_disabled: ClassVar[set[str]] = {}
filtering_fields: ClassVar[set[str]] = {'_resource', 'created', 'document', 'expiration', 'file_version', 'id', 'owner', 'slug'}
queryset

alias of ShareLinksQuerySet

read_only_fields: ClassVar[set[str]] = {'id'}
supported_filtering_params: ClassVar[set[str]] = {'id', 'id__in', 'limit'}
get_document()[source]

Get the document associated with this share link.

Retrieves the full Document object associated with this share link by querying the Paperless-NgX API using the document ID stored in this share link.

Returns:

The document object associated with this share link.

Return type:

Document

Raises:

Examples

>>> share_link = client.share_links.get(5)
>>> document = share_link.get_document()
>>> print(f"Shared document title: {document.title}")
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore', 'populate_by_name': True, 'use_enum_values': True, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context: Any, /) None

We need to both initialize private attributes and call the user-defined model_post_init method.

Parameters:
Return type:

None

serialize_datetime(value)[source]

Serialize a datetime object to an ISO 8601 formatted string.

This serializer converts datetime objects to ISO 8601 formatted strings for JSON serialization when sending data to the Paperless-NgX API.

Parameters:

value (datetime | None) – The datetime object to serialize.

Returns:

The ISO 8601 formatted string representation of the datetime,

or None if the input is None.

Return type:

str | None

Examples

>>> share_link = ShareLinks()
>>> from datetime import datetime
>>> dt = datetime(2023, 1, 15, 12, 30, 45)
>>> share_link.serialize_datetime(dt)
'2023-01-15T12:30:45'
>>> share_link.serialize_datetime(None)
None
expiration: datetime | None
slug: str | None
document: int | None
created: datetime | None
file_version: ShareLinkFileVersionType | None
owner: int | None
class paperap.models.BaseQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: Iterable, Generic

A lazy-loaded, chainable query interface for Paperless-ngx resources.

Provides pagination, filtering, and caching functionality similar to Django’s QuerySet. Only fetches data when it’s actually needed, optimizing API requests and performance.

resource

The resource instance associated with the queryset.

filters

Dictionary of filters to apply to the API request.

_last_response

The last response received from the API.

_result_cache

List of model instances already fetched.

_fetch_all

Whether all results have been fetched.

_next_url

URL for the next page of results, if any.

_urls_fetched

List of URLs already fetched to prevent loops.

_iter

Current iterator over results, if any.

Examples

Basic usage:

>>> docs = client.documents()  # Returns a BaseQuerySet
>>> for doc in docs.filter(title__contains="invoice"):
...     print(doc.title)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

__bool__()[source]

Return True if the QuerySet has any results.

Calls exists() to check if any objects match the current filters.

Return type:

bool

Returns:

True if there are any objects matching the filters.

Examples

Check if any documents exist:

>>> if client.documents():
...     print("Documents found")
__contains__(item)[source]

Return True if the QuerySet contains the given object.

Checks if the given object is present in the queryset by comparing it with each object in the queryset.

Parameters:

item (Any) – The object to check for.

Return type:

bool

Returns:

True if the object is in the QuerySet.

Examples

Check if a document is in a queryset:

>>> doc = client.documents().get(123)
>>> if doc in client.documents().filter(title__contains="invoice"):
...     print("Document is an invoice")
__getitem__(key)[source]

Retrieve an item or slice of items from the QuerySet.

Supports both integer indexing and slicing, optimizing API requests when possible by using limit and offset parameters.

Parameters:

key (int | slice) – An integer index or slice object.

Return type:

_Model | list[_Model]

Returns:

A single object or list of objects.

Raises:

IndexError – If the index is out of range.

Examples

Get a single document by position:

>>> first_doc = client.documents()[0]

Get a slice of documents:

>>> recent_docs = client.documents().order_by('-created')[:10]
__init__(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Initialize a new BaseQuerySet.

Parameters:
  • resource (BaseResource[_Model, Self]) – The resource instance that will handle API requests.

  • filters (dict[str, Any] | None) – Initial filters to apply to the queryset.

  • _cache (list[_Model] | None) – Pre-populated result cache (internal use).

  • _fetch_all (bool) – Whether all results have been fetched (internal use).

  • _next_url (str | None) – URL for the next page of results (internal use).

  • _last_response (ClientResponse) – Last API response received (internal use).

  • _iter (Iterator[_Model] | None) – Current iterator over results (internal use).

  • _urls_fetched (list[str] | None) – List of URLs already fetched (internal use).

__iter__()[source]

Iterate over the objects in the QuerySet.

Implements lazy loading of results, fetching additional pages as needed when iterating through the queryset.

Return type:

Iterator[_Model]

Returns:

An iterator over the model instances.

Examples

Iterate through documents:

>>> for doc in client.documents():
...     print(doc.title)
__len__()[source]

Return the number of objects in the QuerySet.

Calls count() to determine the total number of objects matching the current filters.

Return type:

int

Returns:

The count of objects.

Examples

Get the number of documents:

>>> num_docs = len(client.documents())
>>> print(f"Total documents: {num_docs}")
all()[source]

Return a new QuerySet that copies the current one.

Creates a copy of the current queryset with the same filters. Often used to create a new queryset instance for method chaining.

Return type:

Self

Returns:

A copy of the current QuerySet.

Examples

Create a copy of a queryset:

>>> all_docs = client.documents().all()

Chain with other methods:

>>> recent_docs = client.documents().all().order_by('-created')
count()[source]

Return the total number of objects in the queryset.

Makes an API request if necessary to determine the total count of objects matching the current filters.

Return type:

int

Returns:

The total count of objects matching the filters.

Raises:

NotImplementedError – If the count cannot be determined from the API response.

Examples

Count all documents:

>>> total = client.documents().count()
>>> print(f"Total documents: {total}")

Count filtered documents:

>>> invoice_count = client.documents().filter(title__contains="invoice").count()
count_this_page()[source]

Return the number of objects on the current page.

Counts only the objects on the current page of results, without fetching additional pages. Useful for pagination displays.

Return type:

int

Returns:

The count of objects on the current page.

Raises:

NotImplementedError – If the current page count cannot be determined.

Examples

Get count of current page:

>>> page_count = client.documents().count_this_page()
>>> print(f"Items on this page: {page_count}")
exclude(**kwargs)[source]

Return a new QuerySet excluding objects with the given filters.

Parameters:

**kwargs (Any) – Filters to exclude, where keys are field names and values are excluded values. Supports the same lookup syntax as filter().

Return type:

Self

Returns:

A new QuerySet excluding objects that match the filters.

Examples

Get documents with any correspondent except ID 1:

>>> docs = client.documents().exclude(correspondent=1)

Exclude documents with specific words in title:

>>> docs = client.documents().exclude(title__contains="draft")
exists()[source]

Return True if the QuerySet contains any results.

Optimizes the API request by checking for at least one result rather than fetching all results.

Return type:

bool

Returns:

True if there are any objects matching the filters.

Examples

Check if any documents exist:

>>> if client.documents().exists():
...     print("Documents found")

Check if specific documents exist:

>>> has_invoices = client.documents().filter(title__contains="invoice").exists()
filter(**kwargs)[source]

Return a new QuerySet with the given filters applied.

Parameters:

**kwargs (Any) – Filters to apply, where keys are field names and values are desired values. Supports Django-style lookups like field__contains, field__in, etc.

Return type:

Self

Returns:

A new QuerySet with the additional filters applied.

Examples

Get documents with specific correspondent:

>>> docs = client.documents().filter(correspondent=1)

Filter with multiple conditions:

>>> docs = client.documents().filter(
...     title__contains="invoice",
...     created__gt="2023-01-01"
... )
filter_field_by_str(field, value, *, exact=True, case_insensitive=True)[source]

Filter a queryset based on a given string field.

Allows subclasses to easily implement custom filter methods for string fields with consistent behavior.

Parameters:
  • field (str) – The field name to filter by.

  • value (str) – The string value to filter against.

  • exact (bool) – Whether to filter by an exact match (True) or contains (False).

  • case_insensitive (bool) – Whether the filter should be case-insensitive.

Return type:

Self

Returns:

A new QuerySet instance with the filter applied.

Examples

Filter documents by title (case-insensitive exact match):

>>> docs = client.documents().filter_field_by_str('title', 'Invoice', exact=True)

Filter documents by title containing text (case-insensitive):

>>> docs = client.documents().filter_field_by_str('title', 'invoice', exact=False)
first()[source]

Return the first object in the QuerySet, or None if empty.

Optimizes the API request by limiting to a single result when possible.

Return type:

_Model | None

Returns:

The first object or None if no objects match.

Examples

Get the first document:

>>> first_doc = client.documents().first()
>>> if first_doc:
...     print(f"First document: {first_doc.title}")

Get the first document matching a filter:

>>> first_invoice = client.documents().filter(title__contains="invoice").first()
get(pk)[source]

Retrieve a single object from the API.

This base implementation raises NotImplementedError. Subclasses like StandardQuerySet implement this method for models with ID fields.

Parameters:

pk (Any) – The primary key (e.g., the id) of the object to retrieve.

Return type:

_Model

Returns:

A single object matching the query.

Raises:

Examples

Get document with ID 123:

>>> doc = client.documents().get(123)
last()[source]

Return the last object in the QuerySet, or None if empty.

Note

This method requires fetching all results to determine the last one, which may be inefficient for large result sets.

Return type:

_Model | None

Returns:

The last object or None if no objects match.

Examples

Get the last document:

>>> last_doc = client.documents().last()
>>> if last_doc:
...     print(f"Last document: {last_doc.title}")

Get the last document in a specific order:

>>> oldest_doc = client.documents().order_by('created').last()
none()[source]

Return an empty QuerySet.

Creates a queryset that will always return no results, which is useful for conditional queries.

Return type:

Self

Returns:

An empty QuerySet.

Examples

Create an empty queryset:

>>> empty_docs = client.documents().none()
>>> len(empty_docs)
0

Conditional query:

>>> if condition:
...     docs = client.documents().filter(title__contains="invoice")
... else:
...     docs = client.documents().none()
order_by(*fields)[source]

Return a new QuerySet ordered by the specified fields.

Parameters:

*fields (str) – Field names to order by. Prefix with ‘-’ for descending order. Multiple fields can be specified for multi-level sorting.

Return type:

Self

Returns:

A new QuerySet with the ordering applied.

Examples

Order documents by title ascending:

>>> docs = client.documents().order_by('title')

Order by multiple fields (created date descending, then title ascending):

>>> docs = client.documents().order_by('-created', 'title')
resource: BaseResource[TypeVar(_Model, bound= BaseModel), Self]
filters: dict[str, Any]
class paperap.models.StandardQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: BaseQuerySet, Generic

A queryset for StandardModel instances with ID fields.

Extends BaseQuerySet to provide additional functionality specific to models with standard fields like ‘id’, including direct lookups by ID, bulk operations, and specialized filtering methods.

resource

The StandardResource instance associated with the queryset.

Examples

Get documents by ID:

>>> doc = client.documents().get(123)

Filter documents by ID:

>>> docs = client.documents().id([1, 2, 3])

Perform bulk operations:

>>> client.documents().filter(title__contains="draft").delete()
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

__contains__(item)[source]

Return True if the QuerySet contains the given object.

Checks if an object with the same ID is in the queryset. Can accept either a model instance or an integer ID.

Note

This method only ensures a match by ID, not by full object equality. This is intentional, as the object may be outdated or not fully populated.

Parameters:

item (Any) – The object or ID to check for.

Return type:

bool

Returns:

True if an object with the matching ID is in the QuerySet.

Examples

Check if a document is in a queryset:

>>> doc = client.documents().get(123)
>>> if doc in client.documents().filter(title__contains="invoice"):
...     print("Document is an invoice")

Check if a document ID is in a queryset:

>>> if 123 in client.documents().filter(title__contains="invoice"):
...     print("Document 123 is an invoice")
get(pk)[source]

Retrieve a single object from the API by its ID.

First checks the result cache for an object with the given ID, then falls back to making a direct API request if not found.

Parameters:

pk (int) – The ID of the object to retrieve.

Return type:

_Model

Returns:

A single object matching the ID.

Raises:

ObjectNotFoundError – If no object with the given ID exists.

Examples

Get document with ID 123:

>>> doc = client.documents().get(123)
>>> print(f"Retrieved: {doc.title}")
id(value)[source]

Filter models by ID.

Provides a convenient way to filter objects by their ID or a list of IDs.

Parameters:

value (int | list[int]) – The ID or list of IDs to filter by.

Return type:

Self

Returns:

Filtered QuerySet containing only objects with the specified ID(s).

Examples

Get document with ID 123:

>>> doc = client.documents().id(123).first()

Get multiple documents by ID:

>>> docs = client.documents().id([123, 456, 789])
>>> for doc in docs:
...     print(doc.title)
resource: StandardResource[TypeVar(_Model, bound= StandardModel), Self]
class paperap.models.DocumentQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[Document], HasOwner

QuerySet for Paperless-ngx documents with specialized filtering methods.

This class extends StandardQuerySet to provide document-specific filtering, searching, and bulk operations. It includes methods for filtering by document metadata, content, custom fields, and more, as well as bulk operations like merging, rotating, and updating document properties.

Examples

>>> # Search for documents
>>> docs = client.documents().search("invoice")
>>> for doc in docs:
...     print(doc.title)
>>> # Find documents similar to a specific document
>>> similar_docs = client.documents().more_like(42)
>>> for doc in similar_docs:
...     print(doc.title)
>>> # Filter by correspondent and document type
>>> filtered_docs = client.documents().correspondent(5).document_type("Invoice")
>>> for doc in filtered_docs:
...     print(f"{doc.title} - {doc.created}")
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

add_tag(tag_id)[source]

Add a tag to all documents in the current queryset.

This is a convenience method that calls modify_tags with a single tag ID to add.

Parameters:

tag_id (int) – Tag ID to add to all documents in the queryset.

Returns:

The current queryset for method chaining.

Return type:

Self

Examples

>>> # Add tag 3 to all documents with "invoice" in title
>>> client.documents().title("invoice", exact=False).add_tag(3)
>>>
>>> # Add tag to documents from a specific correspondent
>>> client.documents().correspondent_name("Electric Company").add_tag(5)
added_after(date_str)[source]

Filter documents added after the specified date.

Parameters:

date_str (str) – ISO format date string (YYYY-MM-DD).

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find documents added after January 1, 2023
>>> docs = client.documents().added_after("2023-01-01")
added_before(date_str)[source]

Filter documents added before the specified date.

Parameters:

date_str (str) – ISO format date string (YYYY-MM-DD).

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find documents added before December 31, 2022
>>> docs = client.documents().added_before("2022-12-31")
asn(value, *, exact=True, case_insensitive=True)[source]

Filter documents by archive serial number (ASN).

The archive serial number is a unique identifier assigned to documents in Paperless-ngx, often used for referencing physical documents.

Parameters:
  • value (str) – The archive serial number to filter by.

  • exact (bool) – If True, match the exact value, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Exact match (default)
>>> docs = client.documents().asn("2023-0042")
>>>
>>> # Contains match
>>> docs = client.documents().asn("2023", exact=False)
content(text)[source]

Filter documents whose content contains the specified text.

This method searches the OCR-extracted text content of documents.

Parameters:

text (str) – The text to search for in document content.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find documents containing "invoice amount"
>>> docs = client.documents().content("invoice amount")
>>>
>>> # Chain with other filters
>>> recent_with_text = client.documents().content("tax").created_after("2023-01-01")
correspondent(value=None, *, exact=True, case_insensitive=True, **kwargs)[source]

Filter documents by correspondent.

This method provides a flexible interface for filtering documents by correspondent, supporting filtering by ID, name, or slug, with options for exact or partial matching.

Any number of filter arguments can be provided, but at least one must be specified.

Parameters:
  • value (int | str | None) – The correspondent ID or name to filter by.

  • exact (bool) – If True, match the exact value, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching for string values.

  • **kwargs (Any) – Additional filters (slug, id, name).

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Raises:
  • ValueError – If no valid filters are provided.

  • TypeError – If value is not an int or str.

Examples

>>> # Filter by ID
>>> client.documents().correspondent(1)
>>> client.documents().correspondent(id=1)
>>>
>>> # Filter by name
>>> client.documents().correspondent("John Doe")
>>> client.documents().correspondent(name="John Doe")
>>>
>>> # Filter by name (partial match)
>>> client.documents().correspondent("John", exact=False)
>>>
>>> # Filter by slug
>>> client.documents().correspondent(slug="john-doe")
>>>
>>> # Filter by ID and name
>>> client.documents().correspondent(1, name="John Doe")
correspondent_id(correspondent_id)[source]

Filter documents by correspondent ID.

Parameters:

correspondent_id (int) – The correspondent ID to filter by.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Filter documents with correspondent ID 5
>>> docs = client.documents().correspondent_id(5)
correspondent_name(name, *, exact=True, case_insensitive=True)[source]

Filter documents by correspondent name.

Parameters:
  • name (str) – The correspondent name to filter by.

  • exact (bool) – If True, match the exact name, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Exact match (default)
>>> docs = client.documents().correspondent_name("Electric Company")
>>>
>>> # Contains match
>>> docs = client.documents().correspondent_name("Electric", exact=False)
correspondent_slug(slug, *, exact=True, case_insensitive=True)[source]

Filter documents by correspondent slug.

Parameters:
  • slug (str) – The correspondent slug to filter by.

  • exact (bool) – If True, match the exact slug, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Exact match (default)
>>> docs = client.documents().correspondent_slug("electric-company")
>>>
>>> # Contains match
>>> docs = client.documents().correspondent_slug("electric", exact=False)
created_after(date)[source]

Filter models created after a given date.

This method filters documents based on their creation date in Paperless-ngx.

Parameters:

date (datetime | str) – The date to filter by. Can be a datetime object or an ISO format string.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Using string date
>>> docs = client.documents().created_after("2023-01-01")
>>>
>>> # Using datetime object
>>> from datetime import datetime
>>> date = datetime(2023, 1, 1)
>>> docs = client.documents().created_after(date)
created_before(date)[source]

Filter models created before a given date.

This method filters documents based on their creation date in Paperless-ngx.

Parameters:

date (datetime | str) – The date to filter by. Can be a datetime object or an ISO format string.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Using string date
>>> docs = client.documents().created_before("2023-01-01")
>>>
>>> # Using datetime object
>>> from datetime import datetime
>>> date = datetime(2023, 1, 1)
>>> docs = client.documents().created_before(date)
created_between(start, end)[source]

Filter models created between two dates.

This method filters documents with creation dates falling within the specified range.

Parameters:
  • start (datetime | str) – The start date to filter by. Can be a datetime object or an ISO format string.

  • end (datetime | str) – The end date to filter by. Can be a datetime object or an ISO format string.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Using string dates
>>> docs = client.documents().created_between("2023-01-01", "2023-12-31")
>>>
>>> # Using datetime objects
>>> from datetime import datetime
>>> start = datetime(2023, 1, 1)
>>> end = datetime(2023, 12, 31)
>>> docs = client.documents().created_between(start, end)
custom_field(field, value, *, exact=False, case_insensitive=True)[source]

Filter documents by custom field.

This method filters documents based on a specific custom field’s value.

Parameters:
  • field (str) – The name of the custom field to filter by.

  • value (Any) – The value to filter by.

  • exact (bool) – If True, match the exact value, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching for string values.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Contains match (default)
>>> docs = client.documents().custom_field("Reference Number", "INV")
>>>
>>> # Exact match
>>> docs = client.documents().custom_field("Status", "Paid", exact=True)
>>>
>>> # Case-sensitive contains match
>>> docs = client.documents().custom_field("Notes", "Important",
...                                      case_insensitive=False)
custom_field_contains(field, values)[source]

Filter documents with a custom field that contains all specified values.

This method is useful for custom fields that can hold multiple values, such as array or list-type fields.

Parameters:
  • field (str) – The name of the custom field.

  • values (list[Any]) – The list of values that the field should contain.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find documents with tags field containing both "important" and "tax"
>>> docs = client.documents().custom_field_contains("Tags", ["important", "tax"])
>>>
>>> # Find documents with categories containing specific values
>>> docs = client.documents().custom_field_contains("Categories", ["Finance", "Tax"])
custom_field_exact(field, value)[source]

Filter documents with a custom field value that matches exactly.

This method is a shorthand for custom_field_query with the “exact” operation.

Parameters:
  • field (str) – The name of the custom field.

  • value (Any) – The exact value to match.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Match exact status
>>> docs = client.documents().custom_field_exact("Status", "Paid")
>>>
>>> # Match exact date
>>> docs = client.documents().custom_field_exact("Due Date", "2023-04-15")
custom_field_exists(field, exists=True)[source]

Filter documents based on the existence of a custom field.

This method is a shorthand for custom_field_query with the “exists” operation.

Parameters:
  • field (str) – The name of the custom field.

  • exists (bool) – True to filter documents where the field exists, False otherwise.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find documents that have the "Priority" field
>>> docs = client.documents().custom_field_exists("Priority")
>>>
>>> # Find documents that don't have the "Review Date" field
>>> docs = client.documents().custom_field_exists("Review Date", exists=False)
custom_field_fullsearch(value, *, case_insensitive=True)[source]

Filter documents by searching through both custom field name and value.

This method searches across all custom fields (both names and values) for the specified text.

Parameters:
  • value (str) – The search string to look for in custom fields.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Raises:

NotImplementedError – If case_insensitive is False, as Paperless NGX doesn’t support case-sensitive custom field search.

Examples

>>> # Find documents with custom fields containing "reference"
>>> docs = client.documents().custom_field_fullsearch("reference")
custom_field_in(field, values)[source]

Filter documents with a custom field value in a list of values.

This method is a shorthand for custom_field_query with the “in” operation.

Parameters:
  • field (str) – The name of the custom field.

  • values (list[Any]) – The list of values to match against.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Match documents with status in a list
>>> docs = client.documents().custom_field_in("Status", ["Paid", "Pending"])
>>>
>>> # Match documents with specific reference numbers
>>> docs = client.documents().custom_field_in("Reference", ["INV-001", "INV-002", "INV-003"])
custom_field_isnull(field)[source]

Filter documents with a custom field that is null or empty.

This method finds documents where the specified custom field either doesn’t exist or has an empty value.

Parameters:

field (str) – The name of the custom field.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find documents with missing or empty "Status" field
>>> docs = client.documents().custom_field_isnull("Status")
>>>
>>> # Chain with other filters
>>> recent_missing_field = client.documents().custom_field_isnull("Priority").created_after("2023-01-01")
custom_field_query(*args, **kwargs)[source]

Filter documents by custom field query.

Parameters:
Return type:

Self

custom_field_range(field, start, end)[source]

Filter documents with a custom field value within a specified range.

This is particularly useful for date or numeric custom fields.

Parameters:
  • field (str) – The name of the custom field.

  • start (str) – The start value of the range.

  • end (str) – The end value of the range.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Date range
>>> docs = client.documents().custom_field_range("Invoice Date", "2023-01-01", "2023-12-31")
>>>
>>> # Numeric range
>>> docs = client.documents().custom_field_range("Amount", "100", "500")
delete()[source]

Delete all documents in the current queryset.

This method performs a bulk delete operation on all documents matching the current queryset filters.

Returns:

The API response from the bulk delete operation. None if there are no documents to delete.

Return type:

ClientResponse

Examples

>>> # Delete all documents with "invoice" in title
>>> client.documents().title("invoice", exact=False).delete()
>>>
>>> # Delete old documents
>>> client.documents().created_before("2020-01-01").delete()
document_type(value=None, *, exact=True, case_insensitive=True, **kwargs)[source]

Filter documents by document type.

This method provides a flexible interface for filtering documents by document type, supporting filtering by ID or name, with options for exact or partial matching.

Any number of filter arguments can be provided, but at least one must be specified.

Parameters:
  • value (int | str | None) – The document type ID or name to filter by.

  • exact (bool) – If True, match the exact value, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching for string values.

  • **kwargs (Any) – Additional filters (id, name).

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Raises:
  • ValueError – If no valid filters are provided.

  • TypeError – If value is not an int or str.

Examples

>>> # Filter by ID
>>> client.documents().document_type(1)
>>> client.documents().document_type(id=1)
>>>
>>> # Filter by name
>>> client.documents().document_type("Invoice")
>>> client.documents().document_type(name="Invoice")
>>>
>>> # Filter by name (partial match)
>>> client.documents().document_type("Inv", exact=False)
>>>
>>> # Filter by ID and name
>>> client.documents().document_type(1, name="Invoice")
document_type_id(document_type_id)[source]

Filter documents by document type ID.

Parameters:

document_type_id (int) – The document type ID to filter by.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Filter documents with document type ID 3
>>> docs = client.documents().document_type_id(3)
document_type_name(name, *, exact=True, case_insensitive=True)[source]

Filter documents by document type name.

Parameters:
  • name (str) – The document type name to filter by.

  • exact (bool) – If True, match the exact name, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Exact match (default)
>>> docs = client.documents().document_type_name("Invoice")
>>>
>>> # Contains match
>>> docs = client.documents().document_type_name("bill", exact=False)
has_custom_field_id(pk, *, exact=False)[source]

Filter documents that have a custom field with the specified ID(s).

This method filters documents based on the presence of specific custom fields, regardless of their values.

Parameters:
  • pk (int | list[int]) – A single custom field ID or list of custom field IDs.

  • exact (bool) – If True, return results that have exactly these IDs and no others. If False, return results that have at least these IDs.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Documents with custom field ID 5
>>> docs = client.documents().has_custom_field_id(5)
>>>
>>> # Documents with custom field IDs 5 and 7
>>> docs = client.documents().has_custom_field_id([5, 7])
>>>
>>> # Documents with exactly custom field IDs 5 and 7 and no others
>>> docs = client.documents().has_custom_field_id([5, 7], exact=True)
has_custom_fields()[source]

Filter documents that have any custom fields.

This method returns documents that have at least one custom field defined, regardless of the field name or value.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find all documents with any custom fields
>>> docs = client.documents().has_custom_fields()
merge(metadata_document_id=None, delete_originals=False)[source]

Merge all documents in the current queryset into a single document.

This method combines multiple documents into a single PDF document.

Parameters:
  • metadata_document_id (int | None) – Apply metadata from this document to the merged document. If None, metadata from the first document will be used.

  • delete_originals (bool) – Whether to delete the original documents after merging.

Returns:

True if submitting the merge succeeded, False if there are no documents to merge.

Return type:

bool

Raises:

Examples

>>> # Merge all documents with tag "merge_me"
>>> client.documents().tag_name("merge_me").merge(delete_originals=True)
>>>
>>> # Merge documents and use metadata from document ID 42
>>> client.documents().correspondent_name("Electric Company").merge(
...     metadata_document_id=42, delete_originals=False
... )
modify_custom_fields(add_custom_fields=None, remove_custom_fields=None)[source]

Modify custom fields on all documents in the current queryset.

This method allows for adding, updating, and removing custom fields in bulk for all documents matching the current queryset filters.

Parameters:
  • add_custom_fields (dict[int, Any] | None) – Dictionary of custom field ID to value pairs to add or update.

  • remove_custom_fields (list[int] | None) – List of custom field IDs to remove.

Returns:

The current queryset for method chaining.

Return type:

Self

Examples

>>> # Add a custom field to documents with "invoice" in title
>>> client.documents().title("invoice", exact=False).modify_custom_fields(
...     add_custom_fields={5: "Processed"}
... )
>>>
>>> # Add one field and remove another
>>> client.documents().correspondent_id(3).modify_custom_fields(
...     add_custom_fields={7: "2023-04-15"},
...     remove_custom_fields=[9]
... )
modify_tags(add_tags=None, remove_tags=None)[source]

Modify tags on all documents in the current queryset.

This method allows for adding and removing tags in bulk for all documents matching the current queryset filters.

Parameters:
  • add_tags (list[int] | None) – List of tag IDs to add to the documents.

  • remove_tags (list[int] | None) – List of tag IDs to remove from the documents.

Returns:

The current queryset for method chaining.

Return type:

Self

Examples

>>> # Add tag 3 and remove tag 4 from all documents with "invoice" in title
>>> client.documents().title("invoice", exact=False).modify_tags(
...     add_tags=[3], remove_tags=[4]
... )
>>>
>>> # Add multiple tags to recent documents
>>> from datetime import datetime, timedelta
>>> month_ago = datetime.now() - timedelta(days=30)
>>> client.documents().created_after(month_ago.strftime("%Y-%m-%d")).modify_tags(
...     add_tags=[5, 7, 9]
... )
more_like(document_id)[source]

Find documents similar to the specified document.

Uses Paperless-ngx’s similarity algorithm to find documents with content or metadata similar to the specified document.

Parameters:

document_id (int) – The ID of the document to find similar documents for.

Return type:

DocumentQuerySet

Returns:

A queryset with similar documents.

Examples

>>> # Find documents similar to document with ID 42
>>> similar_docs = client.documents().more_like(42)
>>> for doc in similar_docs:
...     print(doc.title)
>>>
>>> # Chain with other filters
>>> recent_similar = client.documents().more_like(42).created_after("2023-01-01")
no_custom_fields()[source]

Filter documents that do not have any custom fields.

This method returns documents that have no custom fields defined.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find all documents without any custom fields
>>> docs = client.documents().no_custom_fields()
notes(text)[source]

Filter documents whose notes contain the specified text.

This method searches through the document notes for the specified text.

Parameters:

text (str) – The text to search for in document notes.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find documents with "follow up" in notes
>>> docs = client.documents().notes("follow up")
>>>
>>> # Chain with other filters
>>> important_notes = client.documents().notes("important").tag_name("tax")
original_filename(name, *, exact=True, case_insensitive=True)[source]

Filter documents by original file name.

This filters based on the original filename of the document when it was uploaded.

Parameters:
  • name (str) – The original file name to filter by.

  • exact (bool) – If True, match the exact name, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Exact match (default)
>>> docs = client.documents().original_filename("scan_001.pdf")
>>>
>>> # Contains match
>>> docs = client.documents().original_filename("invoice", exact=False)
remove_tag(tag_id)[source]

Remove a tag from all documents in the current queryset.

This is a convenience method that calls modify_tags with a single tag ID to remove.

Parameters:

tag_id (int) – Tag ID to remove from all documents in the queryset.

Returns:

The current queryset for method chaining.

Return type:

Self

Examples

>>> # Remove tag 4 from all documents with "invoice" in title
>>> client.documents().title("invoice", exact=False).remove_tag(4)
>>>
>>> # Remove tag from old documents
>>> client.documents().created_before("2020-01-01").remove_tag(7)
reprocess()[source]

Reprocess all documents in the current queryset.

This method triggers Paperless-ngx to re-run OCR and classification on all documents matching the current queryset filters.

Returns:

The API response from the bulk reprocess operation. None if there are no documents to reprocess.

Return type:

ClientResponse

Examples

>>> # Reprocess documents added in the last week
>>> from datetime import datetime, timedelta
>>> week_ago = datetime.now() - timedelta(days=7)
>>> client.documents().added_after(week_ago.strftime("%Y-%m-%d")).reprocess()
>>>
>>> # Reprocess documents with empty content
>>> client.documents().filter(content="").reprocess()
rotate(degrees)[source]

Rotate all documents in the current queryset.

This method rotates the PDF files of all documents matching the current queryset filters.

Parameters:

degrees (int) – Degrees to rotate (must be 90, 180, or 270).

Returns:

The API response from the bulk rotate operation. None if there are no documents to rotate.

Return type:

ClientResponse

Examples

>>> # Rotate all documents with "sideways" in title by 90 degrees
>>> client.documents().title("sideways", exact=False).rotate(90)
>>>
>>> # Rotate upside-down documents by 180 degrees
>>> client.documents().tag_name("upside-down").rotate(180)
search(query)[source]

Search for documents using a query string.

This method uses the Paperless-ngx full-text search functionality to find documents matching the query string in their content or metadata.

Parameters:

query (str) – The search query string.

Return type:

DocumentQuerySet

Returns:

A queryset with the search results.

Examples

>>> # Search for documents containing "invoice"
>>> docs = client.documents().search("invoice")
>>> for doc in docs:
...     print(doc.title)
>>>
>>> # Search with multiple terms
>>> docs = client.documents().search("electric bill 2023")
set_permissions(permissions=None, owner_id=None, merge=False)[source]

Set permissions for all documents in the current queryset.

This method allows for updating document permissions in bulk for all documents matching the current queryset filters.

Parameters:
  • permissions (dict[str, Any] | None) – Permissions object defining user and group permissions.

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

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

Returns:

The current queryset for method chaining.

Return type:

Self

Examples

>>> # Set owner to user 2 for all documents with "invoice" in title
>>> client.documents().title("invoice", exact=False).set_permissions(owner_id=2)
>>>
>>> # Set complex permissions
>>> permissions = {
...     "view": {"users": [1, 2], "groups": [1]},
...     "change": {"users": [1], "groups": []}
... }
>>> client.documents().tag_name("confidential").set_permissions(
...     permissions=permissions,
...     owner_id=1,
...     merge=True
... )
storage_path(value=None, *, exact=True, case_insensitive=True, **kwargs)[source]

Filter documents by storage path.

This method provides a flexible interface for filtering documents by storage path, supporting filtering by ID or name, with options for exact or partial matching.

Any number of filter arguments can be provided, but at least one must be specified.

Parameters:
  • value (int | str | None) – The storage path ID or name to filter by.

  • exact (bool) – If True, match the exact value, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching for string values.

  • **kwargs (Any) – Additional filters (id, name).

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Raises:
  • ValueError – If no valid filters are provided.

  • TypeError – If value is not an int or str.

Examples

>>> # Filter by ID
>>> client.documents().storage_path(1)
>>> client.documents().storage_path(id=1)
>>>
>>> # Filter by name
>>> client.documents().storage_path("Invoices")
>>> client.documents().storage_path(name="Invoices")
>>>
>>> # Filter by name (partial match)
>>> client.documents().storage_path("Tax", exact=False)
>>>
>>> # Filter by ID and name
>>> client.documents().storage_path(1, name="Invoices")
storage_path_id(storage_path_id)[source]

Filter documents by storage path ID.

Parameters:

storage_path_id (int) – The storage path ID to filter by.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Filter documents with storage path ID 2
>>> docs = client.documents().storage_path_id(2)
storage_path_name(name, *, exact=True, case_insensitive=True)[source]

Filter documents by storage path name.

Parameters:
  • name (str) – The storage path name to filter by.

  • exact (bool) – If True, match the exact name, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Exact match (default)
>>> docs = client.documents().storage_path_name("Tax Documents")
>>>
>>> # Contains match
>>> docs = client.documents().storage_path_name("Tax", exact=False)
tag_id(tag_id)[source]

Filter documents that have the specified tag ID(s).

Parameters:

tag_id (int | list[int]) – A single tag ID or list of tag IDs.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Filter by a single tag ID
>>> docs = client.documents().tag_id(5)
>>>
>>> # Filter by multiple tag IDs
>>> docs = client.documents().tag_id([5, 7, 9])
tag_name(tag_name, *, exact=True, case_insensitive=True)[source]

Filter documents that have a tag with the specified name.

Parameters:
  • tag_name (str) – The name of the tag to filter by.

  • exact (bool) – If True, match the exact tag name, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Exact match (default)
>>> docs = client.documents().tag_name("Tax")
>>>
>>> # Contains match
>>> docs = client.documents().tag_name("invoice", exact=False)
>>>
>>> # Case-sensitive match
>>> docs = client.documents().tag_name("Receipt", case_insensitive=False)
title(title, *, exact=True, case_insensitive=True)[source]

Filter documents by title.

Parameters:
  • title (str) – The document title to filter by.

  • exact (bool) – If True, match the exact title, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Exact match (default)
>>> docs = client.documents().title("Electric Bill March 2023")
>>>
>>> # Contains match
>>> docs = client.documents().title("invoice", exact=False)
update(*, correspondent=None, document_type=None, storage_path=None, owner=None)[source]

Perform bulk updates on all documents in the current queryset.

This method allows for updating multiple document metadata fields in a single API call for all documents matching the current queryset filters.

Parameters:
  • correspondent (Correspondent | int | None) – Set correspondent for all documents. Can be a Correspondent object or ID.

  • document_type (DocumentType | int | None) – Set document type for all documents. Can be a DocumentType object or ID.

  • storage_path (StoragePath | int | None) – Set storage path for all documents. Can be a StoragePath object or ID.

  • owner (int | None) – Owner ID to assign to all documents.

Returns:

The current queryset for method chaining.

Return type:

Self

Examples

>>> # Update correspondent for all invoices
>>> client.documents().title("invoice", exact=False).update(
...     correspondent=5,
...     document_type=3
... )
>>>
>>> # Set owner for documents without an owner
>>> client.documents().filter(owner__isnull=True).update(owner=1)
user_can_change(value)[source]

Filter documents by user change permission.

This filter is useful for finding documents that the current authenticated user has permission to modify.

Parameters:

value (bool) – True to filter documents the user can change, False for those they cannot.

Return type:

Self

Returns:

Filtered DocumentQuerySet.

Examples

>>> # Find documents the current user can change
>>> docs = client.documents().user_can_change(True)
>>>
>>> # Find documents the current user cannot change
>>> docs = client.documents().user_can_change(False)
resource: DocumentResource
class paperap.models.CorrespondentQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[Correspondent], HasOwner, HasDocumentCount, SupportsBulkActions

QuerySet for Paperless-ngx correspondents with specialized filtering methods.

Extends StandardQuerySet to provide correspondent-specific filtering capabilities, including filtering by name, matching algorithm, and other correspondent attributes.

Inherits document counting capabilities from HasDocumentCount and owner-related filtering from HasOwner.

Examples

Get all correspondents:
>>> correspondents = client.correspondents()
Filter by name:
>>> electric = client.correspondents().name("Electric Company")
Find correspondents with case-insensitive matching:
>>> insensitive = client.correspondents().case_insensitive(True)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

case_insensitive(insensitive=True)[source]

Filter correspondents by case sensitivity setting.

Paperless-ngx allows correspondents to have case-sensitive or case-insensitive matching. This method filters correspondents based on that setting.

Parameters:

insensitive (bool) – If True, get correspondents with case-insensitive matching. If False, get correspondents with case-sensitive matching.

Return type:

Self

Returns:

Filtered CorrespondentQuerySet.

match(match, *, exact=True, case_insensitive=True)[source]

Filter correspondents by their match pattern.

The match pattern is the text pattern used by Paperless-ngx to automatically assign documents to this correspondent.

Parameters:
  • match (str) – The match pattern to filter by.

  • exact (bool) – If True, match the exact pattern, otherwise use contains.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

Filtered CorrespondentQuerySet.

Examples

Find correspondents with match pattern containing “invoice”:
>>> invoice_matchers = client.correspondents().match("invoice", exact=False)
matching_algorithm(value)[source]

Filter correspondents by their matching algorithm.

Paperless-ngx supports different algorithms for matching documents to correspondents. This method filters correspondents by the algorithm they use.

Parameters:

value (int) – The matching algorithm ID to filter by. Common values include: 1: Any word 2: All words 3: Exact match 4: Regular expression 5: Fuzzy match 6: Auto

Return type:

Self

Returns:

Filtered CorrespondentQuerySet.

name(value, *, exact=True, case_insensitive=True)[source]

Filter correspondents by name.

Parameters:
  • value (str) – The correspondent name to filter by.

  • exact (bool) – If True, match the exact name, otherwise use contains.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

Filtered CorrespondentQuerySet.

Examples

Find correspondents with exact name:
>>> exact_match = client.correspondents().name("Electric Company")
Find correspondents with name containing “electric”:
>>> contains = client.correspondents().name("electric", exact=False)
slug(value, *, exact=True, case_insensitive=True)[source]

Filter correspondents by slug.

Slugs are URL-friendly versions of the correspondent name used in the Paperless-ngx web interface and API. This method filters correspondents based on their slug value.

Parameters:
  • value (str) – The slug to filter by.

  • exact (bool) – If True, match the exact slug, otherwise use contains.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

Filtered CorrespondentQuerySet.

Examples

Find correspondent with slug “electric-company”:
>>> electric = client.correspondents().slug("electric-company")
user_can_change(value=True)[source]

Filter correspondents by user change permission.

In Paperless-ngx, some correspondents may be restricted from modification by certain users based on permissions. This method filters correspondents based on whether the current user can change them.

Parameters:

value (bool) – If True, get correspondents that can be changed by the current user. If False, get correspondents that cannot be changed by the current user.

Return type:

Self

Returns:

Filtered CorrespondentQuerySet.

class paperap.models.TagQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[Tag], HasStandard, SupportsBulkActions

Implement specialized filtering methods for Paperless-ngx tags.

Extends StandardQuerySet to provide tag-specific filtering capabilities, including filtering by color, matching algorithm, inbox status, and other tag-specific attributes.

The TagQuerySet provides a fluent interface for building complex queries against tag resources in the Paperless-ngx API.

Examples

Get all inbox tags:
>>> inbox_tags = client.tags.all().is_inbox_tag()
Find tags with a specific color:
>>> red_tags = client.tags.all().colour("#ff0000")
Find tags that can be changed by the user:
>>> editable_tags = client.tags.all().user_can_change()
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

case_insensitive(value=True)[source]

Filter tags by case insensitivity setting.

Filters tags based on whether their matching is case insensitive or not. This affects how Paperless-ngx performs automatic tag assignment.

Parameters:

value (bool) – If True, returns tags configured for case-insensitive matching. If False, returns tags configured for case-sensitive matching. Defaults to True.

Return type:

Self

Returns:

A filtered TagQuerySet containing only tags with the specified case sensitivity setting.

Examples

Find case-insensitive tags:
>>> insensitive_tags = client.tags.all().case_insensitive()
Find case-sensitive tags:
>>> sensitive_tags = client.tags.all().case_insensitive(False)
colour(value, *, exact=True, case_insensitive=True)[source]

Filter tags by color.

Allows filtering tags based on their color attribute. The color can be specified as either a string (e.g., “#ff0000” for red) or an integer representation.

Parameters:
  • value (str | int) – The color to filter by (string or integer).

  • exact (bool) – If True, match the exact color, otherwise use contains matching. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching (for string values). Defaults to True.

Return type:

Self

Returns:

A filtered TagQuerySet containing only tags with matching colors.

Examples

Find tags with red color:
>>> red_tags = client.tags.all().colour("#ff0000")
Find tags with colors containing “blue” (case insensitive):
>>> blue_tags = client.tags.all().colour("blue", exact=False)
is_inbox_tag(value=True)[source]

Filter tags by inbox status.

In Paperless-ngx, inbox tags are special tags that mark documents as needing attention or processing. This method filters tags based on whether they are designated as inbox tags.

Parameters:

value (bool) – If True, returns only inbox tags. If False, returns only non-inbox tags. Defaults to True.

Return type:

Self

Returns:

A filtered TagQuerySet containing only tags with the specified inbox status.

Examples

Get all inbox tags:
>>> inbox_tags = client.tags.all().is_inbox_tag()
Get all non-inbox tags:
>>> regular_tags = client.tags.all().is_inbox_tag(False)
match(value, *, exact=True, case_insensitive=True)[source]

Filter tags by match value.

Filters tags based on their match pattern, which is used by Paperless-ngx for automatic tag assignment.

Parameters:
  • value (str) – The match pattern value to filter by.

  • exact (bool) – If True, match the exact value, otherwise use contains matching. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

A filtered TagQuerySet containing only tags with matching patterns.

Examples

Find tags that match “invoice”:
>>> invoice_tags = client.tags.all().match("invoice")
Find tags with match patterns containing “tax”:
>>> tax_tags = client.tags.all().match("tax", exact=False)
matching_algorithm(value)[source]

Filter tags by matching algorithm.

Filters tags based on the algorithm used for automatic tag assignment. Paperless-ngx supports different matching algorithms like exact, regex, fuzzy matching, etc., each represented by an integer value.

Parameters:

value (int) – The matching algorithm ID to filter by. Common values include: 1 (any), 2 (all), 3 (literal), 4 (regex), 5 (fuzzy match).

Return type:

Self

Returns:

A filtered TagQuerySet containing only tags using the specified matching algorithm.

Examples

Find tags using regex matching:
>>> regex_tags = client.tags.all().matching_algorithm(4)
user_can_change(value=True)[source]

Filter tags by user change permission.

Filters tags based on whether the current authenticated user has permission to modify them. This is useful for identifying which tags can be edited in user interfaces.

Parameters:

value (bool) – If True, returns tags that can be changed by the current user. If False, returns tags that cannot be changed by the current user. Defaults to True.

Return type:

Self

Returns:

A filtered TagQuerySet containing only tags with the specified change permission.

Examples

Get tags the current user can modify:
>>> editable_tags = client.tags.all().user_can_change()
Get tags the current user cannot modify:
>>> readonly_tags = client.tags.all().user_can_change(False)
class paperap.models.DocumentTypeQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[DocumentType], HasOwner, HasDocumentCount, SupportsBulkActions

Implement specialized filtering methods for Paperless-ngx document types.

Extends StandardQuerySet to provide document type-specific filtering capabilities, including filtering by name, slug, match pattern, and other document type attributes.

Inherits:

StandardQuerySet: Base queryset functionality for standard models HasOwner: Adds owner filtering capabilities HasDocumentCount: Adds document count filtering capabilities

Returns:

A chainable DocumentTypeQuerySet instance

Return type:

Self

Examples

Get all document types:
>>> all_types = client.document_types.all()
Filter by name:
>>> invoices = client.document_types.filter(name__contains="invoice")
Chain multiple filters:
>>> results = client.document_types.name("Tax").matching_algorithm(1)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

case_insensitive(value=True)[source]

Filter document types by case sensitivity setting.

Filter document types based on whether their matching is case insensitive or case sensitive.

Parameters:

value (bool) – If True, get document types with case insensitive matching. If False, get document types with case sensitive matching. Defaults to True.

Return type:

Self

Returns:

Filtered DocumentTypeQuerySet with case sensitivity filter applied

Examples

Find document types with case insensitive matching:
>>> insensitive_types = client.document_types.case_insensitive()
Find document types with case sensitive matching:
>>> sensitive_types = client.document_types.case_insensitive(False)
match(value, *, exact=True, case_insensitive=True)[source]

Filter document types by match pattern.

The match pattern is used by Paperless-ngx to automatically assign document types to documents based on their content or filename.

Parameters:
  • value (str) – The pattern to search for in match

  • exact (bool) – If True, match the exact pattern, otherwise use contains. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

Filtered DocumentTypeQuerySet with match pattern filter applied

Examples

Find document types that match “invoice”:
>>> invoice_types = client.document_types.match("invoice")
Find document types with match patterns containing “tax”:
>>> tax_types = client.document_types.match("tax", exact=False)
matching_algorithm(value)[source]

Filter document types by matching algorithm.

Paperless-ngx supports different algorithms for matching document types: - 1: Any word (default) - 2: All words - 3: Exact match - 4: Regular expression - 5: Fuzzy match - 6: Auto

Parameters:

value (int) – The matching algorithm ID (1-6)

Return type:

Self

Returns:

Filtered DocumentTypeQuerySet with matching algorithm filter applied

Examples

Find document types using regex matching:
>>> regex_types = client.document_types.matching_algorithm(4)
Find document types using fuzzy matching:
>>> fuzzy_types = client.document_types.matching_algorithm(5)
name(value, *, exact=True, case_insensitive=True)[source]

Filter document types by name.

Parameters:
  • value (str) – The document type name to filter by

  • exact (bool) – If True, match the exact name, otherwise use contains. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

Filtered DocumentTypeQuerySet with name filter applied

Examples

Exact match (default):
>>> invoice_types = client.document_types.name("Invoice")
Contains match:
>>> tax_types = client.document_types.name("tax", exact=False)
Case sensitive match:
>>> types = client.document_types.name("TAX", case_insensitive=False)
slug(value, *, exact=True, case_insensitive=True)[source]

Filter document types by slug.

The slug is a URL-friendly version of the document type name, typically lowercase with hyphens instead of spaces.

Parameters:
  • value (str) – The slug to filter by

  • exact (bool) – If True, match the exact slug, otherwise use contains. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

Filtered DocumentTypeQuerySet with slug filter applied

Examples

Exact match:
>>> invoice_types = client.document_types.slug("invoice-2023")
Contains match:
>>> types = client.document_types.slug("invoice", exact=False)
user_can_change(value=True)[source]

Filter document types by user change permission.

Filter document types based on whether regular users (non-superusers) have permission to modify them.

Parameters:

value (bool) – If True, get document types where users can change. If False, get document types where only superusers can change. Defaults to True.

Return type:

Self

Returns:

Filtered DocumentTypeQuerySet with user permission filter applied

Examples

Find document types that regular users can modify:
>>> user_editable = client.document_types.user_can_change()
Find document types that only superusers can modify:
>>> admin_only = client.document_types.user_can_change(False)
class paperap.models.StoragePathQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[StoragePath], HasStandard

QuerySet for Paperless-ngx storage paths with specialized filtering methods.

Extends StandardQuerySet to provide storage path-specific filtering capabilities, including filtering by path value, match criteria, matching algorithm, and permission settings. This queryset enables efficient querying and filtering of storage path objects from the Paperless-ngx API.

Examples

Get all storage paths:
>>> all_paths = client.storage_paths.all()
Filter by path:
>>> tax_paths = client.storage_paths.path("/documents/taxes/")
Filter by matching algorithm:
>>> auto_paths = client.storage_paths.matching_algorithm(1)  # 1 = Auto
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

case_insensitive(insensitive=True)[source]

Filter storage paths by their case sensitivity setting.

Filter storage paths based on whether they use case-insensitive matching for document routing.

Parameters:

insensitive (bool) – If True, return storage paths configured for case-insensitive matching. If False, return paths with case-sensitive matching. Defaults to True.

Return type:

Self

Returns:

A filtered StoragePathQuerySet containing only storage paths with the specified case sensitivity setting.

Examples

Find case-insensitive paths:
>>> insensitive_paths = client.storage_paths.case_insensitive()
Find case-sensitive paths:
>>> sensitive_paths = client.storage_paths.case_insensitive(False)
match(value, *, exact=True)[source]

Filter storage paths by their match pattern value.

Filter storage paths based on the match pattern used for automatic document routing in Paperless-ngx.

Parameters:
  • value (str) – The match pattern string to filter by.

  • exact (bool) – If True, match the exact pattern string. If False, match patterns containing the value string. Defaults to True.

Return type:

Self

Returns:

A filtered StoragePathQuerySet containing only matching storage paths.

Examples

Find paths with exact match pattern:
>>> invoice_paths = client.storage_paths.match("invoice")
Find paths with match patterns containing “tax”:
>>> tax_paths = client.storage_paths.match("tax", exact=False)
matching_algorithm(value)[source]

Filter storage paths by their matching algorithm.

Filter storage paths based on the algorithm used for matching documents to storage paths in Paperless-ngx.

Parameters:

value (int) – The matching algorithm ID to filter by. Common values are: 1: Auto (let Paperless decide) 2: Exact (exact string matching) 3: Regular expression 4: Fuzzy match

Return type:

Self

Returns:

A filtered StoragePathQuerySet containing only storage paths using the specified matching algorithm.

Examples

Find paths using regular expressions:
>>> regex_paths = client.storage_paths.matching_algorithm(3)
path(value, *, exact=True, case_insensitive=True)[source]

Filter storage paths by their actual path value.

Parameters:
  • value (str) – The path string to filter by.

  • exact (bool) – If True, match the exact path string. If False, match paths containing the value string. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

A filtered StoragePathQuerySet containing only matching storage paths.

Examples

Find exact path match:
>>> tax_paths = client.storage_paths.path("/documents/taxes/")
Find paths containing “invoice” (case insensitive):
>>> invoice_paths = client.storage_paths.path("invoice", exact=False)
user_can_change(can_change=True)[source]

Filter storage paths by user modification permissions.

Filter storage paths based on whether the current user has permission to modify them in the Paperless-ngx system.

Parameters:

can_change (bool) – If True, return storage paths that the current user can modify. If False, return paths that the user cannot modify. Defaults to True.

Return type:

Self

Returns:

A filtered StoragePathQuerySet containing only storage paths with the specified permission setting.

Examples

Find paths the current user can modify:
>>> editable_paths = client.storage_paths.user_can_change()
Find paths the current user cannot modify:
>>> readonly_paths = client.storage_paths.user_can_change(False)
class paperap.models.CustomFieldQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[CustomField], HasDocumentCount

Manage and filter custom fields from Paperless-ngx.

Extends StandardQuerySet to provide specialized filtering methods for custom fields. Allows filtering by name, data type, and extra data, making it easier to find and manage custom fields.

The QuerySet is lazy-loaded, meaning API requests are only made when the results are actually needed (when iterating, counting, etc.).

Inherits all attributes from StandardQuerySet and HasDocumentCount.

Examples

Get all string-type custom fields:
>>> string_fields = client.custom_fields().data_type("string")
Find custom fields with a specific name pattern:
>>> invoice_fields = client.custom_fields().name("invoice", exact=False)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

data_type(value, *, exact=True, case_insensitive=True)[source]

Filter custom fields by data type.

Filter the queryset to include only custom fields with the specified data type. Paperless-ngx supports several data types for custom fields, including string, integer, boolean, date, etc.

Parameters:
  • value (str) – The data type to filter by (e.g., “string”, “integer”, “boolean”, “date”).

  • exact (bool) – If True, match the exact data type; if False, use contains matching. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

A filtered CustomFieldQuerySet containing only custom fields with matching data types.

Examples

Get all date-type custom fields:
>>> date_fields = client.custom_fields().data_type("date")
Get all numeric fields (integer or float):
>>> numeric_fields = client.custom_fields().data_type("int", exact=False)
extra_data(key, value)[source]

Filter custom fields by a key-value pair in extra_data.

Filter custom fields based on specific values within the extra_data JSON structure. Custom fields in Paperless-ngx can have additional configuration stored in this extra_data field.

Parameters:
  • key (str) – The key in extra_data to filter by. This can be a nested key using Django’s double-underscore syntax for JSON fields.

  • value (Any) – The value to filter by. Can be any JSON-compatible value (string, number, boolean, etc.).

Return type:

Self

Returns:

A filtered CustomFieldQuerySet containing only custom fields with matching extra_data values.

Examples

Find custom fields with specific configuration:
>>> fields = client.custom_fields().extra_data("format", "currency")
Find fields with nested configuration:
>>> fields = client.custom_fields().extra_data("options__default", True)
name(value, *, exact=True, case_insensitive=True)[source]

Filter custom fields by name.

Filter the queryset to include only custom fields whose names match the specified value, with options for exact matching and case sensitivity.

Parameters:
  • value (str) – The custom field name to filter by.

  • exact (bool) – If True, match the exact name; if False, use contains matching. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

A filtered CustomFieldQuerySet containing only matching custom fields.

Examples

Find fields with exact name “Invoice Number”:
>>> invoice_fields = client.custom_fields().name("Invoice Number")
Find fields containing “date” (case-insensitive):
>>> date_fields = client.custom_fields().name("date", exact=False)
class paperap.models.UserQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[User]

Provide a lazy-loaded, chainable query interface for Paperless-NGX users.

Extends StandardQuerySet to provide user-specific filtering methods, allowing for efficient querying of user resources from the Paperless-NGX API. Supports filtering by username, email, name, permissions, and various user status flags.

All query methods return a new queryset instance, allowing for method chaining to build complex queries that are only executed when the results are accessed.

Examples

Find active staff users:
>>> staff_users = client.users.filter().staff().active()
Find users with a specific permission:
>>> admin_users = client.users.filter().has_permission("admin")
Find users by email domain:
>>> company_users = client.users.filter().email("@company.com", exact=False)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

active(value=True)[source]

Filter users by active status.

Inactive users cannot log in to Paperless-NGX.

Parameters:

value (bool) – If True, return active users; if False, return inactive users.

Return type:

Self

Returns:

A filtered UserQuerySet containing only users matching the active status.

Examples

Get only active users:
>>> active_users = client.users.filter().active()
Get inactive users:
>>> inactive_users = client.users.filter().active(False)
email(value, *, exact=True, case_insensitive=True)[source]

Filter users by email address.

Parameters:
  • value (str) – The email address to filter by.

  • exact (bool) – If True, match the exact email; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered UserQuerySet containing only users matching the email criteria.

Examples

Find users with a specific domain:
>>> gmail_users = client.users.filter().email("@gmail.com", exact=False)
first_name(value, *, exact=True, case_insensitive=True)[source]

Filter users by first name.

Parameters:
  • value (str) – The first name to filter by.

  • exact (bool) – If True, match the exact first name; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered UserQuerySet containing only users matching the first name criteria.

has_inherited_permission(value)[source]

Filter users by inherited permission.

Filter users who have the specified permission through any means, including direct assignment, group membership, or superuser status.

Parameters:

value (str) – The permission string to filter by (e.g., “documents.view_document”).

Return type:

Self

Returns:

A filtered UserQuerySet containing only users with the specified inherited permission.

Examples

Find users who can add documents:
>>> can_add = client.users.filter().has_inherited_permission("documents.add_document")
has_permission(value)[source]

Filter users by direct permission assignment.

Filter users who have been directly assigned the specified permission through their groups. Does not include permissions inherited from other sources.

Parameters:

value (str) – The permission string to filter by (e.g., “documents.view_document”).

Return type:

Self

Returns:

A filtered UserQuerySet containing only users with the specified permission.

Examples

Find users who can view documents:
>>> viewers = client.users.filter().has_permission("documents.view_document")
in_group(value)[source]

Filter users by group membership.

Parameters:

value (int) – The group ID to filter by.

Return type:

Self

Returns:

A filtered UserQuerySet containing only users who are members of the specified group.

Examples

Find all users in the ‘Accounting’ group (ID: 5):
>>> accounting_users = client.users.filter().in_group(5)
last_name(value, *, exact=True, case_insensitive=True)[source]

Filter users by last name.

Parameters:
  • value (str) – The last name to filter by.

  • exact (bool) – If True, match the exact last name; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered UserQuerySet containing only users matching the last name criteria.

staff(value=True)[source]

Filter users by staff status.

Staff users typically have additional permissions in Paperless-NGX.

Parameters:

value (bool) – If True, return users that are staff members; if False, return non-staff users.

Return type:

Self

Returns:

A filtered UserQuerySet containing only users matching the staff status.

Examples

Get all staff users:
>>> staff = client.users.filter().staff()
Get all non-staff users:
>>> regular_users = client.users.filter().staff(False)
superuser(value=True)[source]

Filter users by superuser status.

Superusers have all permissions in Paperless-NGX regardless of their assigned permissions or groups.

Parameters:

value (bool) – If True, return superusers; if False, return non-superusers.

Return type:

Self

Returns:

A filtered UserQuerySet containing only users matching the superuser status.

Examples

Get only superusers:
>>> admins = client.users.filter().superuser()
Get non-superusers:
>>> regular_users = client.users.filter().superuser(False)
username(value, *, exact=True, case_insensitive=True)[source]

Filter users by username.

Parameters:
  • value (str) – The username to filter by.

  • exact (bool) – If True, match the exact username; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered UserQuerySet containing only users matching the username criteria.

Examples

Find user with exact username:
>>> user = client.users.filter().username("admin")
Find users with ‘admin’ in their username:
>>> admin_users = client.users.filter().username("admin", exact=False)
class paperap.models.GroupQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[Group]

Provide a lazy-loaded, chainable query interface for Paperless-NGX user groups.

Extends StandardQuerySet to provide group-specific filtering methods, allowing for efficient querying of group resources from the Paperless-NGX API. Supports filtering by name and permissions.

All query methods return a new queryset instance, allowing for method chaining to build complex queries that are only executed when the results are accessed.

Examples

Find groups with a specific permission:
>>> admin_groups = client.groups.filter().has_permission("admin.add_user")
Find groups by name:
>>> finance_groups = client.groups.filter().name("finance", exact=False)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

has_permission(value)[source]

Filter groups by assigned permission.

Parameters:

value (str) – The permission string to filter by (e.g., “documents.view_document”).

Return type:

Self

Returns:

A filtered GroupQuerySet containing only groups with the specified permission.

Examples

Find groups that can delete documents:
>>> delete_groups = client.groups.filter().has_permission("documents.delete_document")
name(value, *, exact=True, case_insensitive=True)[source]

Filter groups by name.

Parameters:
  • value (str) – The name to filter by.

  • exact (bool) – If True, match the exact name; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered GroupQuerySet containing only groups matching the name criteria.

Examples

Find the ‘Administrators’ group:
>>> admin_group = client.groups.filter().name("Administrators")
Find all groups with ‘admin’ in their name:
>>> admin_groups = client.groups.filter().name("admin", exact=False)
class paperap.models.TaskQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[Task]

Provide a lazy-loaded, chainable query interface for Paperless-NGX tasks.

Extends StandardQuerySet to provide specialized filtering methods for task-specific attributes like task_id, status, and result. Enables efficient querying of the Paperless-NGX task API endpoint.

The queryset is lazy-loaded, meaning API requests are only made when data is actually needed (when iterating, slicing, or calling terminal methods like count() or get()).

Examples

Get all tasks:
>>> all_tasks = client.tasks.all()
Get a specific task by ID:
>>> task = client.tasks.get(123)
Filter tasks by status:
>>> pending = client.tasks.all().status("PENDING")
Chain filters:
>>> document_tasks = client.tasks.all().type("document").status("SUCCESS")
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

acknowledged(value)[source]

Filter tasks by acknowledged status.

Acknowledged tasks are those that have been marked as seen/reviewed by a user. This is particularly useful for filtering out tasks that need attention.

Parameters:

value (bool) – True to get only acknowledged tasks, False to get only unacknowledged tasks.

Return type:

Self

Returns:

A filtered queryset containing only tasks with the matching acknowledged status.

Examples

Get all unacknowledged tasks that need attention:
>>> needs_attention = client.tasks.all().acknowledged(False)
Get all acknowledged tasks:
>>> reviewed = client.tasks.all().acknowledged(True)
date_done(value)[source]

Filter tasks by completion date.

Parameters:

value (str | None) – The date_done to filter by, in ISO format (YYYY-MM-DDTHH:MM:SS.sssZ). Pass None to find tasks that haven’t completed.

Return type:

Self

Returns:

A filtered queryset containing only tasks with the matching completion date.

Examples

Tasks completed on a specific date:
>>> completed = client.tasks.all().date_done("2023-04-15T00:00:00Z")
Tasks that haven’t completed yet:
>>> pending = client.tasks.all().date_done(None)
related_document(value)[source]

Filter tasks by related document ID.

Many tasks in Paperless-NGX are associated with specific documents. This method allows filtering tasks by their related document ID(s).

Parameters:

value (int | list[int]) – Either a single document ID or a list of document IDs to filter by.

Return type:

Self

Returns:

A filtered queryset containing only tasks related to the specified document(s).

Examples

Get all tasks related to document #42:
>>> doc_tasks = client.tasks.all().related_document(42)
Get all tasks related to a set of documents:
>>> batch_tasks = client.tasks.all().related_document([42, 43, 44])
result(value, *, exact=True, case_insensitive=True)[source]

Filter tasks by result.

The result field typically contains the output of the task, which may be a document ID, error message, or other task-specific data.

Parameters:
  • value (str | None) – The result to filter by. Pass None to find tasks with no result.

  • exact (bool) – If True, match the exact result, otherwise use contains. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

A filtered queryset containing only tasks with the matching result.

Examples

Find tasks with a specific document ID in the result:
>>> doc_tasks = client.tasks.all().result("42")
Find tasks with no result yet:
>>> no_result = client.tasks.all().result(None)
Find tasks with error messages:
>>> error_tasks = client.tasks.all().result("error", exact=False)
status(value, *, exact=True, case_insensitive=True)[source]

Filter tasks by status.

Common status values include ‘PENDING’, ‘STARTED’, ‘SUCCESS’, ‘FAILURE’, ‘RETRY’, etc.

Parameters:
  • value (str) – The status to filter by.

  • exact (bool) – If True, match the exact status, otherwise use contains. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

A filtered queryset containing only tasks with the matching status.

Examples

Get all successful tasks:
>>> successful = client.tasks.all().status("SUCCESS")
Get all failed tasks:
>>> failed = client.tasks.all().status("FAILURE")
Get all in-progress tasks:
>>> in_progress = client.tasks.all().status("STARTED")
task_file_name(value, *, exact=True, case_insensitive=True)[source]

Filter tasks by task_file_name.

Parameters:
  • value (str) – The task_file_name to filter by.

  • exact (bool) – If True, match the exact task_file_name, otherwise use contains. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

A filtered queryset containing only tasks with the matching task_file_name.

Examples

Exact match, case insensitive (default):
>>> pdf_tasks = client.tasks.all().task_file_name("document.pdf")
Contains match, case sensitive:
>>> pdf_tasks = client.tasks.all().task_file_name("pdf", exact=False, case_insensitive=False)
task_id(value)[source]

Filter tasks by task_id.

Parameters:

value (int) – The task_id to filter by.

Return type:

Self

Returns:

A filtered queryset containing only tasks with the specified task_id.

Examples

Get task with specific task_id:
>>> task = client.tasks.all().task_id(12345).first()
type(value, *, exact=True, case_insensitive=True)[source]

Filter tasks by type.

Task types typically include ‘document’, ‘mail’, ‘consumption’, etc.

Parameters:
  • value (str) – The task type to filter by.

  • exact (bool) – If True, match the exact type, otherwise use contains. Defaults to True.

  • case_insensitive (bool) – If True, ignore case when matching. Defaults to True.

Return type:

Self

Returns:

A filtered queryset containing only tasks with the matching type.

Examples

Get all document processing tasks:
>>> doc_tasks = client.tasks.all().type("document")
Get all mail-related tasks (contains match):
>>> mail_tasks = client.tasks.all().type("mail", exact=False)
class paperap.models.SavedViewQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[SavedView], HasOwner

QuerySet for Paperless-ngx saved views with specialized filtering methods.

Extends StandardQuerySet to provide saved view-specific filtering methods, including filtering by name, visibility settings, sort options, and display preferences. Allows for precise querying of saved views based on their attributes and configuration.

Examples

>>> # Get all saved views shown in the sidebar
>>> sidebar_views = client.saved_views.filter().show_in_sidebar()
>>>
>>> # Get dashboard views with large page sizes
>>> large_views = client.saved_views.filter().show_on_dashboard().page_size_over(50)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

display_mode(mode)[source]

Filter saved views by display mode.

Parameters:

mode (str) – The display mode to filter by (e.g., “list”, “grid”, “details”).

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Find views using list display mode
>>> list_views = client.saved_views.filter().display_mode("list")
>>>
>>> # Find views using grid display mode
>>> grid_views = client.saved_views.filter().display_mode("grid")
name(value, *, exact=True, case_insensitive=True)[source]

Filter saved views by name.

Parameters:
  • value (str) – The saved view name to filter by.

  • exact (bool) – If True, match the exact name, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Find views with exact name match
>>> tax_views = client.saved_views.filter().name("Tax Documents")
>>>
>>> # Find views containing "invoice" (case-insensitive)
>>> invoice_views = client.saved_views.filter().name("invoice", exact=False)
page_size(size)[source]

Filter saved views by exact page size.

Parameters:

size (int) – The exact number of items per page to filter by.

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Find views with 25 items per page
>>> standard_views = client.saved_views.filter().page_size(25)
page_size_between(min_size, max_size)[source]

Filter saved views by page size within a specified range.

Parameters:
  • min_size (int) – The minimum number of items per page (inclusive).

  • max_size (int) – The maximum number of items per page (inclusive).

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Find views with between 20 and 50 items per page
>>> medium_views = client.saved_views.filter().page_size_between(20, 50)
page_size_over(size)[source]

Filter saved views by page size over a specified limit.

Parameters:

size (int) – The minimum number of items per page (exclusive).

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Find views with more than 50 items per page
>>> large_views = client.saved_views.filter().page_size_over(50)
page_size_under(size)[source]

Filter saved views by page size under a specified limit.

Parameters:

size (int) – The maximum number of items per page (exclusive).

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Find views with fewer than 20 items per page
>>> small_views = client.saved_views.filter().page_size_under(20)
show_in_sidebar(show=True)[source]

Filter saved views by sidebar visibility.

Parameters:

show (bool) – If True, get views shown in sidebar, otherwise those hidden.

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Get views shown in sidebar
>>> sidebar_views = client.saved_views.filter().show_in_sidebar()
>>>
>>> # Get views not shown in sidebar
>>> hidden_views = client.saved_views.filter().show_in_sidebar(False)
show_on_dashboard(show=True)[source]

Filter saved views by dashboard visibility.

Parameters:

show (bool) – If True, get views shown on dashboard, otherwise those hidden.

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Get views shown on dashboard
>>> dashboard_views = client.saved_views.filter().show_on_dashboard()
>>>
>>> # Get views not shown on dashboard
>>> non_dashboard_views = client.saved_views.filter().show_on_dashboard(False)
sort_field(field, *, exact=True, case_insensitive=True)[source]

Filter saved views by sort field.

Parameters:
  • field (str) – The field to sort by (e.g., “created”, “title”).

  • exact (bool) – If True, match the exact field name, otherwise use contains.

  • case_insensitive (bool) – If True, perform case-insensitive matching.

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Find views sorted by created date
>>> date_sorted = client.saved_views.filter().sort_field("created")
>>>
>>> # Find views with sort fields containing "date"
>>> date_fields = client.saved_views.filter().sort_field("date", exact=False)
sort_reverse(reverse=True)[source]

Filter saved views by sort direction.

Parameters:

reverse (bool) – If True, get views sorted in reverse (descending) order, if False, get views sorted in normal (ascending) order.

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Get views with descending sort
>>> desc_views = client.saved_views.filter().sort_reverse()
>>>
>>> # Get views with ascending sort
>>> asc_views = client.saved_views.filter().sort_reverse(False)
user_can_change(can_change=True)[source]

Filter saved views by user change permissions.

Parameters:

can_change (bool) – If True, get views that can be changed by the current user, if False, get views that cannot be changed by the current user.

Returns:

Filtered SavedViewQuerySet.

Return type:

Self

Examples

>>> # Find views the current user can modify
>>> editable_views = client.saved_views.filter().user_can_change()
>>>
>>> # Find views the current user cannot modify
>>> readonly_views = client.saved_views.filter().user_can_change(False)
class paperap.models.UISettingsQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[UISettings]

Manage queries for UI settings in Paperless-NGX.

Extends StandardQuerySet to handle the singleton nature of UI settings, which always returns exactly one object containing all UI configuration. Unlike typical querysets that can return multiple objects, this queryset is specialized for the unique characteristics of the UI settings endpoint.

_result_cache

Cache of fetched UI settings objects.

Type:

list[UISettings] | None

_last_response

The last response received from the API.

Type:

ClientResponse | None

resource

The resource instance associated with the queryset.

Type:

Resource

filters

Dictionary of filters to apply to the API request.

Type:

dict[str, Any]

Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

count()[source]

Return the count of UI settings objects.

Overrides the standard count method to always return 1 because the UI settings endpoint in Paperless-NGX always returns exactly one object containing all UI configuration settings.

Returns:

Always returns 1, as there is only one UI settings object.

Return type:

Literal[1]

Example

`python settings_count = client.ui_settings().count() print(settings_count)  # Output: 1 `

has_permission(value)[source]

Filter UI settings by checking if a specific permission exists.

Creates a filtered queryset that checks whether a specific permission is included in the permissions list. This method is useful for determining if the current user has a particular permission in the Paperless-NGX system.

Parameters:

value (str) – The permission string to check for in the permissions list. Common permissions include “view_document”, “change_document”, etc.

Returns:

A new queryset filtered to include only settings with the specified permission.

Return type:

Self

Example

```python # Check if the current user has permission to add documents if client.ui_settings().has_permission(“add_document”).exists():

print(“User can add documents”)

else:

print(“User cannot add documents”)

```

class paperap.models.WorkflowQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[Workflow]

Specialized queryset for interacting with Paperless-NGX workflows.

Extends StandardQuerySet to provide workflow-specific filtering methods, making it easier to query workflows by attributes such as name, order, and enabled status. The queryset is lazy-loaded, meaning API requests are only made when data is actually needed.

Examples

Get all enabled workflows:
>>> enabled_workflows = client.workflows.filter(enabled=True)
>>> # Or using the specialized method
>>> enabled_workflows = client.workflows.enabled()
Filter workflows by name:
>>> tax_workflows = client.workflows.name("tax")
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

enabled(value=True)[source]

Filter workflows by their enabled status.

Parameters:

value (bool) – If True, return only enabled workflows; if False, return only disabled workflows.

Return type:

Self

Returns:

A filtered WorkflowQuerySet containing workflows with the specified enabled status.

Examples

Get all enabled workflows:
>>> active_workflows = client.workflows.enabled()
Get all disabled workflows:
>>> inactive_workflows = client.workflows.enabled(False)
name(value, *, exact=True, case_insensitive=True)[source]

Filter workflows by name.

Parameters:
  • value (str) – The workflow name to filter by.

  • exact (bool) – If True, match the exact name; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered WorkflowQuerySet containing matching workflows.

Examples

Find workflows with exact name:
>>> invoice_workflows = client.workflows.name("Invoice Processing")
Find workflows containing a string (case-insensitive):
>>> invoice_workflows = client.workflows.name("invoice", exact=False)
order(value)[source]

Filter workflows by their execution order.

Paperless-NGX workflows have an order value that determines their execution sequence. This method finds workflows with a specific order value.

Parameters:

value (int) – The order value to filter by.

Return type:

Self

Returns:

A filtered WorkflowQuerySet containing workflows with the specified order.

class paperap.models.WorkflowTriggerQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[WorkflowTrigger]

Specialized queryset for interacting with Paperless-NGX workflow triggers.

Extends StandardQuerySet to provide workflow trigger-specific filtering methods, making it easier to query triggers by attributes such as type and filter conditions. Workflow triggers define when a workflow should be executed, such as when a document is added with specific attributes or matches certain criteria.

Examples

Get all triggers of a specific type:
>>> consumption_triggers = client.workflow_triggers.type(1)  # Type 1 might be "document added"
Find triggers that look for specific tags:
>>> tax_triggers = client.workflow_triggers.has_tags(5)  # Tag ID 5 might be "Tax"
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

filter_filename(value, *, exact=True, case_insensitive=True)[source]

Filter workflow triggers by their filename filter condition.

Find workflow triggers that activate based on a document’s original filename matching specific criteria.

Parameters:
  • value (str) – The filename filter text to match.

  • exact (bool) – If True, match the exact filename; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered WorkflowTriggerQuerySet containing triggers with the specified filename filter.

Examples

Find triggers that look for documents with specific text in filenames:
>>> invoice_triggers = client.workflow_triggers.filter_filename("invoice", exact=False)
Find triggers that look for specific file types:
>>> pdf_triggers = client.workflow_triggers.filter_filename(".pdf", exact=False)
filter_mailrule(value, *, exact=True, case_insensitive=True)[source]

Filter workflow triggers by their mail rule filter condition.

Find workflow triggers that activate based on a document’s associated mail rule matching specific criteria.

Parameters:
  • value (str) – The mail rule filter text to match.

  • exact (bool) – If True, match the exact mail rule; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered WorkflowTriggerQuerySet containing triggers with the specified mail rule filter.

Examples

Find triggers that look for documents from a specific mail rule:
>>> vendor_mail_triggers = client.workflow_triggers.filter_mailrule("vendor@example.com")
Find triggers that look for documents from mail rules containing specific text:
>>> invoice_mail_triggers = client.workflow_triggers.filter_mailrule("invoice", exact=False)
filter_path(value, *, exact=True, case_insensitive=True)[source]

Filter workflow triggers by their path filter condition.

Find workflow triggers that activate based on a document’s source path matching specific criteria.

Parameters:
  • value (str) – The path filter text to match.

  • exact (bool) – If True, match the exact path; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered WorkflowTriggerQuerySet containing triggers with the specified path filter.

Examples

Find triggers that look for documents from a specific directory:
>>> inbox_triggers = client.workflow_triggers.filter_path("/inbox/")
Find triggers that look for documents from any path containing a string:
>>> invoice_triggers = client.workflow_triggers.filter_path("invoices", exact=False)
has_correspondent(value)[source]

Filter workflow triggers by their correspondent filter condition.

Find workflow triggers that activate based on a document having a specific correspondent.

Parameters:

value (int) – The correspondent ID to filter by.

Return type:

Self

Returns:

A filtered WorkflowTriggerQuerySet containing triggers with the specified correspondent filter.

Examples

Find triggers that look for documents from a specific correspondent:
>>> vendor_triggers = client.workflow_triggers.has_correspondent(3)
has_document_type(value)[source]

Filter workflow triggers by their document type filter condition.

Find workflow triggers that activate based on a document having a specific document type.

Parameters:

value (int) – The document type ID to filter by.

Return type:

Self

Returns:

A filtered WorkflowTriggerQuerySet containing triggers with the specified document type filter.

Examples

Find triggers that look for documents of a specific type:
>>> invoice_triggers = client.workflow_triggers.has_document_type(2)
has_tags(value)[source]

Filter workflow triggers by their tag filter condition.

Find workflow triggers that activate based on a document having specific tags. Can filter by a single tag ID or multiple tag IDs.

Parameters:

value (int | list[int]) – The tag ID or list of tag IDs to filter by.

Return type:

Self

Returns:

A filtered WorkflowTriggerQuerySet containing triggers with the specified tag filter.

Examples

Find triggers that look for documents with a specific tag:
>>> tax_triggers = client.workflow_triggers.has_tags(5)
Find triggers that look for documents with any of several tags:
>>> financial_triggers = client.workflow_triggers.has_tags([5, 8, 12])
type(value)[source]

Filter workflow triggers by their type.

Workflow triggers in Paperless-NGX have different types that determine when they activate (e.g., document added, document consumed, etc.).

Parameters:

value (int) – The trigger type ID to filter by.

Return type:

Self

Returns:

A filtered WorkflowTriggerQuerySet containing triggers of the specified type.

Examples

Find all triggers that activate when documents are consumed:
>>> consumption_triggers = client.workflow_triggers.type(1)  # Assuming 1 is consumption type
class paperap.models.WorkflowActionQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[WorkflowAction]

Specialized queryset for interacting with Paperless-NGX workflow actions.

Extends StandardQuerySet to provide workflow action-specific filtering methods, making it easier to query actions by attributes such as type and assigned metadata. Workflow actions define what happens when a workflow is triggered, such as assigning tags, correspondents, or document types to documents.

Examples

Get actions that assign a specific tag:
>>> tag_actions = client.workflow_actions.assign_tags(5)
Find actions that set a specific title:
>>> title_actions = client.workflow_actions.assign_title("Invoice")
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

assign_correspondent(value)[source]

Filter workflow actions by the correspondent they assign to documents.

Find workflow actions that assign a specific correspondent to documents when triggered.

Parameters:

value (int) – The correspondent ID to filter by.

Return type:

Self

Returns:

A filtered WorkflowActionQuerySet containing actions that assign the specified correspondent.

Examples

Find actions that assign a specific correspondent:
>>> vendor_actions = client.workflow_actions.assign_correspondent(3)
assign_document_type(value)[source]

Filter workflow actions by the document type they assign.

Find workflow actions that assign a specific document type to documents when triggered.

Parameters:

value (int) – The document type ID to filter by.

Return type:

Self

Returns:

A filtered WorkflowActionQuerySet containing actions that assign the specified document type.

Examples

Find actions that assign a specific document type:
>>> invoice_type_actions = client.workflow_actions.assign_document_type(2)
assign_owner(value)[source]

Filter workflow actions by the owner they assign to documents.

Find workflow actions that assign a specific owner (user) to documents when triggered.

Parameters:

value (int) – The owner (user) ID to filter by.

Return type:

Self

Returns:

A filtered WorkflowActionQuerySet containing actions that assign the specified owner.

Examples

Find actions that assign documents to a specific user:
>>> admin_actions = client.workflow_actions.assign_owner(1)
assign_storage_path(value)[source]

Filter workflow actions by the storage path they assign to documents.

Find workflow actions that assign a specific storage path to documents when triggered.

Parameters:

value (int) – The storage path ID to filter by.

Return type:

Self

Returns:

A filtered WorkflowActionQuerySet containing actions that assign the specified storage path.

Examples

Find actions that assign a specific storage path:
>>> tax_path_actions = client.workflow_actions.assign_storage_path(4)
assign_tags(value)[source]

Filter workflow actions by the tags they assign to documents.

Find workflow actions that assign specific tags to documents when triggered. Can filter by a single tag ID or multiple tag IDs.

Parameters:

value (int | list[int]) – The tag ID or list of tag IDs to filter by.

Return type:

Self

Returns:

A filtered WorkflowActionQuerySet containing actions that assign the specified tags.

Examples

Find actions that assign a specific tag:
>>> tax_tag_actions = client.workflow_actions.assign_tags(5)
Find actions that assign any of several tags:
>>> financial_tag_actions = client.workflow_actions.assign_tags([5, 8, 12])
assign_title(value, *, exact=True, case_insensitive=True)[source]

Filter workflow actions by the title they assign to documents.

Find workflow actions that set a specific document title when triggered.

Parameters:
  • value (str) – The title text to filter by.

  • exact (bool) – If True, match the exact title; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered WorkflowActionQuerySet containing actions that assign the specified title.

Examples

Find actions that set titles containing “Invoice”:
>>> invoice_actions = client.workflow_actions.assign_title("Invoice", exact=False)
type(value, *, exact=True, case_insensitive=True)[source]

Filter workflow actions by their type.

Workflow actions in Paperless-NGX have different types that determine what they do (e.g., assign metadata, move document, etc.).

Parameters:
  • value (str) – The action type to filter by.

  • exact (bool) – If True, match the exact type; if False, use contains matching.

  • case_insensitive (bool) – If True, ignore case when matching.

Return type:

Self

Returns:

A filtered WorkflowActionQuerySet containing actions of the specified type.

Examples

Find all actions that assign metadata:
>>> assign_actions = client.workflow_actions.type("assign")
class paperap.models.ProfileQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[Profile]

Implement a lazy-loaded, chainable query interface for Profile resources.

Extends StandardQuerySet to provide profile-specific filtering methods, allowing for efficient querying of user profiles in the Paperless-NGX system. Following the lazy-loading pattern, data is only fetched when actually needed.

Inherits all attributes from StandardQuerySet.

Examples

Get all profiles:
>>> profiles = client.profiles()
Filter profiles by email:
>>> profiles = client.profiles().email("example@example.com")
Iterate through results:
>>> for profile in profiles:
>>>     print(profile.first_name)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

email(value, *, exact=True, case_insensitive=True)[source]

Filter profiles by email address.

Parameters:
  • value (str) – The email address or pattern to filter by.

  • exact (bool) – Whether to filter by an exact match (True) or partial match (False). Defaults to True.

  • case_insensitive (bool) – Whether the match should be case insensitive. Defaults to True.

Return type:

ProfileQuerySet

Returns:

A new ProfileQuerySet instance with the email filter applied.

Examples

Exact match (default):
>>> profiles = client.profiles().email("john.doe@gmail.com")
Partial match (contains):
>>> profiles = client.profiles().email("gmail.com", exact=False)
Case-sensitive match:
>>> profiles = client.profiles().email("John.Doe@gmail.com", case_insensitive=False)
first_name(value, *, exact=True, case_insensitive=True)[source]

Filter profiles by first name.

Parameters:
  • value (str) – The first name or pattern to filter by.

  • exact (bool) – Whether to filter by an exact match (True) or partial match (False). Defaults to True.

  • case_insensitive (bool) – Whether the match should be case insensitive. Defaults to True.

Return type:

ProfileQuerySet

Returns:

A new ProfileQuerySet instance with the first name filter applied.

Examples

Exact match (default):
>>> profiles = client.profiles().first_name("John")
Partial match (contains):
>>> profiles = client.profiles().first_name("Jo", exact=False)
Case-sensitive match:
>>> profiles = client.profiles().first_name("John", case_insensitive=False)
has_usable_password(value=True)[source]

Filter profiles by whether they have a usable password.

Distinguish between local user accounts and those authenticated through external systems (like OAuth or LDAP) based on password usability.

Parameters:

value (bool) – True to find profiles with usable passwords, False to find profiles without usable passwords. Defaults to True.

Return type:

ProfileQuerySet

Returns:

A new ProfileQuerySet instance with the password usability filter applied.

Examples

Find profiles with usable passwords (local accounts):
>>> profiles = client.profiles().has_usable_password()
Find profiles without usable passwords (external auth):
>>> profiles = client.profiles().has_usable_password(False)
last_name(value, *, exact=True, case_insensitive=True)[source]

Filter profiles by last name.

Parameters:
  • value (str) – The last name or pattern to filter by.

  • exact (bool) – Whether to filter by an exact match (True) or partial match (False). Defaults to True.

  • case_insensitive (bool) – Whether the match should be case insensitive. Defaults to True.

Return type:

ProfileQuerySet

Returns:

A new ProfileQuerySet instance with the last name filter applied.

Examples

Exact match (default):
>>> profiles = client.profiles().last_name("Doe")
Partial match (contains):
>>> profiles = client.profiles().last_name("Do", exact=False)
Case-sensitive match:
>>> profiles = client.profiles().last_name("Doe", case_insensitive=False)
class paperap.models.ShareLinksQuerySet(resource, filters=None, _cache=None, _fetch_all=False, _next_url=None, _last_response=None, _iter=None, _urls_fetched=None)[source]

Bases: StandardQuerySet[ShareLinks]

Implement a lazy-loaded, chainable query interface for ShareLinks resources.

Extends StandardQuerySet to provide ShareLinks-specific filtering methods, including filtering by expiration date, slug, document, and file version. Only fetches data when it’s actually needed, providing pagination, filtering, and caching functionality similar to Django’s QuerySet.

Examples

Get all share links:
>>> all_links = client.share_links.all()
Filter by document ID:
>>> doc_links = client.share_links.filter(document=123)
Find links that expire soon:
>>> import datetime
>>> tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
>>> expiring_soon = client.share_links.expiration_before(tomorrow)
Parameters:
  • resource (BaseResource[_Model, Self])

  • filters (dict[str, Any] | None)

  • _cache (list[_Model] | None)

  • _fetch_all (bool)

  • _next_url (str | None)

  • _last_response (ClientResponse)

  • _iter (Iterator[_Model] | None)

  • _urls_fetched (list[str] | None)

created_after(date)[source]

Filter ShareLinks created after a given date.

Parameters:

date (datetime) – The datetime to compare against. ShareLinks created after this datetime will be included in the results.

Returns:

A filtered queryset containing ShareLinks created after the specified date.

Return type:

Self

Examples

Find links created in the last week:
>>> last_week = datetime.datetime.now() - datetime.timedelta(days=7)
>>> recent_links = client.share_links.created_after(last_week)
created_before(date)[source]

Filter ShareLinks created before a given date.

Parameters:

date (datetime) – The datetime to compare against. ShareLinks created before this datetime will be included in the results.

Returns:

A filtered queryset containing ShareLinks created before the specified date.

Return type:

Self

Examples

Find links created before last month:
>>> last_month = datetime.datetime.now() - datetime.timedelta(days=30)
>>> old_links = client.share_links.created_before(last_month)
created_between(start, end)[source]

Filter ShareLinks created between two dates.

Parameters:
  • start (datetime) – The start datetime. ShareLinks created at or after this datetime will be included in the results.

  • end (datetime) – The end datetime. ShareLinks created at or before this datetime will be included in the results.

Returns:

A filtered queryset containing ShareLinks created within the specified date range.

Return type:

Self

Examples

Find links created in January 2023:
>>> start = datetime.datetime(2023, 1, 1)
>>> end = datetime.datetime(2023, 1, 31, 23, 59, 59)
>>> jan_links = client.share_links.created_between(start, end)
document(value)[source]

Filter ShareLinks by associated document ID(s).

Parameters:

value (int | list[int]) – Either a single document ID or a list of document IDs to filter by. When a list is provided, links associated with any of the documents will be returned.

Returns:

A filtered queryset containing ShareLinks associated with the specified document(s).

Return type:

Self

Examples

Find all share links for a specific document:
>>> doc_links = client.share_links.document(123)
Find links for multiple documents:
>>> multi_doc_links = client.share_links.document([123, 456, 789])
expiration_after(value)[source]

Filter ShareLinks where expiration date is after the specified value.

Parameters:

value (datetime | str) – The datetime or ISO-formatted string to compare against. If a string is provided, it should be in ISO format (YYYY-MM-DDTHH:MM:SSZ).

Returns:

A filtered queryset containing only ShareLinks that expire after the given date.

Return type:

Self

Examples

Find links that haven’t expired yet:
>>> now = datetime.datetime.now()
>>> valid_links = client.share_links.expiration_after(now)
expiration_before(value)[source]

Filter ShareLinks where expiration date is before the specified value.

Parameters:

value (datetime | str) – The datetime or ISO-formatted string to compare against. If a string is provided, it should be in ISO format (YYYY-MM-DDTHH:MM:SSZ).

Returns:

A filtered queryset containing only ShareLinks that expire before the given date.

Return type:

Self

Examples

Find links expiring in the next week:
>>> next_week = datetime.datetime.now() + datetime.timedelta(days=7)
>>> expiring_soon = client.share_links.expiration_before(next_week)
Using string format:
>>> expiring_soon = client.share_links.expiration_before("2023-12-31T23:59:59Z")
file_version(value)[source]

Filter ShareLinks by file version.

In Paperless-NgX, share links can be created for specific versions of a document. This method filters links by their associated file version.

Parameters:

value (str) – The file version string to filter by (e.g., “archive”, “original”).

Returns:

A filtered queryset containing ShareLinks with the specified file version.

Return type:

Self

Examples

Find all share links for original document versions:
>>> original_links = client.share_links.file_version("original")
Find all share links for archived versions:
>>> archive_links = client.share_links.file_version("archive")
slug(value, *, exact=True, case_insensitive=True)[source]

Filter ShareLinks by their slug value.

The slug is a unique identifier for the share link that appears in the URL.

Parameters:
  • value (str) – The slug value to filter by.

  • exact (bool) – If True, matches the exact slug. If False, performs a contains search.

  • case_insensitive (bool) – If True, performs case-insensitive matching. If False, matching is case-sensitive.

Returns:

A filtered queryset containing ShareLinks matching the slug criteria.

Return type:

Self

Examples

Find a specific share link by its exact slug:
>>> link = client.share_links.slug("abc123def")
Find links containing a substring in their slug:
>>> links = client.share_links.slug("invoice", exact=False)

Subpackages