easypaperless
easypaperless — Python API wrapper for paperless-ngx.
1"""easypaperless — Python API wrapper for paperless-ngx.""" 2 3import importlib.metadata 4import logging 5 6__version__: str = importlib.metadata.version("easypaperless") 7 8from easypaperless import resources as resources # noqa: F401 9from easypaperless._internal.sentinel import UNSET, Unset 10from easypaperless.client import PaperlessClient 11from easypaperless.exceptions import ( 12 AuthError, 13 NotFoundError, 14 PaperlessError, 15 ServerError, 16 TaskTimeoutError, 17 UploadError, 18 ValidationError, 19) 20from easypaperless.models import ( 21 Correspondent, 22 CustomField, 23 CustomFieldValue, 24 Document, 25 DocumentMetadata, 26 DocumentNote, 27 DocumentType, 28 FieldDataType, 29 FileMetadataEntry, 30 MatchingAlgorithm, 31 PagedResult, 32 PaperlessPermission, 33 PermissionSet, 34 SearchHit, 35 SetPermissions, 36 StoragePath, 37 Tag, 38 Task, 39 TaskStatus, 40 User, 41) 42from easypaperless.sync import SyncPaperlessClient 43 44logging.getLogger("easypaperless").addHandler(logging.NullHandler()) 45 46__all__ = [ 47 "__version__", 48 # Clients 49 "PaperlessClient", 50 "SyncPaperlessClient", 51 # Sentinel 52 "UNSET", 53 "Unset", 54 # Models 55 "MatchingAlgorithm", 56 "PagedResult", 57 "Correspondent", 58 "CustomField", 59 "CustomFieldValue", 60 "Document", 61 "DocumentMetadata", 62 "DocumentNote", 63 "DocumentType", 64 "FieldDataType", 65 "FileMetadataEntry", 66 "PermissionSet", 67 "SearchHit", 68 "SetPermissions", 69 "StoragePath", 70 "Tag", 71 "Task", 72 "TaskStatus", 73 "User", 74 "PaperlessPermission", 75 # Exceptions 76 "PaperlessError", 77 "AuthError", 78 "NotFoundError", 79 "ValidationError", 80 "ServerError", 81 "UploadError", 82 "TaskTimeoutError", 83]
158class PaperlessClient(_ClientCore): 159 """Async client for the paperless-ngx API. 160 161 Resources are accessible as attributes: 162 163 * ``client.correspondents`` — correspondent CRUD + bulk ops - 164 see `easypaperless.resources.CorrespondentsResource` 165 * ``client.custom_fields`` — custom field CRUD - 166 see `easypaperless.resources.CustomFieldsResource` 167 * ``client.document_types`` — document type CRUD + bulk ops - 168 see `easypaperless.resources.DocumentTypesResource` 169 * ``client.documents`` — document CRUD, bulk ops, upload, download - 170 see `easypaperless.resources.DocumentsResource` 171 * ``client.documents.notes`` — document notes - 172 see `easypaperless.resources.NotesResource` 173 * ``client.storage_paths`` — storage path CRUD + bulk ops - 174 see `easypaperless.resources.StoragePathsResource` 175 * ``client.tags`` — tag CRUD + bulk ops - 176 see `easypaperless.resources.TagsResource` 177 * ``client.users`` — user CRUD - 178 see `easypaperless.resources.UsersResource` 179 * ``client.trash`` — list, restore, and permanently delete trashed documents - 180 see `easypaperless.resources.TrashResource` 181 182 Use as an async context manager to ensure the underlying HTTP connection 183 pool is closed when you are done: 184 185 Example: 186 async with PaperlessClient(url="http://localhost:8000", api_token="abc") as client: 187 docs = await client.documents.list(max_results=10) 188 """ 189 190 def __init__( 191 self, 192 url: str, 193 api_token: str, 194 *, 195 timeout: float = 30.0, 196 poll_interval: float = 2.0, 197 poll_timeout: float = 60.0, 198 ) -> None: 199 """Create an async paperless-ngx client. 200 201 Args: 202 url: Base URL of the paperless-ngx instance 203 (e.g. ``"http://localhost:8000"``). 204 api_token: API token. Generate one in paperless-ngx under 205 *Settings → API → Generate Token*. 206 timeout: Default request timeout in seconds. Default: ``30.0``. 207 poll_interval: Seconds between status checks when ``wait=True`` 208 is passed to :meth:`documents.upload`. Default: ``2.0``. 209 poll_timeout: Maximum seconds to wait for a document to finish 210 processing before raising 211 :exc:`~easypaperless.exceptions.TaskTimeoutError`. 212 Default: ``60.0``. 213 """ 214 super().__init__( 215 url, api_token, timeout=timeout, poll_interval=poll_interval, poll_timeout=poll_timeout 216 ) 217 218 async def __aenter__(self) -> PaperlessClient: 219 return self 220 221 async def __aexit__(self, *args: Any) -> None: 222 await self.close()
Async client for the paperless-ngx API.
Resources are accessible as attributes:
client.correspondents— correspondent CRUD + bulk ops - seeeasypaperless.resources.CorrespondentsResourceclient.custom_fields— custom field CRUD - seeeasypaperless.resources.CustomFieldsResourceclient.document_types— document type CRUD + bulk ops - seeeasypaperless.resources.DocumentTypesResourceclient.documents— document CRUD, bulk ops, upload, download - seeeasypaperless.resources.DocumentsResourceclient.documents.notes— document notes - seeeasypaperless.resources.NotesResourceclient.storage_paths— storage path CRUD + bulk ops - seeeasypaperless.resources.StoragePathsResourceclient.tags— tag CRUD + bulk ops - seeeasypaperless.resources.TagsResourceclient.users— user CRUD - seeeasypaperless.resources.UsersResourceclient.trash— list, restore, and permanently delete trashed documents - seeeasypaperless.resources.TrashResource
Use as an async context manager to ensure the underlying HTTP connection pool is closed when you are done:
Example:
async with PaperlessClient(url="http://localhost:8000", api_token="abc") as client: docs = await client.documents.list(max_results=10)
190 def __init__( 191 self, 192 url: str, 193 api_token: str, 194 *, 195 timeout: float = 30.0, 196 poll_interval: float = 2.0, 197 poll_timeout: float = 60.0, 198 ) -> None: 199 """Create an async paperless-ngx client. 200 201 Args: 202 url: Base URL of the paperless-ngx instance 203 (e.g. ``"http://localhost:8000"``). 204 api_token: API token. Generate one in paperless-ngx under 205 *Settings → API → Generate Token*. 206 timeout: Default request timeout in seconds. Default: ``30.0``. 207 poll_interval: Seconds between status checks when ``wait=True`` 208 is passed to :meth:`documents.upload`. Default: ``2.0``. 209 poll_timeout: Maximum seconds to wait for a document to finish 210 processing before raising 211 :exc:`~easypaperless.exceptions.TaskTimeoutError`. 212 Default: ``60.0``. 213 """ 214 super().__init__( 215 url, api_token, timeout=timeout, poll_interval=poll_interval, poll_timeout=poll_timeout 216 )
Create an async paperless-ngx client.
Arguments:
- url: Base URL of the paperless-ngx instance
(e.g.
"http://localhost:8000"). - api_token: API token. Generate one in paperless-ngx under Settings → API → Generate Token.
- timeout: Default request timeout in seconds. Default:
30.0. - poll_interval: Seconds between status checks when
wait=Trueis passed todocuments.upload(). Default:2.0. - poll_timeout: Maximum seconds to wait for a document to finish
processing before raising
~easypaperless.exceptions.TaskTimeoutError. Default:60.0.
83class SyncPaperlessClient(_SyncCore): 84 """Synchronous interface to paperless-ngx. 85 86 Resources are accessible as attributes: 87 88 * ``client.correspondents`` — correspondent CRUD + bulk ops - 89 see `easypaperless.resources.SyncCorrespondentsResource` 90 * ``client.custom_fields`` — custom field CRUD - 91 see `easypaperless.resources.SyncCustomFieldsResource` 92 * ``client.document_types`` — document type CRUD + bulk ops - 93 see `easypaperless.resources.SyncDocumentTypesResource` 94 * ``client.documents`` — document CRUD, bulk ops, upload, download - 95 see `easypaperless.resources.SyncDocumentsResource` 96 * ``client.documents.notes`` — document notes - 97 see `easypaperless.resources.SyncNotesResource` 98 * ``client.storage_paths`` — storage path CRUD + bulk ops - 99 see `easypaperless.resources.SyncStoragePathsResource` 100 * ``client.tags`` — tag CRUD + bulk ops - 101 see `easypaperless.resources.SyncTagsResource` 102 * ``client.users`` — user CRUD - 103 see `easypaperless.resources.SyncUsersResource` 104 * ``client.trash`` — list, restore, and permanently delete trashed documents - 105 see `easypaperless.resources.SyncTrashResource` 106 107 All methods are synchronous wrappers around the async 108 :class:`~easypaperless.client.PaperlessClient`. Operations run on a 109 dedicated background event loop thread so that the httpx connection pool 110 is reused across calls and cleanup works correctly. 111 112 Use as a context manager to ensure proper cleanup: 113 114 Example: 115 with SyncPaperlessClient(url="http://localhost:8000", api_token="abc") as client: 116 tags = client.tags.list() 117 docs = client.documents.list(search="invoice") 118 119 Note: 120 Cannot be used inside an already-running event loop (e.g. Jupyter 121 notebooks). Use :class:`~easypaperless.client.PaperlessClient` 122 directly in those environments. 123 """ 124 125 def __init__(self, url: str, api_token: str, **kwargs: Any) -> None: 126 """Create a synchronous paperless-ngx client. 127 128 Args: 129 url: Base URL of the paperless-ngx instance 130 (e.g. ``"http://localhost:8000"``). 131 api_token: API token. Generate one in paperless-ngx under 132 *Settings → API → Generate Token*. 133 **kwargs: Additional keyword arguments forwarded to 134 :class:`~easypaperless.client.PaperlessClient` (e.g. 135 ``poll_interval``, ``poll_timeout``). 136 """ 137 super().__init__(url, api_token, **kwargs) 138 139 def __enter__(self) -> SyncPaperlessClient: 140 return self 141 142 def __exit__(self, *args: Any) -> None: 143 self.close()
Synchronous interface to paperless-ngx.
Resources are accessible as attributes:
client.correspondents— correspondent CRUD + bulk ops - seeeasypaperless.resources.SyncCorrespondentsResourceclient.custom_fields— custom field CRUD - seeeasypaperless.resources.SyncCustomFieldsResourceclient.document_types— document type CRUD + bulk ops - seeeasypaperless.resources.SyncDocumentTypesResourceclient.documents— document CRUD, bulk ops, upload, download - seeeasypaperless.resources.SyncDocumentsResourceclient.documents.notes— document notes - seeeasypaperless.resources.SyncNotesResourceclient.storage_paths— storage path CRUD + bulk ops - seeeasypaperless.resources.SyncStoragePathsResourceclient.tags— tag CRUD + bulk ops - seeeasypaperless.resources.SyncTagsResourceclient.users— user CRUD - seeeasypaperless.resources.SyncUsersResourceclient.trash— list, restore, and permanently delete trashed documents - seeeasypaperless.resources.SyncTrashResource
All methods are synchronous wrappers around the async
~easypaperless.client.PaperlessClient. Operations run on a
dedicated background event loop thread so that the httpx connection pool
is reused across calls and cleanup works correctly.
Use as a context manager to ensure proper cleanup:
Example:
with SyncPaperlessClient(url="http://localhost:8000", api_token="abc") as client: tags = client.tags.list() docs = client.documents.list(search="invoice")
Note:
Cannot be used inside an already-running event loop (e.g. Jupyter notebooks). Use
~easypaperless.client.PaperlessClientdirectly in those environments.
125 def __init__(self, url: str, api_token: str, **kwargs: Any) -> None: 126 """Create a synchronous paperless-ngx client. 127 128 Args: 129 url: Base URL of the paperless-ngx instance 130 (e.g. ``"http://localhost:8000"``). 131 api_token: API token. Generate one in paperless-ngx under 132 *Settings → API → Generate Token*. 133 **kwargs: Additional keyword arguments forwarded to 134 :class:`~easypaperless.client.PaperlessClient` (e.g. 135 ``poll_interval``, ``poll_timeout``). 136 """ 137 super().__init__(url, api_token, **kwargs)
Create a synchronous paperless-ngx client.
Arguments:
- url: Base URL of the paperless-ngx instance
(e.g.
"http://localhost:8000"). - api_token: API token. Generate one in paperless-ngx under Settings → API → Generate Token.
- **kwargs: Additional keyword arguments forwarded to
~easypaperless.client.PaperlessClient(e.g.poll_interval,poll_timeout).
9class Unset: 10 """Sentinel type signalling that a parameter was not provided. 11 12 Use the singleton :data:`UNSET` constant — do not instantiate directly. 13 """ 14 15 __slots__ = () 16 17 def __repr__(self) -> str: 18 return "UNSET"
Sentinel type signalling that a parameter was not provided.
Use the singleton UNSET constant — do not instantiate directly.
9class MatchingAlgorithm(IntEnum): 10 """Auto-matching algorithm used by tags, correspondents, document types, and storage paths.""" 11 12 NONE = 0 13 ANY_WORD = 1 14 ALL_WORDS = 2 15 EXACT = 3 16 REGEX = 4 17 FUZZY = 5 18 AUTO = 6
Auto-matching algorithm used by tags, correspondents, document types, and storage paths.
13class PagedResult(BaseModel, Generic[T]): 14 """Wrapper returned by all ``list()`` methods. 15 16 Holds the pagination metadata returned by paperless-ngx alongside the 17 deserialized resource items. 18 19 Attributes: 20 count: Total number of matching items as reported by the server on 21 the first fetched page. 22 next: URL of the next page as returned by the API, or ``None``. 23 Always ``None`` when auto-pagination is active (the default 24 ``page=None``), because the navigation URL is meaningless once 25 all pages have been consumed by the library. 26 previous: URL of the previous page as returned by the API, or 27 ``None``. Always ``None`` when auto-pagination is active. 28 all: All matching item IDs when the API includes them; ``None`` 29 otherwise. 30 results: The deserialized resource items for this page / all fetched 31 pages. 32 """ 33 34 count: int 35 next: str | None = None 36 previous: str | None = None 37 all: List[int] | None = None 38 results: List[T] = Field(default_factory=list)
Wrapper returned by all list() methods.
Holds the pagination metadata returned by paperless-ngx alongside the deserialized resource items.
Attributes:
- count: Total number of matching items as reported by the server on the first fetched page.
- next: URL of the next page as returned by the API, or
None. AlwaysNonewhen auto-pagination is active (the defaultpage=None), because the navigation URL is meaningless once all pages have been consumed by the library. - previous: URL of the previous page as returned by the API, or
None. AlwaysNonewhen auto-pagination is active. - all: All matching item IDs when the API includes them;
Noneotherwise. - results: The deserialized resource items for this page / all fetched pages.
13class Correspondent(BaseModel): 14 """A paperless-ngx correspondent (sender or recipient of a document). 15 16 Attributes: 17 id: Unique correspondent ID. 18 name: Correspondent name. 19 document_count: Number of documents assigned to this correspondent. 20 last_correspondence: Date of the most recent document assigned here, 21 or ``None``. 22 """ 23 24 model_config = ConfigDict(extra="ignore") 25 26 id: int 27 name: str 28 slug: str | None = None 29 match: str | None = None 30 matching_algorithm: MatchingAlgorithm | None = None 31 is_insensitive: bool | None = None 32 document_count: int | None = None 33 last_correspondence: date | None = None 34 owner: int | None = None 35 user_can_change: bool | None = None
A paperless-ngx correspondent (sender or recipient of a document).
Attributes:
- id: Unique correspondent ID.
- name: Correspondent name.
- document_count: Number of documents assigned to this correspondent.
- last_correspondence: Date of the most recent document assigned here,
or
None.
26class CustomField(BaseModel): 27 """A custom field definition in paperless-ngx. 28 29 Attributes: 30 id: Unique custom-field ID. 31 name: Field name shown in the UI. 32 data_type: The value type for this field (see 33 :class:`FieldDataType`). 34 extra_data: Additional configuration (e.g. select options), or 35 ``None``. 36 document_count: Number of documents that have a value for this field. 37 """ 38 39 model_config = ConfigDict(extra="ignore") 40 41 id: int 42 name: str 43 data_type: FieldDataType 44 extra_data: Any = None 45 document_count: int | None = None
A custom field definition in paperless-ngx.
Attributes:
- id: Unique custom-field ID.
- name: Field name shown in the UI.
- data_type: The value type for this field (see
FieldDataType). - extra_data: Additional configuration (e.g. select options), or
None. - document_count: Number of documents that have a value for this field.
66class CustomFieldValue(BaseModel): 67 """A custom field value attached to a document. 68 69 Attributes: 70 field: ID of the :class:`~easypaperless.models.custom_fields.CustomField` 71 definition. 72 value: The stored value; its Python type depends on the field's 73 ``data_type``. 74 """ 75 76 model_config = ConfigDict(extra="ignore") 77 78 field: int 79 value: Any = None
A custom field value attached to a document.
Attributes:
- field: ID of the
~easypaperless.models.custom_fields.CustomFielddefinition. - value: The stored value; its Python type depends on the field's
data_type.
173class Document(BaseModel): 174 """A paperless-ngx document. 175 176 Attributes: 177 id: Unique document ID. 178 title: Document title. 179 content: Full OCR text content, if available. 180 tags: List of tag IDs assigned to this document. 181 document_type: ID of the assigned document type, or ``None``. 182 correspondent: ID of the assigned correspondent, or ``None``. 183 storage_path: ID of the assigned storage path, or ``None``. 184 created: Document creation date (``date`` object). Changed from 185 ``datetime`` to ``date`` in paperless-ngx API v9. 186 created_date: Date portion of creation. **Deprecated** by 187 paperless-ngx as of v9 — use ``created`` instead. Will be 188 removed in a future API version. 189 archive_serial_number: Archive serial number (ASN), or ``None``. 190 custom_fields: List of :class:`CustomFieldValue` instances. 191 notes: User notes attached to this document. 192 search_hit: Full-text search relevance metadata, populated only when 193 the document was returned by a full-text search. 194 metadata: Extended file-level metadata (checksums, sizes, MIME type). 195 ``None`` unless the document was fetched with 196 ``include_metadata=True`` or retrieved via 197 :meth:`~easypaperless._internal.resources.documents.DocumentsResource.get_metadata`. 198 """ 199 200 model_config = ConfigDict(extra="ignore", populate_by_name=True) 201 202 id: int 203 title: str 204 content: str | None = None 205 tags: list[int] = Field(default_factory=list) 206 document_type: int | None = None 207 correspondent: int | None = None 208 storage_path: int | None = None 209 created: date | None = None 210 created_date: date | None = None 211 modified: datetime | None = None 212 added: datetime | None = None 213 archive_serial_number: int | None = None 214 original_file_name: str | None = None 215 archived_file_name: str | None = None 216 owner: int | None = None 217 user_can_change: bool | None = None 218 is_shared_by_requester: bool | None = None 219 notes: list[DocumentNote] = Field(default_factory=list) 220 custom_fields: list[CustomFieldValue] = Field(default_factory=list) 221 search_hit: SearchHit | None = Field(default=None, alias="__search_hit__") 222 metadata: DocumentMetadata | None = None
A paperless-ngx document.
Attributes:
- id: Unique document ID.
- title: Document title.
- content: Full OCR text content, if available.
- tags: List of tag IDs assigned to this document.
- document_type: ID of the assigned document type, or
None. - correspondent: ID of the assigned correspondent, or
None. - storage_path: ID of the assigned storage path, or
None. - created: Document creation date (
dateobject). Changed fromdatetimetodatein paperless-ngx API v9. - created_date: Date portion of creation. Deprecated by
paperless-ngx as of v9 — use
createdinstead. Will be removed in a future API version. - archive_serial_number: Archive serial number (ASN), or
None. - custom_fields: List of
CustomFieldValueinstances. - notes: User notes attached to this document.
- search_hit: Full-text search relevance metadata, populated only when the document was returned by a full-text search.
- metadata: Extended file-level metadata (checksums, sizes, MIME type).
Noneunless the document was fetched withinclude_metadata=Trueor retrieved via~easypaperless._internal.resources.documents.DocumentsResource.get_metadata().
131class DocumentMetadata(BaseModel): 132 """Extended file-level metadata for a document. 133 134 Returned by ``GET /api/documents/{id}/metadata/`` and optionally attached 135 to a :class:`Document` when 136 :meth:`~easypaperless._internal.resources.documents.DocumentsResource.get` 137 is called with ``include_metadata=True``. 138 139 Because reading metadata requires disk I/O it is **not** included in 140 document list responses; it must be requested explicitly. 141 142 Attributes: 143 original_checksum: MD5 checksum of the original uploaded file. 144 original_size: Size of the original file in bytes. 145 original_mime_type: MIME type of the original file 146 (e.g. ``"application/pdf"``). 147 media_filename: Path of the archived file relative to the 148 paperless-ngx media root. 149 has_archive_version: ``True`` when paperless-ngx has produced an 150 archived (post-processed) PDF in addition to the original. 151 original_metadata: File-level metadata entries extracted from the 152 original document (PDF XMP/info tags, etc.). 153 archive_checksum: MD5 checksum of the archived file, or ``None`` if 154 no archive version exists. 155 archive_size: Size of the archived file in bytes, or ``None``. 156 archive_metadata: File-level metadata entries from the archived 157 document, or ``None``. 158 """ 159 160 model_config = ConfigDict(extra="ignore") 161 162 original_checksum: str | None = None 163 original_size: int | None = None 164 original_mime_type: str | None = None 165 media_filename: str | None = None 166 has_archive_version: bool | None = None 167 original_metadata: list[FileMetadataEntry] = Field(default_factory=list) 168 archive_checksum: str | None = None 169 archive_size: int | None = None 170 archive_metadata: list[FileMetadataEntry] | None = None
Extended file-level metadata for a document.
Returned by GET /api/documents/{id}/metadata/ and optionally attached
to a Document when
~easypaperless._internal.resources.documents.DocumentsResource.get()
is called with include_metadata=True.
Because reading metadata requires disk I/O it is not included in document list responses; it must be requested explicitly.
Attributes:
- original_checksum: MD5 checksum of the original uploaded file.
- original_size: Size of the original file in bytes.
- original_mime_type: MIME type of the original file
(e.g.
"application/pdf"). - media_filename: Path of the archived file relative to the paperless-ngx media root.
- has_archive_version:
Truewhen paperless-ngx has produced an archived (post-processed) PDF in addition to the original. - original_metadata: File-level metadata entries extracted from the original document (PDF XMP/info tags, etc.).
- archive_checksum: MD5 checksum of the archived file, or
Noneif no archive version exists. - archive_size: Size of the archived file in bytes, or
None. - archive_metadata: File-level metadata entries from the archived
document, or
None.
82class DocumentNote(BaseModel): 83 """A user note attached to a document. 84 85 Attributes: 86 id: Unique note ID. 87 note: Text content of the note. 88 created: Timestamp when the note was created. 89 document: ID of the parent document. 90 user: ID of the user who created the note. 91 """ 92 93 model_config = ConfigDict(extra="ignore") 94 95 id: int | None = None 96 note: str 97 created: datetime | None = None 98 document: int | None = None 99 user: int | None = None 100 101 @field_validator("user", mode="before") 102 @classmethod 103 def _coerce_user(cls, v: object) -> int | None: 104 if isinstance(v, dict): 105 return v.get("id") 106 return v # type: ignore[return-value]
A user note attached to a document.
Attributes:
- id: Unique note ID.
- note: Text content of the note.
- created: Timestamp when the note was created.
- document: ID of the parent document.
- user: ID of the user who created the note.
11class DocumentType(BaseModel): 12 """A paperless-ngx document type (e.g. Invoice, Receipt, Contract). 13 14 Attributes: 15 id: Unique document-type ID. 16 name: Document-type name. 17 document_count: Number of documents assigned to this document type. 18 """ 19 20 model_config = ConfigDict(extra="ignore") 21 22 id: int 23 name: str 24 slug: str | None = None 25 match: str | None = None 26 matching_algorithm: MatchingAlgorithm | None = None 27 is_insensitive: bool | None = None 28 document_count: int | None = None 29 owner: int | None = None 30 user_can_change: bool | None = None
A paperless-ngx document type (e.g. Invoice, Receipt, Contract).
Attributes:
- id: Unique document-type ID.
- name: Document-type name.
- document_count: Number of documents assigned to this document type.
12class FieldDataType(StrEnum): 13 """Allowed data types for a custom field.""" 14 15 string = "string" 16 boolean = "boolean" 17 integer = "integer" 18 float = "float" 19 monetary = "monetary" 20 date = "date" 21 url = "url" 22 documentlink = "documentlink" 23 select = "select"
Allowed data types for a custom field.
109class FileMetadataEntry(BaseModel): 110 """A single embedded metadata key-value pair from a document file. 111 112 Paperless-ngx reads file-level metadata (e.g. PDF XMP/info tags) and 113 exposes each entry in this format. ``namespace`` and ``prefix`` are 114 ``None`` for non-namespaced entries. 115 116 Attributes: 117 namespace: XML namespace URI, or ``None``. 118 prefix: Namespace prefix (e.g. ``"pdf"``), or ``None``. 119 key: Metadata key (e.g. ``"Producer"``). 120 value: Metadata value as a string. 121 """ 122 123 model_config = ConfigDict(extra="ignore") 124 125 namespace: str | None = None 126 prefix: str | None = None 127 key: str 128 value: str
A single embedded metadata key-value pair from a document file.
Paperless-ngx reads file-level metadata (e.g. PDF XMP/info tags) and
exposes each entry in this format. namespace and prefix are
None for non-namespaced entries.
Attributes:
- namespace: XML namespace URI, or
None. - prefix: Namespace prefix (e.g.
"pdf"), orNone. - key: Metadata key (e.g.
"Producer"). - value: Metadata value as a string.
7class PermissionSet(BaseModel): 8 users: list[int] = Field(default_factory=list) 9 groups: list[int] = Field(default_factory=list)
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
- __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
49class SearchHit(BaseModel): 50 """Full-text search relevance metadata returned alongside a document. 51 52 Attributes: 53 score: Relevance score assigned by the Whoosh FTS engine. 54 highlights: HTML snippet with matching terms highlighted. 55 rank: Position in the result set by relevance. 56 """ 57 58 model_config = ConfigDict(extra="ignore") 59 60 score: float | None = None 61 highlights: str | None = None 62 note_highlights: str | None = None 63 rank: int | None = None
Full-text search relevance metadata returned alongside a document.
Attributes:
- score: Relevance score assigned by the Whoosh FTS engine.
- highlights: HTML snippet with matching terms highlighted.
- rank: Position in the result set by relevance.
12class SetPermissions(BaseModel): 13 view: PermissionSet = Field(default_factory=PermissionSet) 14 change: PermissionSet = Field(default_factory=PermissionSet)
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: Metadata for generic models; contains data used for a similar purpose to __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.
- __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
11class StoragePath(BaseModel): 12 """A paperless-ngx storage path — controls where archived files are stored. 13 14 Attributes: 15 id: Unique storage-path ID. 16 name: Storage-path name. 17 path: Template string used to build the storage path, e.g. 18 ``"{created_year}/{correspondent}/{title}"``. 19 document_count: Number of documents using this storage path. 20 """ 21 22 model_config = ConfigDict(extra="ignore") 23 24 id: int 25 name: str 26 slug: str | None = None 27 path: str | None = None 28 match: str | None = None 29 matching_algorithm: MatchingAlgorithm | None = None 30 is_insensitive: bool | None = None 31 document_count: int | None = None 32 owner: int | None = None 33 user_can_change: bool | None = None
A paperless-ngx storage path — controls where archived files are stored.
Attributes:
- id: Unique storage-path ID.
- name: Storage-path name.
- path: Template string used to build the storage path, e.g.
"{created_year}/{correspondent}/{title}". - document_count: Number of documents using this storage path.
11class Tag(BaseModel): 12 """A paperless-ngx tag. 13 14 Attributes: 15 id: Unique tag ID. 16 name: Tag name. 17 color: Hex colour code used in the UI (e.g. ``"#ff0000"``). 18 is_inbox_tag: If ``True``, newly ingested documents receive this tag 19 automatically until they are processed. 20 document_count: Number of documents currently assigned to this tag. 21 parent: ID of the parent tag for hierarchical tag trees, or ``None``. 22 children: IDs of child tags, or ``None``. 23 """ 24 25 model_config = ConfigDict(extra="ignore") 26 27 id: int 28 name: str 29 slug: str | None = None 30 color: str | None = None 31 text_color: str | None = None 32 match: str | None = None 33 matching_algorithm: MatchingAlgorithm | None = None 34 is_insensitive: bool | None = None 35 is_inbox_tag: bool | None = None 36 document_count: int | None = None 37 owner: int | None = None 38 user_can_change: bool | None = None 39 parent: int | None = None 40 children: list[int] | None = None
A paperless-ngx tag.
Attributes:
- id: Unique tag ID.
- name: Tag name.
- color: Hex colour code used in the UI (e.g.
"#ff0000"). - is_inbox_tag: If
True, newly ingested documents receive this tag automatically until they are processed. - document_count: Number of documents currently assigned to this tag.
- parent: ID of the parent tag for hierarchical tag trees, or
None. - children: IDs of child tags, or
None.
24class Task(BaseModel): 25 """A paperless-ngx background processing task (e.g. document ingestion). 26 27 Attributes: 28 task_id: Unique Celery task identifier. 29 task_file_name: Original file name submitted for processing. 30 status: Current task status as a :class:`TaskStatus` enum value. 31 result: Human-readable result or error message, set on completion. 32 related_document: String representation of the resulting document ID 33 on success, ``None`` otherwise. 34 """ 35 36 model_config = ConfigDict(extra="ignore") 37 38 task_id: str 39 task_file_name: str | None = None 40 date_created: datetime | None = None 41 date_done: datetime | None = None 42 type: str | None = None 43 status: TaskStatus | None = None 44 result: str | None = None 45 acknowledged: bool | None = None 46 related_document: str | None = None
A paperless-ngx background processing task (e.g. document ingestion).
Attributes:
- task_id: Unique Celery task identifier.
- task_file_name: Original file name submitted for processing.
- status: Current task status as a
TaskStatusenum value. - result: Human-readable result or error message, set on completion.
- related_document: String representation of the resulting document ID
on success,
Noneotherwise.
13class TaskStatus(StrEnum): 14 """Status values for a paperless-ngx background processing task.""" 15 16 PENDING = "PENDING" 17 STARTED = "STARTED" 18 SUCCESS = "SUCCESS" 19 FAILURE = "FAILURE" 20 RETRY = "RETRY" 21 REVOKED = "REVOKED"
Status values for a paperless-ngx background processing task.
205class User(BaseModel): 206 """A paperless-ngx user account. 207 208 Attributes: 209 id: Unique user ID (set by the API). 210 username: Login username. 211 email: Email address. 212 password: Password field as returned by the API (write-only in practice). 213 first_name: Given name. 214 last_name: Family name. 215 date_joined: Timestamp of account creation. 216 is_staff: Whether the user has staff (admin UI) access. 217 is_active: Whether the account is active. 218 is_superuser: Whether the user has unrestricted superuser access. 219 groups: IDs of groups the user belongs to. 220 user_permissions: Directly assigned permission strings. 221 inherited_permissions: Effective permissions inherited from groups 222 (read-only, not sent on create/update). 223 is_mfa_enabled: Whether multi-factor authentication is enabled 224 (read-only, not sent on create/update). 225 """ 226 227 model_config = ConfigDict(extra="ignore") 228 229 id: int 230 username: str 231 email: str | None = None 232 password: str | None = None 233 first_name: str | None = None 234 last_name: str | None = None 235 date_joined: datetime | None = None 236 is_staff: bool | None = None 237 is_active: bool | None = None 238 is_superuser: bool | None = None 239 groups: list[int] | None = None 240 user_permissions: list[str] | None = None 241 inherited_permissions: list[str] | None = None 242 is_mfa_enabled: bool | None = None
A paperless-ngx user account.
Attributes:
- id: Unique user ID (set by the API).
- username: Login username.
- email: Email address.
- password: Password field as returned by the API (write-only in practice).
- first_name: Given name.
- last_name: Family name.
- date_joined: Timestamp of account creation.
- is_staff: Whether the user has staff (admin UI) access.
- is_active: Whether the account is active.
- is_superuser: Whether the user has unrestricted superuser access.
- groups: IDs of groups the user belongs to.
- user_permissions: Directly assigned permission strings.
- inherited_permissions: Effective permissions inherited from groups (read-only, not sent on create/update).
- is_mfa_enabled: Whether multi-factor authentication is enabled (read-only, not sent on create/update).
7class PaperlessError(Exception): 8 """Base exception for all easypaperless errors. 9 10 Attributes: 11 status_code: The HTTP status code associated with the error, or 12 ``None`` for non-HTTP errors (e.g. timeouts, local validation). 13 """ 14 15 def __init__(self, message: str, status_code: int | None = None) -> None: 16 """Create a PaperlessError. 17 18 Args: 19 message: Human-readable error description. 20 status_code: HTTP status code, if applicable. 21 """ 22 super().__init__(message) 23 self.status_code = status_code
Base exception for all easypaperless errors.
Attributes:
- status_code: The HTTP status code associated with the error, or
Nonefor non-HTTP errors (e.g. timeouts, local validation).
15 def __init__(self, message: str, status_code: int | None = None) -> None: 16 """Create a PaperlessError. 17 18 Args: 19 message: Human-readable error description. 20 status_code: HTTP status code, if applicable. 21 """ 22 super().__init__(message) 23 self.status_code = status_code
Create a PaperlessError.
Arguments:
- message: Human-readable error description.
- status_code: HTTP status code, if applicable.
26class AuthError(PaperlessError): 27 """Raised on 401 or 403 responses. 28 29 Indicates that the API key is missing, invalid, or lacks permission for 30 the requested operation. 31 """
Raised on 401 or 403 responses.
Indicates that the API key is missing, invalid, or lacks permission for the requested operation.
34class NotFoundError(PaperlessError): 35 """Raised on 404 responses or when a name lookup fails."""
Raised on 404 responses or when a name lookup fails.
38class ValidationError(PaperlessError): 39 """Raised on 422 responses or bad input supplied by the caller."""
Raised on 422 responses or bad input supplied by the caller.
42class ServerError(PaperlessError): 43 """Raised on 5xx responses or unrecoverable transport errors."""
Raised on 5xx responses or unrecoverable transport errors.
46class UploadError(PaperlessError): 47 """Raised when file submission or document processing fails. 48 49 Typically raised when paperless-ngx reports a ``FAILURE`` status on the 50 Celery task created by 51 :meth:`~easypaperless.client.PaperlessClient.upload_document`. 52 """
Raised when file submission or document processing fails.
Typically raised when paperless-ngx reports a FAILURE status on the
Celery task created by
~easypaperless.client.PaperlessClient.upload_document().
55class TaskTimeoutError(PaperlessError): 56 """Raised when upload polling exceeds the configured timeout. 57 58 Raised by :meth:`~easypaperless.client.PaperlessClient.upload_document` 59 (with ``wait=True``) when the document processing task does not reach a 60 terminal state within ``poll_timeout`` seconds. 61 """ 62 63 def __init__(self, message: str) -> None: 64 super().__init__(message, status_code=None)
Raised when upload polling exceeds the configured timeout.
Raised by ~easypaperless.client.PaperlessClient.upload_document()
(with wait=True) when the document processing task does not reach a
terminal state within poll_timeout seconds.