easypaperless.resources
Resource Classes
The following resource classes are _internal classes. Methods can be accessed via the instance of
easypaperless.PaperlessClient or easypaperless.SyncPaperlessClient
Example:
async with PaperlessClient(url="http://localhost:8000", api_key="abc") as client: docs = await client.documents.list(max_results=10)
1"""Resource Classes 2 3The following resource classes are _internal classes. Methods can be accessed via the instance of 4`easypaperless.PaperlessClient` or `easypaperless.SyncPaperlessClient` 5 6Example: 7 async with PaperlessClient(url="http://localhost:8000", api_key="abc") as client: 8 docs = await client.documents.list(max_results=10) 9 10""" 11 12# internal comment: the doc string above is also rendered in the pdoc documentation. 13# 14# original was: 15# 16# Public resource classes — for type annotations and IDE support. 17# 18# Re-exports all async and sync resource classes from the internal modules 19# so that pdoc can document them as a full page with all methods. 20# 21# Example: 22# from easypaperless.resources import DocumentsResource 23 24 25from easypaperless._internal.resources.correspondents import CorrespondentsResource 26from easypaperless._internal.resources.custom_fields import CustomFieldsResource 27from easypaperless._internal.resources.document_types import DocumentTypesResource 28from easypaperless._internal.resources.documents import DocumentsResource, NotesResource 29from easypaperless._internal.resources.storage_paths import StoragePathsResource 30from easypaperless._internal.resources.tags import TagsResource 31from easypaperless._internal.sync_resources.correspondents import SyncCorrespondentsResource 32from easypaperless._internal.sync_resources.custom_fields import SyncCustomFieldsResource 33from easypaperless._internal.sync_resources.document_types import SyncDocumentTypesResource 34from easypaperless._internal.sync_resources.documents import ( 35 SyncDocumentsResource, 36 SyncNotesResource, 37) 38from easypaperless._internal.sync_resources.storage_paths import SyncStoragePathsResource 39from easypaperless._internal.sync_resources.tags import SyncTagsResource 40 41__all__ = [ 42 "CorrespondentsResource", 43 "CustomFieldsResource", 44 "DocumentTypesResource", 45 "DocumentsResource", 46 "NotesResource", 47 "StoragePathsResource", 48 "TagsResource", 49 "SyncCorrespondentsResource", 50 "SyncCustomFieldsResource", 51 "SyncDocumentTypesResource", 52 "SyncDocumentsResource", 53 "SyncNotesResource", 54 "SyncStoragePathsResource", 55 "SyncTagsResource", 56]
17class CorrespondentsResource: 18 """Accessor for correspondents: ``client.correspondents``.""" 19 20 def __init__(self, core: _ClientCore) -> None: 21 self._core = core 22 23 async def list( 24 self, 25 *, 26 ids: List[int] | None = None, 27 name_contains: str | None = None, 28 name_exact: str | None = None, 29 page: int | None = None, 30 page_size: int | None = None, 31 ordering: str | None = None, 32 descending: bool = False, 33 ) -> List[Correspondent]: 34 """Return correspondents defined in paperless-ngx. 35 36 Args: 37 ids: Return only correspondents whose ID is in this list. 38 name_contains: Case-insensitive substring filter on name. 39 name_exact: Case-insensitive exact match on name. 40 page: Return only this specific page (1-based). 41 page_size: Number of results per page. 42 ordering: Field to sort by. 43 descending: When ``True``, reverses the sort direction. 44 45 Returns: 46 List of :class:`~easypaperless.models.correspondents.Correspondent` objects. 47 """ 48 params: dict[str, Any] = {} 49 if ids is not None: 50 params["id__in"] = ",".join(str(i) for i in ids) 51 if name_contains is not None: 52 params["name__icontains"] = name_contains 53 if name_exact is not None: 54 params["name__iexact"] = name_exact 55 if page is not None: 56 params["page"] = page 57 if page_size is not None: 58 params["page_size"] = page_size 59 if ordering is not None: 60 params["ordering"] = f"-{ordering}" if descending else ordering 61 return cast( 62 List[Correspondent], 63 await self._core._list_resource("correspondents", Correspondent, params or None), 64 ) 65 66 async def get(self, id: int) -> Correspondent: 67 """Fetch a single correspondent by its ID. 68 69 Args: 70 id: Numeric correspondent ID. 71 72 Returns: 73 The :class:`~easypaperless.models.correspondents.Correspondent` with the given ID. 74 75 Raises: 76 ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID. 77 """ 78 return cast( 79 Correspondent, await self._core._get_resource("correspondents", id, Correspondent) 80 ) 81 82 async def create( 83 self, 84 *, 85 name: str, 86 match: str | None | _Unset = UNSET, 87 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 88 is_insensitive: bool = True, 89 owner: int | None | _Unset = UNSET, 90 set_permissions: SetPermissions | None = None, 91 ) -> Correspondent: 92 """Create a new correspondent. 93 94 Args: 95 name: Correspondent name. Must be unique. 96 match: Auto-matching pattern. 97 matching_algorithm: Controls how ``match`` is applied. 98 is_insensitive: When ``True``, ``match`` is case-insensitive. 99 Defaults to ``True``, matching the paperless-ngx API default. 100 owner: Numeric user ID to assign as owner. 101 set_permissions: Explicit view/change permission sets. 102 103 Returns: 104 The newly created :class:`~easypaperless.models.correspondents.Correspondent`. 105 """ 106 return cast( 107 Correspondent, 108 await self._core._create_resource( 109 "correspondents", 110 Correspondent, 111 owner=owner, 112 set_permissions=set_permissions, 113 name=name, 114 match=match, 115 matching_algorithm=matching_algorithm, 116 is_insensitive=is_insensitive, 117 ), 118 ) 119 120 async def update( 121 self, 122 id: int, 123 *, 124 name: str | None | _Unset = UNSET, 125 match: str | None | _Unset = UNSET, 126 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 127 is_insensitive: bool | None | _Unset = UNSET, 128 owner: int | None | _Unset = UNSET, 129 set_permissions: SetPermissions | None | _Unset = UNSET, 130 ) -> Correspondent: 131 """Partially update a correspondent (PATCH semantics). 132 133 Args: 134 id: Numeric ID of the correspondent to update. 135 name: Correspondent name. 136 match: Auto-matching pattern. 137 matching_algorithm: Controls how ``match`` is applied. 138 is_insensitive: When ``True``, ``match`` is case-insensitive. 139 owner: Numeric user ID to assign as owner. 140 Pass ``None`` to clear the owner. 141 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 142 set_permissions: Explicit view/change permission sets. 143 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 144 145 Returns: 146 The updated :class:`~easypaperless.models.correspondents.Correspondent`. 147 """ 148 _set_perms: dict[str, Any] | _Unset = ( 149 UNSET 150 if isinstance(set_permissions, _Unset) 151 else (set_permissions or SetPermissions()).model_dump() 152 ) 153 return cast( 154 Correspondent, 155 await self._core._update_resource( 156 "correspondents", 157 id, 158 Correspondent, 159 name=name, 160 match=match, 161 matching_algorithm=matching_algorithm, 162 is_insensitive=is_insensitive, 163 owner=owner, 164 set_permissions=_set_perms, 165 ), 166 ) 167 168 async def delete(self, id: int) -> None: 169 """Delete a correspondent. 170 171 Args: 172 id: Numeric ID of the correspondent to delete. 173 174 Raises: 175 ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID. 176 """ 177 await self._core._delete_resource("correspondents", id) 178 179 async def bulk_delete(self, ids: List[int]) -> None: 180 """Permanently delete multiple correspondents in a single request. 181 182 Args: 183 ids: List of correspondent IDs to delete. 184 """ 185 await self._core._bulk_edit_objects("correspondents", ids, "delete") 186 187 async def bulk_set_permissions( 188 self, 189 ids: List[int], 190 *, 191 set_permissions: SetPermissions | None = None, 192 owner: int | None = None, 193 merge: bool = False, 194 ) -> None: 195 """Set permissions and/or owner on multiple correspondents. 196 197 Args: 198 ids: List of correspondent IDs to modify. 199 set_permissions: Explicit view/change permission sets. 200 owner: Numeric user ID to assign as owner. 201 merge: When ``True``, new permissions are merged with existing ones. 202 """ 203 params: dict[str, Any] = {"merge": merge} 204 if set_permissions is not None: 205 params["permissions"] = set_permissions.model_dump() 206 if owner is not None: 207 params["owner"] = owner 208 await self._core._bulk_edit_objects("correspondents", ids, "set_permissions", **params)
Accessor for correspondents: client.correspondents.
23 async def list( 24 self, 25 *, 26 ids: List[int] | None = None, 27 name_contains: str | None = None, 28 name_exact: str | None = None, 29 page: int | None = None, 30 page_size: int | None = None, 31 ordering: str | None = None, 32 descending: bool = False, 33 ) -> List[Correspondent]: 34 """Return correspondents defined in paperless-ngx. 35 36 Args: 37 ids: Return only correspondents whose ID is in this list. 38 name_contains: Case-insensitive substring filter on name. 39 name_exact: Case-insensitive exact match on name. 40 page: Return only this specific page (1-based). 41 page_size: Number of results per page. 42 ordering: Field to sort by. 43 descending: When ``True``, reverses the sort direction. 44 45 Returns: 46 List of :class:`~easypaperless.models.correspondents.Correspondent` objects. 47 """ 48 params: dict[str, Any] = {} 49 if ids is not None: 50 params["id__in"] = ",".join(str(i) for i in ids) 51 if name_contains is not None: 52 params["name__icontains"] = name_contains 53 if name_exact is not None: 54 params["name__iexact"] = name_exact 55 if page is not None: 56 params["page"] = page 57 if page_size is not None: 58 params["page_size"] = page_size 59 if ordering is not None: 60 params["ordering"] = f"-{ordering}" if descending else ordering 61 return cast( 62 List[Correspondent], 63 await self._core._list_resource("correspondents", Correspondent, params or None), 64 )
Return correspondents defined in paperless-ngx.
Arguments:
- ids: Return only correspondents whose ID is in this list.
- name_contains: Case-insensitive substring filter on name.
- name_exact: Case-insensitive exact match on name.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.correspondents.Correspondentobjects.
66 async def get(self, id: int) -> Correspondent: 67 """Fetch a single correspondent by its ID. 68 69 Args: 70 id: Numeric correspondent ID. 71 72 Returns: 73 The :class:`~easypaperless.models.correspondents.Correspondent` with the given ID. 74 75 Raises: 76 ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID. 77 """ 78 return cast( 79 Correspondent, await self._core._get_resource("correspondents", id, Correspondent) 80 )
Fetch a single correspondent by its ID.
Arguments:
- id: Numeric correspondent ID.
Returns:
The
~easypaperless.models.correspondents.Correspondentwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID.
82 async def create( 83 self, 84 *, 85 name: str, 86 match: str | None | _Unset = UNSET, 87 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 88 is_insensitive: bool = True, 89 owner: int | None | _Unset = UNSET, 90 set_permissions: SetPermissions | None = None, 91 ) -> Correspondent: 92 """Create a new correspondent. 93 94 Args: 95 name: Correspondent name. Must be unique. 96 match: Auto-matching pattern. 97 matching_algorithm: Controls how ``match`` is applied. 98 is_insensitive: When ``True``, ``match`` is case-insensitive. 99 Defaults to ``True``, matching the paperless-ngx API default. 100 owner: Numeric user ID to assign as owner. 101 set_permissions: Explicit view/change permission sets. 102 103 Returns: 104 The newly created :class:`~easypaperless.models.correspondents.Correspondent`. 105 """ 106 return cast( 107 Correspondent, 108 await self._core._create_resource( 109 "correspondents", 110 Correspondent, 111 owner=owner, 112 set_permissions=set_permissions, 113 name=name, 114 match=match, 115 matching_algorithm=matching_algorithm, 116 is_insensitive=is_insensitive, 117 ), 118 )
Create a new correspondent.
Arguments:
- name: Correspondent name. Must be unique.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. Defaults toTrue, matching the paperless-ngx API default. - owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.correspondents.Correspondent.
120 async def update( 121 self, 122 id: int, 123 *, 124 name: str | None | _Unset = UNSET, 125 match: str | None | _Unset = UNSET, 126 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 127 is_insensitive: bool | None | _Unset = UNSET, 128 owner: int | None | _Unset = UNSET, 129 set_permissions: SetPermissions | None | _Unset = UNSET, 130 ) -> Correspondent: 131 """Partially update a correspondent (PATCH semantics). 132 133 Args: 134 id: Numeric ID of the correspondent to update. 135 name: Correspondent name. 136 match: Auto-matching pattern. 137 matching_algorithm: Controls how ``match`` is applied. 138 is_insensitive: When ``True``, ``match`` is case-insensitive. 139 owner: Numeric user ID to assign as owner. 140 Pass ``None`` to clear the owner. 141 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 142 set_permissions: Explicit view/change permission sets. 143 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 144 145 Returns: 146 The updated :class:`~easypaperless.models.correspondents.Correspondent`. 147 """ 148 _set_perms: dict[str, Any] | _Unset = ( 149 UNSET 150 if isinstance(set_permissions, _Unset) 151 else (set_permissions or SetPermissions()).model_dump() 152 ) 153 return cast( 154 Correspondent, 155 await self._core._update_resource( 156 "correspondents", 157 id, 158 Correspondent, 159 name=name, 160 match=match, 161 matching_algorithm=matching_algorithm, 162 is_insensitive=is_insensitive, 163 owner=owner, 164 set_permissions=_set_perms, 165 ), 166 )
Partially update a correspondent (PATCH semantics).
Arguments:
- id: Numeric ID of the correspondent to update.
- name: Correspondent name.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. - owner: Numeric user ID to assign as owner.
Pass
Noneto clear the owner. Omit (or pass~easypaperless.UNSET) to leave unchanged. - set_permissions: Explicit view/change permission sets.
Omit (or pass
~easypaperless.UNSET) to leave unchanged.
Returns:
The updated
~easypaperless.models.correspondents.Correspondent.
168 async def delete(self, id: int) -> None: 169 """Delete a correspondent. 170 171 Args: 172 id: Numeric ID of the correspondent to delete. 173 174 Raises: 175 ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID. 176 """ 177 await self._core._delete_resource("correspondents", id)
Delete a correspondent.
Arguments:
- id: Numeric ID of the correspondent to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID.
179 async def bulk_delete(self, ids: List[int]) -> None: 180 """Permanently delete multiple correspondents in a single request. 181 182 Args: 183 ids: List of correspondent IDs to delete. 184 """ 185 await self._core._bulk_edit_objects("correspondents", ids, "delete")
Permanently delete multiple correspondents in a single request.
Arguments:
- ids: List of correspondent IDs to delete.
187 async def bulk_set_permissions( 188 self, 189 ids: List[int], 190 *, 191 set_permissions: SetPermissions | None = None, 192 owner: int | None = None, 193 merge: bool = False, 194 ) -> None: 195 """Set permissions and/or owner on multiple correspondents. 196 197 Args: 198 ids: List of correspondent IDs to modify. 199 set_permissions: Explicit view/change permission sets. 200 owner: Numeric user ID to assign as owner. 201 merge: When ``True``, new permissions are merged with existing ones. 202 """ 203 params: dict[str, Any] = {"merge": merge} 204 if set_permissions is not None: 205 params["permissions"] = set_permissions.model_dump() 206 if owner is not None: 207 params["owner"] = owner 208 await self._core._bulk_edit_objects("correspondents", ids, "set_permissions", **params)
Set permissions and/or owner on multiple correspondents.
Arguments:
- ids: List of correspondent IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as owner.
- merge: When
True, new permissions are merged with existing ones.
16class CustomFieldsResource: 17 """Accessor for custom fields: ``client.custom_fields``.""" 18 19 def __init__(self, core: _ClientCore) -> None: 20 self._core = core 21 22 async def list( 23 self, 24 *, 25 name_contains: str | None = None, 26 name_exact: str | None = None, 27 page: int | None = None, 28 page_size: int | None = None, 29 ordering: str | None = None, 30 descending: bool = False, 31 ) -> List[CustomField]: 32 """Return all custom fields defined in paperless-ngx. 33 34 Args: 35 name_contains: Case-insensitive substring filter on name. 36 name_exact: Case-insensitive exact match on name. 37 page: Return only this specific page (1-based). 38 page_size: Number of results per page. 39 ordering: Field to sort by. 40 descending: When ``True``, reverses the sort direction. 41 42 Returns: 43 List of :class:`~easypaperless.models.custom_fields.CustomField` objects. 44 """ 45 params: dict[str, Any] = {} 46 if name_contains is not None: 47 params["name__icontains"] = name_contains 48 if name_exact is not None: 49 params["name__iexact"] = name_exact 50 if page is not None: 51 params["page"] = page 52 if page_size is not None: 53 params["page_size"] = page_size 54 if ordering is not None: 55 params["ordering"] = f"-{ordering}" if descending else ordering 56 return cast( 57 List[CustomField], 58 await self._core._list_resource("custom_fields", CustomField, params or None), 59 ) 60 61 async def get(self, id: int) -> CustomField: 62 """Fetch a single custom field by its ID. 63 64 Args: 65 id: Numeric custom-field ID. 66 67 Returns: 68 The :class:`~easypaperless.models.custom_fields.CustomField` with the given ID. 69 70 Raises: 71 ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID. 72 """ 73 return cast(CustomField, await self._core._get_resource("custom_fields", id, CustomField)) 74 75 async def create( 76 self, 77 *, 78 name: str, 79 data_type: str, 80 extra_data: Any | None = None, 81 owner: int | None | _Unset = UNSET, 82 set_permissions: SetPermissions | None = None, 83 ) -> CustomField: 84 """Create a new custom field. 85 86 Args: 87 name: Field name shown in the UI. Must be unique. 88 data_type: Value type. One of ``"string"``, ``"boolean"``, 89 ``"integer"``, ``"float"``, ``"monetary"``, ``"date"``, 90 ``"url"``, ``"documentlink"``, ``"select"``. 91 extra_data: Additional configuration for the field type. 92 owner: Numeric user ID to assign as owner. 93 set_permissions: Explicit view/change permission sets. 94 95 Returns: 96 The newly created :class:`~easypaperless.models.custom_fields.CustomField`. 97 """ 98 return cast( 99 CustomField, 100 await self._core._create_resource( 101 "custom_fields", 102 CustomField, 103 owner=owner, 104 set_permissions=set_permissions, 105 name=name, 106 data_type=data_type, 107 extra_data=extra_data, 108 ), 109 ) 110 111 async def update( 112 self, 113 id: int, 114 *, 115 name: str | None | _Unset = UNSET, 116 data_type: str | None | _Unset = UNSET, 117 extra_data: Any | None | _Unset = UNSET, 118 ) -> CustomField: 119 """Partially update a custom field (PATCH semantics). 120 121 Args: 122 id: Numeric ID of the custom field to update. 123 name: Field name shown in the UI. 124 data_type: Value type (e.g. ``"string"``, ``"boolean"``, ``"integer"``). 125 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 126 extra_data: Additional configuration for the field type. 127 128 Returns: 129 The updated :class:`~easypaperless.models.custom_fields.CustomField`. 130 """ 131 return cast( 132 CustomField, 133 await self._core._update_resource( 134 "custom_fields", 135 id, 136 CustomField, 137 name=name, 138 data_type=data_type, 139 extra_data=extra_data, 140 ), 141 ) 142 143 async def delete(self, id: int) -> None: 144 """Delete a custom field. 145 146 Args: 147 id: Numeric ID of the custom field to delete. 148 149 Raises: 150 ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID. 151 """ 152 await self._core._delete_resource("custom_fields", id)
Accessor for custom fields: client.custom_fields.
22 async def list( 23 self, 24 *, 25 name_contains: str | None = None, 26 name_exact: str | None = None, 27 page: int | None = None, 28 page_size: int | None = None, 29 ordering: str | None = None, 30 descending: bool = False, 31 ) -> List[CustomField]: 32 """Return all custom fields defined in paperless-ngx. 33 34 Args: 35 name_contains: Case-insensitive substring filter on name. 36 name_exact: Case-insensitive exact match on name. 37 page: Return only this specific page (1-based). 38 page_size: Number of results per page. 39 ordering: Field to sort by. 40 descending: When ``True``, reverses the sort direction. 41 42 Returns: 43 List of :class:`~easypaperless.models.custom_fields.CustomField` objects. 44 """ 45 params: dict[str, Any] = {} 46 if name_contains is not None: 47 params["name__icontains"] = name_contains 48 if name_exact is not None: 49 params["name__iexact"] = name_exact 50 if page is not None: 51 params["page"] = page 52 if page_size is not None: 53 params["page_size"] = page_size 54 if ordering is not None: 55 params["ordering"] = f"-{ordering}" if descending else ordering 56 return cast( 57 List[CustomField], 58 await self._core._list_resource("custom_fields", CustomField, params or None), 59 )
Return all custom fields defined in paperless-ngx.
Arguments:
- name_contains: Case-insensitive substring filter on name.
- name_exact: Case-insensitive exact match on name.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.custom_fields.CustomFieldobjects.
61 async def get(self, id: int) -> CustomField: 62 """Fetch a single custom field by its ID. 63 64 Args: 65 id: Numeric custom-field ID. 66 67 Returns: 68 The :class:`~easypaperless.models.custom_fields.CustomField` with the given ID. 69 70 Raises: 71 ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID. 72 """ 73 return cast(CustomField, await self._core._get_resource("custom_fields", id, CustomField))
Fetch a single custom field by its ID.
Arguments:
- id: Numeric custom-field ID.
Returns:
The
~easypaperless.models.custom_fields.CustomFieldwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID.
75 async def create( 76 self, 77 *, 78 name: str, 79 data_type: str, 80 extra_data: Any | None = None, 81 owner: int | None | _Unset = UNSET, 82 set_permissions: SetPermissions | None = None, 83 ) -> CustomField: 84 """Create a new custom field. 85 86 Args: 87 name: Field name shown in the UI. Must be unique. 88 data_type: Value type. One of ``"string"``, ``"boolean"``, 89 ``"integer"``, ``"float"``, ``"monetary"``, ``"date"``, 90 ``"url"``, ``"documentlink"``, ``"select"``. 91 extra_data: Additional configuration for the field type. 92 owner: Numeric user ID to assign as owner. 93 set_permissions: Explicit view/change permission sets. 94 95 Returns: 96 The newly created :class:`~easypaperless.models.custom_fields.CustomField`. 97 """ 98 return cast( 99 CustomField, 100 await self._core._create_resource( 101 "custom_fields", 102 CustomField, 103 owner=owner, 104 set_permissions=set_permissions, 105 name=name, 106 data_type=data_type, 107 extra_data=extra_data, 108 ), 109 )
Create a new custom field.
Arguments:
- name: Field name shown in the UI. Must be unique.
- data_type: Value type. One of
"string","boolean","integer","float","monetary","date","url","documentlink","select". - extra_data: Additional configuration for the field type.
- owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.custom_fields.CustomField.
111 async def update( 112 self, 113 id: int, 114 *, 115 name: str | None | _Unset = UNSET, 116 data_type: str | None | _Unset = UNSET, 117 extra_data: Any | None | _Unset = UNSET, 118 ) -> CustomField: 119 """Partially update a custom field (PATCH semantics). 120 121 Args: 122 id: Numeric ID of the custom field to update. 123 name: Field name shown in the UI. 124 data_type: Value type (e.g. ``"string"``, ``"boolean"``, ``"integer"``). 125 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 126 extra_data: Additional configuration for the field type. 127 128 Returns: 129 The updated :class:`~easypaperless.models.custom_fields.CustomField`. 130 """ 131 return cast( 132 CustomField, 133 await self._core._update_resource( 134 "custom_fields", 135 id, 136 CustomField, 137 name=name, 138 data_type=data_type, 139 extra_data=extra_data, 140 ), 141 )
Partially update a custom field (PATCH semantics).
Arguments:
- id: Numeric ID of the custom field to update.
- name: Field name shown in the UI.
- data_type: Value type (e.g.
"string","boolean","integer"). Omit (or pass~easypaperless.UNSET) to leave unchanged. - extra_data: Additional configuration for the field type.
Returns:
The updated
~easypaperless.models.custom_fields.CustomField.
143 async def delete(self, id: int) -> None: 144 """Delete a custom field. 145 146 Args: 147 id: Numeric ID of the custom field to delete. 148 149 Raises: 150 ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID. 151 """ 152 await self._core._delete_resource("custom_fields", id)
Delete a custom field.
Arguments:
- id: Numeric ID of the custom field to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID.
17class DocumentTypesResource: 18 """Accessor for document types: ``client.document_types``.""" 19 20 def __init__(self, core: _ClientCore) -> None: 21 self._core = core 22 23 async def list( 24 self, 25 *, 26 ids: List[int] | None = None, 27 name_contains: str | None = None, 28 name_exact: str | None = None, 29 page: int | None = None, 30 page_size: int | None = None, 31 ordering: str | None = None, 32 descending: bool = False, 33 ) -> List[DocumentType]: 34 """Return document types defined in paperless-ngx. 35 36 Args: 37 ids: Return only document types whose ID is in this list. 38 name_contains: Case-insensitive substring filter on name. 39 name_exact: Case-insensitive exact match on name. 40 page: Return only this specific page (1-based). 41 page_size: Number of results per page. 42 ordering: Field to sort by. 43 descending: When ``True``, reverses the sort direction. 44 45 Returns: 46 List of :class:`~easypaperless.models.document_types.DocumentType` objects. 47 """ 48 params: dict[str, Any] = {} 49 if ids is not None: 50 params["id__in"] = ",".join(str(i) for i in ids) 51 if name_contains is not None: 52 params["name__icontains"] = name_contains 53 if name_exact is not None: 54 params["name__iexact"] = name_exact 55 if page is not None: 56 params["page"] = page 57 if page_size is not None: 58 params["page_size"] = page_size 59 if ordering is not None: 60 params["ordering"] = f"-{ordering}" if descending else ordering 61 return cast( 62 List[DocumentType], 63 await self._core._list_resource("document_types", DocumentType, params or None), 64 ) 65 66 async def get(self, id: int) -> DocumentType: 67 """Fetch a single document type by its ID. 68 69 Args: 70 id: Numeric document-type ID. 71 72 Returns: 73 The :class:`~easypaperless.models.document_types.DocumentType` with the given ID. 74 75 Raises: 76 ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID. 77 """ 78 return cast( 79 DocumentType, await self._core._get_resource("document_types", id, DocumentType) 80 ) 81 82 async def create( 83 self, 84 *, 85 name: str, 86 match: str | None | _Unset = UNSET, 87 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 88 is_insensitive: bool = True, 89 owner: int | None | _Unset = UNSET, 90 set_permissions: SetPermissions | None = None, 91 ) -> DocumentType: 92 """Create a new document type. 93 94 Args: 95 name: Document-type name. Must be unique. 96 match: Auto-matching pattern. 97 matching_algorithm: Controls how ``match`` is applied. 98 is_insensitive: When ``True``, ``match`` is case-insensitive. 99 Defaults to ``True``, matching the paperless-ngx API default. 100 owner: Numeric user ID to assign as owner. 101 set_permissions: Explicit view/change permission sets. 102 103 Returns: 104 The newly created :class:`~easypaperless.models.document_types.DocumentType`. 105 """ 106 return cast( 107 DocumentType, 108 await self._core._create_resource( 109 "document_types", 110 DocumentType, 111 owner=owner, 112 set_permissions=set_permissions, 113 name=name, 114 match=match, 115 matching_algorithm=matching_algorithm, 116 is_insensitive=is_insensitive, 117 ), 118 ) 119 120 async def update( 121 self, 122 id: int, 123 *, 124 name: str | None | _Unset = UNSET, 125 match: str | None | _Unset = UNSET, 126 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 127 is_insensitive: bool | None | _Unset = UNSET, 128 owner: int | None | _Unset = UNSET, 129 set_permissions: SetPermissions | None | _Unset = UNSET, 130 ) -> DocumentType: 131 """Partially update a document type (PATCH semantics). 132 133 Args: 134 id: Numeric ID of the document type to update. 135 name: Document-type name. 136 match: Auto-matching pattern. 137 matching_algorithm: Controls how ``match`` is applied. 138 is_insensitive: When ``True``, ``match`` is case-insensitive. 139 owner: Numeric user ID to assign as owner. 140 Pass ``None`` to clear the owner. 141 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 142 set_permissions: Explicit view/change permission sets. 143 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 144 145 Returns: 146 The updated :class:`~easypaperless.models.document_types.DocumentType`. 147 """ 148 _set_perms: dict[str, Any] | _Unset = ( 149 UNSET 150 if isinstance(set_permissions, _Unset) 151 else (set_permissions or SetPermissions()).model_dump() 152 ) 153 return cast( 154 DocumentType, 155 await self._core._update_resource( 156 "document_types", 157 id, 158 DocumentType, 159 name=name, 160 match=match, 161 matching_algorithm=matching_algorithm, 162 is_insensitive=is_insensitive, 163 owner=owner, 164 set_permissions=_set_perms, 165 ), 166 ) 167 168 async def delete(self, id: int) -> None: 169 """Delete a document type. 170 171 Args: 172 id: Numeric ID of the document type to delete. 173 174 Raises: 175 ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID. 176 """ 177 await self._core._delete_resource("document_types", id) 178 179 async def bulk_delete(self, ids: List[int]) -> None: 180 """Permanently delete multiple document types in a single request. 181 182 Args: 183 ids: List of document type IDs to delete. 184 """ 185 await self._core._bulk_edit_objects("document_types", ids, "delete") 186 187 async def bulk_set_permissions( 188 self, 189 ids: List[int], 190 *, 191 set_permissions: SetPermissions | None = None, 192 owner: int | None = None, 193 merge: bool = False, 194 ) -> None: 195 """Set permissions and/or owner on multiple document types. 196 197 Args: 198 ids: List of document type IDs to modify. 199 set_permissions: Explicit view/change permission sets. 200 owner: Numeric user ID to assign as owner. 201 merge: When ``True``, new permissions are merged with existing ones. 202 """ 203 params: dict[str, Any] = {"merge": merge} 204 if set_permissions is not None: 205 params["permissions"] = set_permissions.model_dump() 206 if owner is not None: 207 params["owner"] = owner 208 await self._core._bulk_edit_objects("document_types", ids, "set_permissions", **params)
Accessor for document types: client.document_types.
23 async def list( 24 self, 25 *, 26 ids: List[int] | None = None, 27 name_contains: str | None = None, 28 name_exact: str | None = None, 29 page: int | None = None, 30 page_size: int | None = None, 31 ordering: str | None = None, 32 descending: bool = False, 33 ) -> List[DocumentType]: 34 """Return document types defined in paperless-ngx. 35 36 Args: 37 ids: Return only document types whose ID is in this list. 38 name_contains: Case-insensitive substring filter on name. 39 name_exact: Case-insensitive exact match on name. 40 page: Return only this specific page (1-based). 41 page_size: Number of results per page. 42 ordering: Field to sort by. 43 descending: When ``True``, reverses the sort direction. 44 45 Returns: 46 List of :class:`~easypaperless.models.document_types.DocumentType` objects. 47 """ 48 params: dict[str, Any] = {} 49 if ids is not None: 50 params["id__in"] = ",".join(str(i) for i in ids) 51 if name_contains is not None: 52 params["name__icontains"] = name_contains 53 if name_exact is not None: 54 params["name__iexact"] = name_exact 55 if page is not None: 56 params["page"] = page 57 if page_size is not None: 58 params["page_size"] = page_size 59 if ordering is not None: 60 params["ordering"] = f"-{ordering}" if descending else ordering 61 return cast( 62 List[DocumentType], 63 await self._core._list_resource("document_types", DocumentType, params or None), 64 )
Return document types defined in paperless-ngx.
Arguments:
- ids: Return only document types whose ID is in this list.
- name_contains: Case-insensitive substring filter on name.
- name_exact: Case-insensitive exact match on name.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.document_types.DocumentTypeobjects.
66 async def get(self, id: int) -> DocumentType: 67 """Fetch a single document type by its ID. 68 69 Args: 70 id: Numeric document-type ID. 71 72 Returns: 73 The :class:`~easypaperless.models.document_types.DocumentType` with the given ID. 74 75 Raises: 76 ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID. 77 """ 78 return cast( 79 DocumentType, await self._core._get_resource("document_types", id, DocumentType) 80 )
Fetch a single document type by its ID.
Arguments:
- id: Numeric document-type ID.
Returns:
The
~easypaperless.models.document_types.DocumentTypewith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID.
82 async def create( 83 self, 84 *, 85 name: str, 86 match: str | None | _Unset = UNSET, 87 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 88 is_insensitive: bool = True, 89 owner: int | None | _Unset = UNSET, 90 set_permissions: SetPermissions | None = None, 91 ) -> DocumentType: 92 """Create a new document type. 93 94 Args: 95 name: Document-type name. Must be unique. 96 match: Auto-matching pattern. 97 matching_algorithm: Controls how ``match`` is applied. 98 is_insensitive: When ``True``, ``match`` is case-insensitive. 99 Defaults to ``True``, matching the paperless-ngx API default. 100 owner: Numeric user ID to assign as owner. 101 set_permissions: Explicit view/change permission sets. 102 103 Returns: 104 The newly created :class:`~easypaperless.models.document_types.DocumentType`. 105 """ 106 return cast( 107 DocumentType, 108 await self._core._create_resource( 109 "document_types", 110 DocumentType, 111 owner=owner, 112 set_permissions=set_permissions, 113 name=name, 114 match=match, 115 matching_algorithm=matching_algorithm, 116 is_insensitive=is_insensitive, 117 ), 118 )
Create a new document type.
Arguments:
- name: Document-type name. Must be unique.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. Defaults toTrue, matching the paperless-ngx API default. - owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.document_types.DocumentType.
120 async def update( 121 self, 122 id: int, 123 *, 124 name: str | None | _Unset = UNSET, 125 match: str | None | _Unset = UNSET, 126 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 127 is_insensitive: bool | None | _Unset = UNSET, 128 owner: int | None | _Unset = UNSET, 129 set_permissions: SetPermissions | None | _Unset = UNSET, 130 ) -> DocumentType: 131 """Partially update a document type (PATCH semantics). 132 133 Args: 134 id: Numeric ID of the document type to update. 135 name: Document-type name. 136 match: Auto-matching pattern. 137 matching_algorithm: Controls how ``match`` is applied. 138 is_insensitive: When ``True``, ``match`` is case-insensitive. 139 owner: Numeric user ID to assign as owner. 140 Pass ``None`` to clear the owner. 141 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 142 set_permissions: Explicit view/change permission sets. 143 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 144 145 Returns: 146 The updated :class:`~easypaperless.models.document_types.DocumentType`. 147 """ 148 _set_perms: dict[str, Any] | _Unset = ( 149 UNSET 150 if isinstance(set_permissions, _Unset) 151 else (set_permissions or SetPermissions()).model_dump() 152 ) 153 return cast( 154 DocumentType, 155 await self._core._update_resource( 156 "document_types", 157 id, 158 DocumentType, 159 name=name, 160 match=match, 161 matching_algorithm=matching_algorithm, 162 is_insensitive=is_insensitive, 163 owner=owner, 164 set_permissions=_set_perms, 165 ), 166 )
Partially update a document type (PATCH semantics).
Arguments:
- id: Numeric ID of the document type to update.
- name: Document-type name.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. - owner: Numeric user ID to assign as owner.
Pass
Noneto clear the owner. Omit (or pass~easypaperless.UNSET) to leave unchanged. - set_permissions: Explicit view/change permission sets.
Omit (or pass
~easypaperless.UNSET) to leave unchanged.
Returns:
The updated
~easypaperless.models.document_types.DocumentType.
168 async def delete(self, id: int) -> None: 169 """Delete a document type. 170 171 Args: 172 id: Numeric ID of the document type to delete. 173 174 Raises: 175 ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID. 176 """ 177 await self._core._delete_resource("document_types", id)
Delete a document type.
Arguments:
- id: Numeric ID of the document type to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID.
179 async def bulk_delete(self, ids: List[int]) -> None: 180 """Permanently delete multiple document types in a single request. 181 182 Args: 183 ids: List of document type IDs to delete. 184 """ 185 await self._core._bulk_edit_objects("document_types", ids, "delete")
Permanently delete multiple document types in a single request.
Arguments:
- ids: List of document type IDs to delete.
187 async def bulk_set_permissions( 188 self, 189 ids: List[int], 190 *, 191 set_permissions: SetPermissions | None = None, 192 owner: int | None = None, 193 merge: bool = False, 194 ) -> None: 195 """Set permissions and/or owner on multiple document types. 196 197 Args: 198 ids: List of document type IDs to modify. 199 set_permissions: Explicit view/change permission sets. 200 owner: Numeric user ID to assign as owner. 201 merge: When ``True``, new permissions are merged with existing ones. 202 """ 203 params: dict[str, Any] = {"merge": merge} 204 if set_permissions is not None: 205 params["permissions"] = set_permissions.model_dump() 206 if owner is not None: 207 params["owner"] = owner 208 await self._core._bulk_edit_objects("document_types", ids, "set_permissions", **params)
Set permissions and/or owner on multiple document types.
Arguments:
- ids: List of document type IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as owner.
- merge: When
True, new permissions are merged with existing ones.
105class DocumentsResource: 106 """Accessor for documents: ``client.documents``.""" 107 108 def __init__(self, core: _ClientCore) -> None: 109 self._core = core 110 self.notes = NotesResource(core) 111 112 @staticmethod 113 def _format_date_value(value: date | datetime | str) -> str: 114 if isinstance(value, datetime): 115 return value.isoformat() 116 if isinstance(value, date): 117 return value.isoformat() 118 return value 119 120 @staticmethod 121 def _is_datetime(value: date | datetime | str) -> bool: 122 if isinstance(value, datetime): 123 return True 124 if isinstance(value, str): 125 return bool(_DATETIME_STR_RE.match(value)) 126 return False 127 128 async def get(self, id: int, *, include_metadata: bool = False) -> Document: 129 """Fetch a single document by its ID. 130 131 Args: 132 id: Numeric paperless-ngx document ID. 133 include_metadata: When ``True``, the extended file-level metadata 134 is fetched concurrently and attached to the document. 135 Default: ``False``. 136 137 Returns: 138 The :class:`~easypaperless.models.documents.Document` with the 139 given ID. 140 141 Raises: 142 ~easypaperless.exceptions.NotFoundError: If no document exists 143 with that ID. 144 """ 145 if include_metadata: 146 doc_resp, meta_resp = await asyncio.gather( 147 self._core._session.get(f"/documents/{id}/"), 148 self._core._session.get(f"/documents/{id}/metadata/"), 149 ) 150 data = doc_resp.json() 151 data["metadata"] = meta_resp.json() 152 else: 153 resp = await self._core._session.get(f"/documents/{id}/") 154 data = resp.json() 155 return Document.model_validate(data) 156 157 async def get_metadata(self, id: int) -> DocumentMetadata: 158 """Fetch the extended file-level metadata for a document. 159 160 Args: 161 id: Numeric paperless-ngx document ID. 162 163 Returns: 164 A :class:`~easypaperless.models.documents.DocumentMetadata` instance. 165 166 Raises: 167 ~easypaperless.exceptions.NotFoundError: If no document exists 168 with that ID. 169 """ 170 resp = await self._core._session.get(f"/documents/{id}/metadata/") 171 return DocumentMetadata.model_validate(resp.json()) 172 173 async def list( 174 self, 175 *, 176 search: str | None = None, 177 search_mode: str = "title_or_content", 178 ids: List[int] | None = None, 179 tags: List[int | str] | None = None, 180 any_tags: List[int | str] | None = None, 181 exclude_tags: List[int | str] | None = None, 182 correspondent: int | str | None | _Unset = UNSET, 183 any_correspondent: List[int | str] | None = None, 184 exclude_correspondents: List[int | str] | None = None, 185 document_type: int | str | None | _Unset = UNSET, 186 document_type_name_contains: str | None = None, 187 document_type_name_exact: str | None = None, 188 any_document_type: List[int | str] | None = None, 189 exclude_document_types: List[int | str] | None = None, 190 storage_path: int | str | None | _Unset = UNSET, 191 any_storage_paths: List[int | str] | None = None, 192 exclude_storage_paths: List[int | str] | None = None, 193 owner: int | None | _Unset = UNSET, 194 exclude_owners: List[int] | None = None, 195 custom_fields: List[int | str] | None = None, 196 any_custom_fields: List[int | str] | None = None, 197 exclude_custom_fields: List[int | str] | None = None, 198 custom_field_query: List[Any] | None = None, 199 archive_serial_number: int | None | _Unset = UNSET, 200 archive_serial_number_from: int | None = None, 201 archive_serial_number_till: int | None = None, 202 created_after: date | str | None = None, 203 created_before: date | str | None = None, 204 added_after: date | datetime | str | None = None, 205 added_from: date | datetime | str | None = None, 206 added_before: date | datetime | str | None = None, 207 added_until: date | datetime | str | None = None, 208 modified_after: date | datetime | str | None = None, 209 modified_from: date | datetime | str | None = None, 210 modified_before: date | datetime | str | None = None, 211 modified_until: date | datetime | str | None = None, 212 checksum: str | None = None, 213 page_size: int = 25, 214 page: int | None = None, 215 ordering: str | None = None, 216 descending: bool = False, 217 max_results: int | None = None, 218 on_page: Callable[[int, int | None], None] | None = None, 219 ) -> List[Document]: 220 """Return a filtered list of documents. 221 222 All tag, correspondent, document-type, storage-path, and custom-field 223 parameters accept either integer IDs or string names. 224 225 Args: 226 search: Search string. Behaviour depends on ``search_mode``. 227 search_mode: How ``search`` is applied. One of: 228 ``"title_or_content"`` *(default)*, ``"title"``, ``"query"``, 229 ``"original_filename"``. 230 ids: Return only documents whose ID is in this list. 231 tags: Documents must have **all** of these tags (AND semantics). 232 any_tags: Documents must have **at least one** of these tags. 233 exclude_tags: Documents must have **none** of these tags. 234 correspondent: Filter to documents assigned to this correspondent. 235 Pass ``None`` to return only documents with no correspondent set. 236 any_correspondent: Filter to documents assigned to any of these. 237 exclude_correspondents: Exclude documents assigned to any of these. 238 document_type: Filter to documents of exactly this type. 239 Pass ``None`` to return only documents with no document type set. 240 document_type_name_contains: Case-insensitive substring filter on document type name. 241 document_type_name_exact: Case-insensitive exact match on document type name. 242 any_document_type: Filter to documents whose type is any of these. 243 exclude_document_types: Exclude documents whose type is any of these. 244 storage_path: Filter to documents assigned to this storage path. 245 Pass ``None`` to return only documents with no storage path set. 246 any_storage_paths: Filter to documents assigned to any of these paths. 247 exclude_storage_paths: Exclude documents assigned to any of these paths. 248 owner: Filter to documents owned by this user ID. 249 Pass ``None`` to return only documents with no owner set. 250 exclude_owners: Exclude documents owned by any of these user IDs. 251 custom_fields: Documents must have **all** of these custom fields set. 252 any_custom_fields: Documents must have **at least one** of these fields. 253 exclude_custom_fields: Documents must have **none** of these fields. 254 custom_field_query: Filter documents by custom field values. 255 archive_serial_number: Filter by exact archive serial number. 256 Pass ``None`` to return only documents with no ASN set. 257 archive_serial_number_from: Filter by ASN >= this value. 258 archive_serial_number_till: Filter by ASN <= this value. 259 created_after: Only documents created after this date. 260 created_before: Only documents created before this date. 261 added_after: Only documents added after this date/time. 262 added_from: Only documents added on or after this date/time. 263 added_before: Only documents added before this date/time. 264 added_until: Only documents added on or before this date/time. 265 modified_after: Only documents modified after this date/time. 266 modified_from: Only documents modified on or after this date/time. 267 modified_before: Only documents modified before this date/time. 268 modified_until: Only documents modified on or before this date/time. 269 checksum: MD5 checksum of the original file (exact match). 270 page_size: Number of results per API page. Default: ``25``. 271 page: Return only this specific page (1-based). 272 ordering: Field name to sort by. 273 descending: When ``True``, reverses the sort direction. 274 max_results: Stop after collecting this many documents. 275 on_page: Callback invoked after each page fetch. 276 277 Returns: 278 List of :class:`~easypaperless.models.documents.Document` objects. 279 """ 280 resolver = self._core._resolver 281 params: dict[str, Any] = {"page_size": page_size} 282 283 if search is not None: 284 api_param = _SEARCH_MODE_MAP.get(search_mode, "search") 285 params[api_param] = search 286 287 if ids is not None: 288 params["id__in"] = ",".join(str(i) for i in ids) 289 290 if tags is not None: 291 resolved = await resolver.resolve_list("tags", tags) 292 params["tags__id__all"] = ",".join(str(t) for t in resolved) 293 294 if any_tags is not None: 295 resolved = await resolver.resolve_list("tags", any_tags) 296 params["tags__id__in"] = ",".join(str(t) for t in resolved) 297 298 if exclude_tags is not None: 299 resolved = await resolver.resolve_list("tags", exclude_tags) 300 params["tags__id__none"] = ",".join(str(t) for t in resolved) 301 302 if any_correspondent is not None: 303 resolved = await resolver.resolve_list("correspondents", any_correspondent) 304 params["correspondent__id__in"] = ",".join(str(c) for c in resolved) 305 elif not isinstance(correspondent, _Unset): 306 if correspondent is None: 307 params["correspondent__isnull"] = "true" 308 else: 309 resolved_id = await resolver.resolve("correspondents", correspondent) 310 params["correspondent__id__in"] = resolved_id 311 312 if exclude_correspondents is not None: 313 resolved = await resolver.resolve_list("correspondents", exclude_correspondents) 314 params["correspondent__id__none"] = ",".join(str(c) for c in resolved) 315 316 if document_type_name_contains is not None: 317 params["document_type__name__icontains"] = document_type_name_contains 318 if document_type_name_exact is not None: 319 params["document_type__name__iexact"] = document_type_name_exact 320 321 if any_document_type is not None: 322 resolved = await resolver.resolve_list("document_types", any_document_type) 323 params["document_type__id__in"] = ",".join(str(d) for d in resolved) 324 elif not isinstance(document_type, _Unset): 325 if document_type is None: 326 params["document_type__isnull"] = "true" 327 else: 328 resolved_id = await resolver.resolve("document_types", document_type) 329 params["document_type"] = resolved_id 330 331 if exclude_document_types is not None: 332 resolved = await resolver.resolve_list("document_types", exclude_document_types) 333 params["document_type__id__none"] = ",".join(str(d) for d in resolved) 334 335 if any_storage_paths is not None: 336 resolved = await resolver.resolve_list("storage_paths", any_storage_paths) 337 params["storage_path__id__in"] = ",".join(str(s) for s in resolved) 338 elif not isinstance(storage_path, _Unset): 339 if storage_path is None: 340 params["storage_path__isnull"] = "true" 341 else: 342 resolved_id = await resolver.resolve("storage_paths", storage_path) 343 params["storage_path__id__in"] = resolved_id 344 345 if exclude_storage_paths is not None: 346 resolved = await resolver.resolve_list("storage_paths", exclude_storage_paths) 347 params["storage_path__id__none"] = ",".join(str(s) for s in resolved) 348 349 if not isinstance(owner, _Unset): 350 if owner is None: 351 params["owner__isnull"] = "true" 352 else: 353 params["owner__id__in"] = owner 354 355 if exclude_owners is not None: 356 params["owner__id__none"] = ",".join(str(o) for o in exclude_owners) 357 358 if custom_fields is not None: 359 resolved = await resolver.resolve_list("custom_fields", custom_fields) 360 params["custom_fields__id__all"] = ",".join(str(f) for f in resolved) 361 362 if any_custom_fields is not None: 363 resolved = await resolver.resolve_list("custom_fields", any_custom_fields) 364 params["custom_fields__id__in"] = ",".join(str(f) for f in resolved) 365 366 if exclude_custom_fields is not None: 367 resolved = await resolver.resolve_list("custom_fields", exclude_custom_fields) 368 params["custom_fields__id__none"] = ",".join(str(f) for f in resolved) 369 370 if custom_field_query is not None: 371 params["custom_field_query"] = json.dumps(custom_field_query) 372 373 if not isinstance(archive_serial_number, _Unset): 374 if archive_serial_number is None: 375 params["archive_serial_number__isnull"] = "true" 376 else: 377 params["archive_serial_number"] = archive_serial_number 378 379 if archive_serial_number_from is not None: 380 params["archive_serial_number__gte"] = archive_serial_number_from 381 382 if archive_serial_number_till is not None: 383 params["archive_serial_number__lte"] = archive_serial_number_till 384 385 if created_after is not None: 386 params["created__date__gt"] = self._format_date_value(created_after) 387 388 if created_before is not None: 389 params["created__date__lt"] = self._format_date_value(created_before) 390 391 if added_after is not None: 392 key = "added__gt" if self._is_datetime(added_after) else "added__date__gt" 393 params[key] = self._format_date_value(added_after) 394 395 if added_from is not None: 396 key = "added__gte" if self._is_datetime(added_from) else "added__date__gte" 397 params[key] = self._format_date_value(added_from) 398 399 if added_before is not None: 400 key = "added__lt" if self._is_datetime(added_before) else "added__date__lt" 401 params[key] = self._format_date_value(added_before) 402 403 if added_until is not None: 404 key = "added__lte" if self._is_datetime(added_until) else "added__date__lte" 405 params[key] = self._format_date_value(added_until) 406 407 if modified_after is not None: 408 key = "modified__gt" if self._is_datetime(modified_after) else "modified__date__gt" 409 params[key] = self._format_date_value(modified_after) 410 411 if modified_from is not None: 412 key = "modified__gte" if self._is_datetime(modified_from) else "modified__date__gte" 413 params[key] = self._format_date_value(modified_from) 414 415 if modified_before is not None: 416 key = "modified__lt" if self._is_datetime(modified_before) else "modified__date__lt" 417 params[key] = self._format_date_value(modified_before) 418 419 if modified_until is not None: 420 key = "modified__lte" if self._is_datetime(modified_until) else "modified__date__lte" 421 params[key] = self._format_date_value(modified_until) 422 423 if checksum is not None: 424 params["checksum__iexact"] = checksum 425 426 if ordering is not None: 427 params["ordering"] = f"-{ordering}" if descending else ordering 428 429 if page is not None: 430 params["page"] = page 431 resp = await self._core._session.get("/documents/", params=params) 432 items = resp.json().get("results", []) 433 if max_results is not None: 434 items = items[:max_results] 435 return [Document.model_validate(item) for item in items] 436 437 items = await self._core._session.get_all_pages( 438 "/documents/", params, max_results=max_results, on_page=on_page 439 ) 440 return [Document.model_validate(item) for item in items] 441 442 async def update( 443 self, 444 id: int, 445 *, 446 title: str | None | _Unset = UNSET, 447 content: str | None | _Unset = UNSET, 448 created: date | str | None | _Unset = UNSET, 449 correspondent: int | str | None | _Unset = UNSET, 450 document_type: int | str | None | _Unset = UNSET, 451 storage_path: int | str | None | _Unset = UNSET, 452 tags: List[int | str] | None | _Unset = UNSET, 453 archive_serial_number: int | None | _Unset = UNSET, 454 custom_fields: List[dict[str, Any]] | None | _Unset = UNSET, 455 owner: int | None | _Unset = UNSET, 456 set_permissions: SetPermissions | None | _Unset = UNSET, 457 remove_inbox_tags: bool | None | _Unset = UNSET, 458 ) -> Document: 459 """Partially update a document (PATCH semantics). 460 461 Args: 462 id: Numeric ID of the document to update. 463 title: New document title. 464 content: OCR text content of the document. 465 created: Creation date as an ISO-8601 string (``"YYYY-MM-DD"``) or a 466 :class:`~datetime.date` object. 467 correspondent: Correspondent to assign, as an ID or name. 468 Pass ``None`` to clear the correspondent. 469 document_type: Document type to assign, as an ID or name. 470 Pass ``None`` to clear the document type. 471 storage_path: Storage path to assign, as an ID or name. 472 Pass ``None`` to clear the storage path. 473 tags: Full replacement list of tags (IDs or names). 474 archive_serial_number: Archive serial number to assign. 475 Pass ``None`` to clear the archive serial number. 476 custom_fields: List of ``{"field": <field_id>, "value": ...}`` dicts. 477 owner: Numeric user ID to assign as document owner. 478 Pass ``None`` to clear the owner. 479 set_permissions: Explicit view/change permission sets. 480 remove_inbox_tags: When ``True``, removes all inbox tags from the document. 481 482 Returns: 483 The updated :class:`~easypaperless.models.documents.Document`. 484 """ 485 logger.debug("Updating document id=%d", id) 486 resolver = self._core._resolver 487 payload: dict[str, Any] = {} 488 489 if not isinstance(title, _Unset): 490 payload["title"] = title 491 if not isinstance(content, _Unset): 492 payload["content"] = content 493 if not isinstance(created, _Unset): 494 payload["created"] = self._format_date_value(created) if created is not None else None 495 if not isinstance(correspondent, _Unset): 496 payload["correspondent"] = ( 497 None 498 if correspondent is None 499 else await resolver.resolve("correspondents", correspondent) 500 ) 501 if not isinstance(document_type, _Unset): 502 payload["document_type"] = ( 503 None 504 if document_type is None 505 else await resolver.resolve("document_types", document_type) 506 ) 507 if not isinstance(storage_path, _Unset): 508 payload["storage_path"] = ( 509 None 510 if storage_path is None 511 else await resolver.resolve("storage_paths", storage_path) 512 ) 513 if not isinstance(tags, _Unset): 514 payload["tags"] = await resolver.resolve_list("tags", tags or []) 515 if not isinstance(archive_serial_number, _Unset): 516 payload["archive_serial_number"] = archive_serial_number 517 if not isinstance(custom_fields, _Unset): 518 payload["custom_fields"] = custom_fields 519 if not isinstance(owner, _Unset): 520 payload["owner"] = owner 521 if not isinstance(set_permissions, _Unset): 522 payload["set_permissions"] = (set_permissions or SetPermissions()).model_dump() 523 if not isinstance(remove_inbox_tags, _Unset): 524 payload["remove_inbox_tags"] = remove_inbox_tags 525 526 resp = await self._core._session.patch(f"/documents/{id}/", json=payload) 527 return Document.model_validate(resp.json()) 528 529 async def delete(self, id: int) -> None: 530 """Permanently delete a document. 531 532 Args: 533 id: Numeric ID of the document to delete. 534 535 Raises: 536 ~easypaperless.exceptions.NotFoundError: If no document exists 537 with that ID. 538 """ 539 logger.debug("Deleting document id=%d", id) 540 await self._core._session.delete(f"/documents/{id}/") 541 542 async def download(self, id: int, *, original: bool = False) -> bytes: 543 """Download the binary content of a document. 544 545 Args: 546 id: Numeric ID of the document to download. 547 original: If ``False`` *(default)*, returns the archived PDF. 548 If ``True``, returns the original uploaded file. 549 550 Returns: 551 Raw file bytes. 552 """ 553 endpoint = "download" if original else "archive" 554 resp = await self._core._session.get_download(f"/documents/{id}/{endpoint}/") 555 content_type = resp.headers.get("content-type", "") 556 if "text/html" in content_type or resp.content[:9].lower().startswith(b"<!doctype"): 557 raise ServerError( 558 f"Download returned an HTML page (content-type: {content_type!r}). " 559 "The server redirected to a login page even after re-attaching auth.", 560 status_code=None, 561 ) 562 return resp.content 563 564 async def upload( 565 self, 566 file: str | Path, 567 *, 568 title: str | None = None, 569 created: date | str | None = None, 570 correspondent: int | str | None | _Unset = UNSET, 571 document_type: int | str | None | _Unset = UNSET, 572 storage_path: int | str | None | _Unset = UNSET, 573 tags: List[int | str] | None = None, 574 archive_serial_number: int | None | _Unset = UNSET, 575 custom_fields: List[dict[str, Any]] | None = None, 576 wait: bool = False, 577 poll_interval: float | None = None, 578 poll_timeout: float | None = None, 579 ) -> str | Document: 580 """Upload a document to paperless-ngx. 581 582 Args: 583 file: Path to the file to upload. 584 title: Title to assign to the document. 585 created: Creation date as an ISO-8601 string (``"YYYY-MM-DD"``) or a 586 :class:`~datetime.date` object. 587 correspondent: Correspondent to assign, as an ID or name. 588 document_type: Document type to assign, as an ID or name. 589 storage_path: Storage path to assign, as an ID or name. 590 tags: Tags to assign, as IDs or names. 591 archive_serial_number: Archive serial number to assign. 592 custom_fields: List of ``{"field": <field_id>, "value": ...}`` dicts. 593 wait: If ``False`` *(default)*, returns immediately with the task ID. 594 If ``True``, polls until processing completes. 595 poll_interval: Override the client-level ``poll_interval`` (in seconds). 596 poll_timeout: Override the client-level ``poll_timeout`` (in seconds). 597 598 Returns: 599 The Celery task ID string when ``wait=False``, or the fully 600 processed :class:`~easypaperless.models.documents.Document` 601 when ``wait=True``. 602 603 Raises: 604 ~easypaperless.exceptions.UploadError: If processing fails. 605 ~easypaperless.exceptions.TaskTimeoutError: If timeout is exceeded. 606 """ 607 resolver = self._core._resolver 608 file_path = Path(file) 609 file_bytes = file_path.read_bytes() 610 logger.info("Uploading %r (%d bytes)", file_path.name, len(file_bytes)) 611 612 data: dict[str, Any] = {} 613 if title is not None: 614 data["title"] = title 615 if created is not None: 616 data["created"] = self._format_date_value(created) 617 if not isinstance(correspondent, _Unset) and correspondent is not None: 618 data["correspondent"] = await resolver.resolve("correspondents", correspondent) 619 if not isinstance(document_type, _Unset) and document_type is not None: 620 data["document_type"] = await resolver.resolve("document_types", document_type) 621 if not isinstance(storage_path, _Unset) and storage_path is not None: 622 data["storage_path"] = await resolver.resolve("storage_paths", storage_path) 623 if tags is not None: 624 resolved = await resolver.resolve_list("tags", tags) 625 data["tags"] = resolved 626 if not isinstance(archive_serial_number, _Unset) and archive_serial_number is not None: 627 data["archive_serial_number"] = archive_serial_number 628 if custom_fields is not None: 629 data["custom_fields"] = json.dumps(custom_fields) 630 631 files = {"document": (file_path.name, file_bytes)} 632 resp = await self._core._session.post("/documents/post_document/", data=data, files=files) 633 task_id: str = resp.text.strip('"') 634 logger.debug("Upload accepted, task_id=%r", task_id) 635 636 if not wait: 637 return task_id 638 639 interval = poll_interval if poll_interval is not None else self._core._poll_interval 640 timeout = poll_timeout if poll_timeout is not None else self._core._poll_timeout 641 return await self._poll_task(task_id, poll_interval=interval, poll_timeout=timeout) 642 643 async def _poll_task( 644 self, task_id: str, *, poll_interval: float, poll_timeout: float 645 ) -> Document: 646 start = time.monotonic() 647 deadline = start + poll_timeout 648 while time.monotonic() < deadline: 649 resp = await self._core._session.get("/tasks/", params={"task_id": task_id}) 650 tasks = resp.json() 651 if not tasks: 652 await asyncio.sleep(poll_interval) 653 continue 654 655 task = Task.model_validate(tasks[0]) 656 elapsed = time.monotonic() - start 657 logger.debug( 658 "Polling task %r (status=%s, elapsed=%.1fs)", 659 task_id, 660 task.status.value if task.status is not None else "unknown", 661 elapsed, 662 ) 663 if task.status == TaskStatus.SUCCESS: 664 if task.related_document is None: 665 raise UploadError(f"Task {task_id!r} succeeded but returned no document ID") 666 doc_id = int(task.related_document) 667 logger.info("Task %r succeeded, document_id=%d", task_id, doc_id) 668 return await self.get(doc_id) 669 elif task.status == TaskStatus.FAILURE: 670 logger.warning("Task %r failed: %s", task_id, task.result) 671 raise UploadError(f"Document processing failed: {task.result}") 672 elif task.status == TaskStatus.REVOKED: 673 logger.warning("Task %r was revoked", task_id) 674 raise UploadError(f"Task {task_id!r} was revoked") 675 await asyncio.sleep(poll_interval) 676 677 elapsed = time.monotonic() - start 678 logger.warning("Task %r timed out after %.1fs", task_id, elapsed) 679 raise TaskTimeoutError(f"Task {task_id!r} did not complete within {poll_timeout}s") 680 681 # ------------------------------------------------------------------------- 682 # Document bulk operations 683 # ------------------------------------------------------------------------- 684 685 async def _bulk_edit(self, document_ids: List[int], method: str, **parameters: Any) -> None: 686 """Execute a bulk-edit operation on a list of documents. 687 688 Args: 689 document_ids: List of document IDs to operate on. 690 method: Bulk-edit method name (e.g. ``"add_tag"``, ``"delete"``). 691 **parameters: Additional keyword arguments forwarded to the API. 692 """ 693 payload = {"documents": document_ids, "method": method, "parameters": parameters} 694 await self._core._session.post("/documents/bulk_edit/", json=payload, timeout=120.0) 695 696 async def bulk_add_tag(self, document_ids: List[int], tag: int | str) -> None: 697 """Add a tag to multiple documents in a single request. 698 699 Args: 700 document_ids: List of document IDs to tag. 701 tag: Tag to add, as an ID or name. 702 """ 703 tag_id = await self._core._resolver.resolve("tags", tag) 704 await self._bulk_edit(document_ids, "add_tag", tag=tag_id) 705 706 async def bulk_remove_tag(self, document_ids: List[int], tag: int | str) -> None: 707 """Remove a tag from multiple documents in a single request. 708 709 Args: 710 document_ids: List of document IDs to un-tag. 711 tag: Tag to remove, as an ID or name. 712 """ 713 tag_id = await self._core._resolver.resolve("tags", tag) 714 await self._bulk_edit(document_ids, "remove_tag", tag=tag_id) 715 716 async def bulk_modify_tags( 717 self, 718 document_ids: List[int], 719 *, 720 add_tags: List[int | str] | None = None, 721 remove_tags: List[int | str] | None = None, 722 ) -> None: 723 """Add and/or remove tags on multiple documents atomically. 724 725 Args: 726 document_ids: List of document IDs to modify. 727 add_tags: Tags to add, as IDs or names. 728 remove_tags: Tags to remove, as IDs or names. 729 """ 730 resolver = self._core._resolver 731 add_ids = await resolver.resolve_list("tags", add_tags or []) 732 remove_ids = await resolver.resolve_list("tags", remove_tags or []) 733 await self._bulk_edit(document_ids, "modify_tags", add_tags=add_ids, remove_tags=remove_ids) 734 735 async def bulk_delete(self, document_ids: List[int]) -> None: 736 """Permanently delete multiple documents in a single request. 737 738 Args: 739 document_ids: List of document IDs to delete. 740 """ 741 await self._bulk_edit(document_ids, "delete") 742 743 async def bulk_set_correspondent( 744 self, document_ids: List[int], correspondent: int | str | None 745 ) -> None: 746 """Assign a correspondent to multiple documents in a single request. 747 748 Args: 749 document_ids: List of document IDs to modify. 750 correspondent: Correspondent to assign, as an ID or name. 751 Pass ``None`` to clear. 752 """ 753 cor_id: int | None = None 754 if correspondent is not None: 755 cor_id = await self._core._resolver.resolve("correspondents", correspondent) 756 await self._bulk_edit(document_ids, "set_correspondent", correspondent=cor_id) 757 758 async def bulk_set_document_type( 759 self, document_ids: List[int], document_type: int | str | None 760 ) -> None: 761 """Assign a document type to multiple documents in a single request. 762 763 Args: 764 document_ids: List of document IDs to modify. 765 document_type: Document type to assign, as an ID or name. 766 Pass ``None`` to clear. 767 """ 768 dt_id: int | None = None 769 if document_type is not None: 770 dt_id = await self._core._resolver.resolve("document_types", document_type) 771 await self._bulk_edit(document_ids, "set_document_type", document_type=dt_id) 772 773 async def bulk_set_storage_path( 774 self, document_ids: List[int], storage_path: int | str | None 775 ) -> None: 776 """Assign a storage path to multiple documents in a single request. 777 778 Args: 779 document_ids: List of document IDs to modify. 780 storage_path: Storage path to assign, as an ID or name. 781 Pass ``None`` to clear. 782 """ 783 sp_id: int | None = None 784 if storage_path is not None: 785 sp_id = await self._core._resolver.resolve("storage_paths", storage_path) 786 await self._bulk_edit(document_ids, "set_storage_path", storage_path=sp_id) 787 788 async def bulk_modify_custom_fields( 789 self, 790 document_ids: List[int], 791 *, 792 add_fields: List[dict[str, Any]] | None = None, 793 remove_fields: List[int] | None = None, 794 ) -> None: 795 """Add and/or remove custom field values on multiple documents. 796 797 Args: 798 document_ids: List of document IDs to modify. 799 add_fields: Custom-field value dicts to add. 800 remove_fields: Custom-field IDs whose values should be removed. 801 """ 802 await self._bulk_edit( 803 document_ids, 804 "modify_custom_fields", 805 add_custom_fields=add_fields or [], 806 remove_custom_fields=remove_fields or [], 807 ) 808 809 async def bulk_set_permissions( 810 self, 811 document_ids: List[int], 812 *, 813 set_permissions: SetPermissions | None = None, 814 owner: int | None = None, 815 merge: bool = False, 816 ) -> None: 817 """Set permissions and/or owner on multiple documents. 818 819 Args: 820 document_ids: List of document IDs to modify. 821 set_permissions: Explicit view/change permission sets. 822 owner: Numeric user ID to assign as document owner. 823 merge: When ``True``, new permissions are merged with existing ones. 824 """ 825 params: dict[str, Any] = {"merge": merge} 826 if set_permissions is not None: 827 params["set_permissions"] = set_permissions.model_dump() 828 if owner is not None: 829 params["owner"] = owner 830 await self._bulk_edit(document_ids, "set_permissions", **params)
Accessor for documents: client.documents.
128 async def get(self, id: int, *, include_metadata: bool = False) -> Document: 129 """Fetch a single document by its ID. 130 131 Args: 132 id: Numeric paperless-ngx document ID. 133 include_metadata: When ``True``, the extended file-level metadata 134 is fetched concurrently and attached to the document. 135 Default: ``False``. 136 137 Returns: 138 The :class:`~easypaperless.models.documents.Document` with the 139 given ID. 140 141 Raises: 142 ~easypaperless.exceptions.NotFoundError: If no document exists 143 with that ID. 144 """ 145 if include_metadata: 146 doc_resp, meta_resp = await asyncio.gather( 147 self._core._session.get(f"/documents/{id}/"), 148 self._core._session.get(f"/documents/{id}/metadata/"), 149 ) 150 data = doc_resp.json() 151 data["metadata"] = meta_resp.json() 152 else: 153 resp = await self._core._session.get(f"/documents/{id}/") 154 data = resp.json() 155 return Document.model_validate(data)
Fetch a single document by its ID.
Arguments:
- id: Numeric paperless-ngx document ID.
- include_metadata: When
True, the extended file-level metadata is fetched concurrently and attached to the document. Default:False.
Returns:
The
~easypaperless.models.documents.Documentwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
157 async def get_metadata(self, id: int) -> DocumentMetadata: 158 """Fetch the extended file-level metadata for a document. 159 160 Args: 161 id: Numeric paperless-ngx document ID. 162 163 Returns: 164 A :class:`~easypaperless.models.documents.DocumentMetadata` instance. 165 166 Raises: 167 ~easypaperless.exceptions.NotFoundError: If no document exists 168 with that ID. 169 """ 170 resp = await self._core._session.get(f"/documents/{id}/metadata/") 171 return DocumentMetadata.model_validate(resp.json())
Fetch the extended file-level metadata for a document.
Arguments:
- id: Numeric paperless-ngx document ID.
Returns:
A
~easypaperless.models.documents.DocumentMetadatainstance.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
173 async def list( 174 self, 175 *, 176 search: str | None = None, 177 search_mode: str = "title_or_content", 178 ids: List[int] | None = None, 179 tags: List[int | str] | None = None, 180 any_tags: List[int | str] | None = None, 181 exclude_tags: List[int | str] | None = None, 182 correspondent: int | str | None | _Unset = UNSET, 183 any_correspondent: List[int | str] | None = None, 184 exclude_correspondents: List[int | str] | None = None, 185 document_type: int | str | None | _Unset = UNSET, 186 document_type_name_contains: str | None = None, 187 document_type_name_exact: str | None = None, 188 any_document_type: List[int | str] | None = None, 189 exclude_document_types: List[int | str] | None = None, 190 storage_path: int | str | None | _Unset = UNSET, 191 any_storage_paths: List[int | str] | None = None, 192 exclude_storage_paths: List[int | str] | None = None, 193 owner: int | None | _Unset = UNSET, 194 exclude_owners: List[int] | None = None, 195 custom_fields: List[int | str] | None = None, 196 any_custom_fields: List[int | str] | None = None, 197 exclude_custom_fields: List[int | str] | None = None, 198 custom_field_query: List[Any] | None = None, 199 archive_serial_number: int | None | _Unset = UNSET, 200 archive_serial_number_from: int | None = None, 201 archive_serial_number_till: int | None = None, 202 created_after: date | str | None = None, 203 created_before: date | str | None = None, 204 added_after: date | datetime | str | None = None, 205 added_from: date | datetime | str | None = None, 206 added_before: date | datetime | str | None = None, 207 added_until: date | datetime | str | None = None, 208 modified_after: date | datetime | str | None = None, 209 modified_from: date | datetime | str | None = None, 210 modified_before: date | datetime | str | None = None, 211 modified_until: date | datetime | str | None = None, 212 checksum: str | None = None, 213 page_size: int = 25, 214 page: int | None = None, 215 ordering: str | None = None, 216 descending: bool = False, 217 max_results: int | None = None, 218 on_page: Callable[[int, int | None], None] | None = None, 219 ) -> List[Document]: 220 """Return a filtered list of documents. 221 222 All tag, correspondent, document-type, storage-path, and custom-field 223 parameters accept either integer IDs or string names. 224 225 Args: 226 search: Search string. Behaviour depends on ``search_mode``. 227 search_mode: How ``search`` is applied. One of: 228 ``"title_or_content"`` *(default)*, ``"title"``, ``"query"``, 229 ``"original_filename"``. 230 ids: Return only documents whose ID is in this list. 231 tags: Documents must have **all** of these tags (AND semantics). 232 any_tags: Documents must have **at least one** of these tags. 233 exclude_tags: Documents must have **none** of these tags. 234 correspondent: Filter to documents assigned to this correspondent. 235 Pass ``None`` to return only documents with no correspondent set. 236 any_correspondent: Filter to documents assigned to any of these. 237 exclude_correspondents: Exclude documents assigned to any of these. 238 document_type: Filter to documents of exactly this type. 239 Pass ``None`` to return only documents with no document type set. 240 document_type_name_contains: Case-insensitive substring filter on document type name. 241 document_type_name_exact: Case-insensitive exact match on document type name. 242 any_document_type: Filter to documents whose type is any of these. 243 exclude_document_types: Exclude documents whose type is any of these. 244 storage_path: Filter to documents assigned to this storage path. 245 Pass ``None`` to return only documents with no storage path set. 246 any_storage_paths: Filter to documents assigned to any of these paths. 247 exclude_storage_paths: Exclude documents assigned to any of these paths. 248 owner: Filter to documents owned by this user ID. 249 Pass ``None`` to return only documents with no owner set. 250 exclude_owners: Exclude documents owned by any of these user IDs. 251 custom_fields: Documents must have **all** of these custom fields set. 252 any_custom_fields: Documents must have **at least one** of these fields. 253 exclude_custom_fields: Documents must have **none** of these fields. 254 custom_field_query: Filter documents by custom field values. 255 archive_serial_number: Filter by exact archive serial number. 256 Pass ``None`` to return only documents with no ASN set. 257 archive_serial_number_from: Filter by ASN >= this value. 258 archive_serial_number_till: Filter by ASN <= this value. 259 created_after: Only documents created after this date. 260 created_before: Only documents created before this date. 261 added_after: Only documents added after this date/time. 262 added_from: Only documents added on or after this date/time. 263 added_before: Only documents added before this date/time. 264 added_until: Only documents added on or before this date/time. 265 modified_after: Only documents modified after this date/time. 266 modified_from: Only documents modified on or after this date/time. 267 modified_before: Only documents modified before this date/time. 268 modified_until: Only documents modified on or before this date/time. 269 checksum: MD5 checksum of the original file (exact match). 270 page_size: Number of results per API page. Default: ``25``. 271 page: Return only this specific page (1-based). 272 ordering: Field name to sort by. 273 descending: When ``True``, reverses the sort direction. 274 max_results: Stop after collecting this many documents. 275 on_page: Callback invoked after each page fetch. 276 277 Returns: 278 List of :class:`~easypaperless.models.documents.Document` objects. 279 """ 280 resolver = self._core._resolver 281 params: dict[str, Any] = {"page_size": page_size} 282 283 if search is not None: 284 api_param = _SEARCH_MODE_MAP.get(search_mode, "search") 285 params[api_param] = search 286 287 if ids is not None: 288 params["id__in"] = ",".join(str(i) for i in ids) 289 290 if tags is not None: 291 resolved = await resolver.resolve_list("tags", tags) 292 params["tags__id__all"] = ",".join(str(t) for t in resolved) 293 294 if any_tags is not None: 295 resolved = await resolver.resolve_list("tags", any_tags) 296 params["tags__id__in"] = ",".join(str(t) for t in resolved) 297 298 if exclude_tags is not None: 299 resolved = await resolver.resolve_list("tags", exclude_tags) 300 params["tags__id__none"] = ",".join(str(t) for t in resolved) 301 302 if any_correspondent is not None: 303 resolved = await resolver.resolve_list("correspondents", any_correspondent) 304 params["correspondent__id__in"] = ",".join(str(c) for c in resolved) 305 elif not isinstance(correspondent, _Unset): 306 if correspondent is None: 307 params["correspondent__isnull"] = "true" 308 else: 309 resolved_id = await resolver.resolve("correspondents", correspondent) 310 params["correspondent__id__in"] = resolved_id 311 312 if exclude_correspondents is not None: 313 resolved = await resolver.resolve_list("correspondents", exclude_correspondents) 314 params["correspondent__id__none"] = ",".join(str(c) for c in resolved) 315 316 if document_type_name_contains is not None: 317 params["document_type__name__icontains"] = document_type_name_contains 318 if document_type_name_exact is not None: 319 params["document_type__name__iexact"] = document_type_name_exact 320 321 if any_document_type is not None: 322 resolved = await resolver.resolve_list("document_types", any_document_type) 323 params["document_type__id__in"] = ",".join(str(d) for d in resolved) 324 elif not isinstance(document_type, _Unset): 325 if document_type is None: 326 params["document_type__isnull"] = "true" 327 else: 328 resolved_id = await resolver.resolve("document_types", document_type) 329 params["document_type"] = resolved_id 330 331 if exclude_document_types is not None: 332 resolved = await resolver.resolve_list("document_types", exclude_document_types) 333 params["document_type__id__none"] = ",".join(str(d) for d in resolved) 334 335 if any_storage_paths is not None: 336 resolved = await resolver.resolve_list("storage_paths", any_storage_paths) 337 params["storage_path__id__in"] = ",".join(str(s) for s in resolved) 338 elif not isinstance(storage_path, _Unset): 339 if storage_path is None: 340 params["storage_path__isnull"] = "true" 341 else: 342 resolved_id = await resolver.resolve("storage_paths", storage_path) 343 params["storage_path__id__in"] = resolved_id 344 345 if exclude_storage_paths is not None: 346 resolved = await resolver.resolve_list("storage_paths", exclude_storage_paths) 347 params["storage_path__id__none"] = ",".join(str(s) for s in resolved) 348 349 if not isinstance(owner, _Unset): 350 if owner is None: 351 params["owner__isnull"] = "true" 352 else: 353 params["owner__id__in"] = owner 354 355 if exclude_owners is not None: 356 params["owner__id__none"] = ",".join(str(o) for o in exclude_owners) 357 358 if custom_fields is not None: 359 resolved = await resolver.resolve_list("custom_fields", custom_fields) 360 params["custom_fields__id__all"] = ",".join(str(f) for f in resolved) 361 362 if any_custom_fields is not None: 363 resolved = await resolver.resolve_list("custom_fields", any_custom_fields) 364 params["custom_fields__id__in"] = ",".join(str(f) for f in resolved) 365 366 if exclude_custom_fields is not None: 367 resolved = await resolver.resolve_list("custom_fields", exclude_custom_fields) 368 params["custom_fields__id__none"] = ",".join(str(f) for f in resolved) 369 370 if custom_field_query is not None: 371 params["custom_field_query"] = json.dumps(custom_field_query) 372 373 if not isinstance(archive_serial_number, _Unset): 374 if archive_serial_number is None: 375 params["archive_serial_number__isnull"] = "true" 376 else: 377 params["archive_serial_number"] = archive_serial_number 378 379 if archive_serial_number_from is not None: 380 params["archive_serial_number__gte"] = archive_serial_number_from 381 382 if archive_serial_number_till is not None: 383 params["archive_serial_number__lte"] = archive_serial_number_till 384 385 if created_after is not None: 386 params["created__date__gt"] = self._format_date_value(created_after) 387 388 if created_before is not None: 389 params["created__date__lt"] = self._format_date_value(created_before) 390 391 if added_after is not None: 392 key = "added__gt" if self._is_datetime(added_after) else "added__date__gt" 393 params[key] = self._format_date_value(added_after) 394 395 if added_from is not None: 396 key = "added__gte" if self._is_datetime(added_from) else "added__date__gte" 397 params[key] = self._format_date_value(added_from) 398 399 if added_before is not None: 400 key = "added__lt" if self._is_datetime(added_before) else "added__date__lt" 401 params[key] = self._format_date_value(added_before) 402 403 if added_until is not None: 404 key = "added__lte" if self._is_datetime(added_until) else "added__date__lte" 405 params[key] = self._format_date_value(added_until) 406 407 if modified_after is not None: 408 key = "modified__gt" if self._is_datetime(modified_after) else "modified__date__gt" 409 params[key] = self._format_date_value(modified_after) 410 411 if modified_from is not None: 412 key = "modified__gte" if self._is_datetime(modified_from) else "modified__date__gte" 413 params[key] = self._format_date_value(modified_from) 414 415 if modified_before is not None: 416 key = "modified__lt" if self._is_datetime(modified_before) else "modified__date__lt" 417 params[key] = self._format_date_value(modified_before) 418 419 if modified_until is not None: 420 key = "modified__lte" if self._is_datetime(modified_until) else "modified__date__lte" 421 params[key] = self._format_date_value(modified_until) 422 423 if checksum is not None: 424 params["checksum__iexact"] = checksum 425 426 if ordering is not None: 427 params["ordering"] = f"-{ordering}" if descending else ordering 428 429 if page is not None: 430 params["page"] = page 431 resp = await self._core._session.get("/documents/", params=params) 432 items = resp.json().get("results", []) 433 if max_results is not None: 434 items = items[:max_results] 435 return [Document.model_validate(item) for item in items] 436 437 items = await self._core._session.get_all_pages( 438 "/documents/", params, max_results=max_results, on_page=on_page 439 ) 440 return [Document.model_validate(item) for item in items]
Return a filtered list of documents.
All tag, correspondent, document-type, storage-path, and custom-field parameters accept either integer IDs or string names.
Arguments:
- search: Search string. Behaviour depends on
search_mode. - search_mode: How
searchis applied. One of:"title_or_content"(default),"title","query","original_filename". - ids: Return only documents whose ID is in this list.
- tags: Documents must have all of these tags (AND semantics).
- any_tags: Documents must have at least one of these tags.
- exclude_tags: Documents must have none of these tags.
- correspondent: Filter to documents assigned to this correspondent.
Pass
Noneto return only documents with no correspondent set. - any_correspondent: Filter to documents assigned to any of these.
- exclude_correspondents: Exclude documents assigned to any of these.
- document_type: Filter to documents of exactly this type.
Pass
Noneto return only documents with no document type set. - document_type_name_contains: Case-insensitive substring filter on document type name.
- document_type_name_exact: Case-insensitive exact match on document type name.
- any_document_type: Filter to documents whose type is any of these.
- exclude_document_types: Exclude documents whose type is any of these.
- storage_path: Filter to documents assigned to this storage path.
Pass
Noneto return only documents with no storage path set. - any_storage_paths: Filter to documents assigned to any of these paths.
- exclude_storage_paths: Exclude documents assigned to any of these paths.
- owner: Filter to documents owned by this user ID.
Pass
Noneto return only documents with no owner set. - exclude_owners: Exclude documents owned by any of these user IDs.
- custom_fields: Documents must have all of these custom fields set.
- any_custom_fields: Documents must have at least one of these fields.
- exclude_custom_fields: Documents must have none of these fields.
- custom_field_query: Filter documents by custom field values.
- archive_serial_number: Filter by exact archive serial number.
Pass
Noneto return only documents with no ASN set. - archive_serial_number_from: Filter by ASN >= this value.
- archive_serial_number_till: Filter by ASN <= this value.
- created_after: Only documents created after this date.
- created_before: Only documents created before this date.
- added_after: Only documents added after this date/time.
- added_from: Only documents added on or after this date/time.
- added_before: Only documents added before this date/time.
- added_until: Only documents added on or before this date/time.
- modified_after: Only documents modified after this date/time.
- modified_from: Only documents modified on or after this date/time.
- modified_before: Only documents modified before this date/time.
- modified_until: Only documents modified on or before this date/time.
- checksum: MD5 checksum of the original file (exact match).
- page_size: Number of results per API page. Default:
25. - page: Return only this specific page (1-based).
- ordering: Field name to sort by.
- descending: When
True, reverses the sort direction. - max_results: Stop after collecting this many documents.
- on_page: Callback invoked after each page fetch.
Returns:
List of
~easypaperless.models.documents.Documentobjects.
442 async def update( 443 self, 444 id: int, 445 *, 446 title: str | None | _Unset = UNSET, 447 content: str | None | _Unset = UNSET, 448 created: date | str | None | _Unset = UNSET, 449 correspondent: int | str | None | _Unset = UNSET, 450 document_type: int | str | None | _Unset = UNSET, 451 storage_path: int | str | None | _Unset = UNSET, 452 tags: List[int | str] | None | _Unset = UNSET, 453 archive_serial_number: int | None | _Unset = UNSET, 454 custom_fields: List[dict[str, Any]] | None | _Unset = UNSET, 455 owner: int | None | _Unset = UNSET, 456 set_permissions: SetPermissions | None | _Unset = UNSET, 457 remove_inbox_tags: bool | None | _Unset = UNSET, 458 ) -> Document: 459 """Partially update a document (PATCH semantics). 460 461 Args: 462 id: Numeric ID of the document to update. 463 title: New document title. 464 content: OCR text content of the document. 465 created: Creation date as an ISO-8601 string (``"YYYY-MM-DD"``) or a 466 :class:`~datetime.date` object. 467 correspondent: Correspondent to assign, as an ID or name. 468 Pass ``None`` to clear the correspondent. 469 document_type: Document type to assign, as an ID or name. 470 Pass ``None`` to clear the document type. 471 storage_path: Storage path to assign, as an ID or name. 472 Pass ``None`` to clear the storage path. 473 tags: Full replacement list of tags (IDs or names). 474 archive_serial_number: Archive serial number to assign. 475 Pass ``None`` to clear the archive serial number. 476 custom_fields: List of ``{"field": <field_id>, "value": ...}`` dicts. 477 owner: Numeric user ID to assign as document owner. 478 Pass ``None`` to clear the owner. 479 set_permissions: Explicit view/change permission sets. 480 remove_inbox_tags: When ``True``, removes all inbox tags from the document. 481 482 Returns: 483 The updated :class:`~easypaperless.models.documents.Document`. 484 """ 485 logger.debug("Updating document id=%d", id) 486 resolver = self._core._resolver 487 payload: dict[str, Any] = {} 488 489 if not isinstance(title, _Unset): 490 payload["title"] = title 491 if not isinstance(content, _Unset): 492 payload["content"] = content 493 if not isinstance(created, _Unset): 494 payload["created"] = self._format_date_value(created) if created is not None else None 495 if not isinstance(correspondent, _Unset): 496 payload["correspondent"] = ( 497 None 498 if correspondent is None 499 else await resolver.resolve("correspondents", correspondent) 500 ) 501 if not isinstance(document_type, _Unset): 502 payload["document_type"] = ( 503 None 504 if document_type is None 505 else await resolver.resolve("document_types", document_type) 506 ) 507 if not isinstance(storage_path, _Unset): 508 payload["storage_path"] = ( 509 None 510 if storage_path is None 511 else await resolver.resolve("storage_paths", storage_path) 512 ) 513 if not isinstance(tags, _Unset): 514 payload["tags"] = await resolver.resolve_list("tags", tags or []) 515 if not isinstance(archive_serial_number, _Unset): 516 payload["archive_serial_number"] = archive_serial_number 517 if not isinstance(custom_fields, _Unset): 518 payload["custom_fields"] = custom_fields 519 if not isinstance(owner, _Unset): 520 payload["owner"] = owner 521 if not isinstance(set_permissions, _Unset): 522 payload["set_permissions"] = (set_permissions or SetPermissions()).model_dump() 523 if not isinstance(remove_inbox_tags, _Unset): 524 payload["remove_inbox_tags"] = remove_inbox_tags 525 526 resp = await self._core._session.patch(f"/documents/{id}/", json=payload) 527 return Document.model_validate(resp.json())
Partially update a document (PATCH semantics).
Arguments:
- id: Numeric ID of the document to update.
- title: New document title.
- content: OCR text content of the document.
- created: Creation date as an ISO-8601 string (
"YYYY-MM-DD") or a~datetime.dateobject. - correspondent: Correspondent to assign, as an ID or name.
Pass
Noneto clear the correspondent. - document_type: Document type to assign, as an ID or name.
Pass
Noneto clear the document type. - storage_path: Storage path to assign, as an ID or name.
Pass
Noneto clear the storage path. - tags: Full replacement list of tags (IDs or names).
- archive_serial_number: Archive serial number to assign.
Pass
Noneto clear the archive serial number. - custom_fields: List of
{"field": <field_id>, "value": ...}dicts. - owner: Numeric user ID to assign as document owner.
Pass
Noneto clear the owner. - set_permissions: Explicit view/change permission sets.
- remove_inbox_tags: When
True, removes all inbox tags from the document.
Returns:
The updated
~easypaperless.models.documents.Document.
529 async def delete(self, id: int) -> None: 530 """Permanently delete a document. 531 532 Args: 533 id: Numeric ID of the document to delete. 534 535 Raises: 536 ~easypaperless.exceptions.NotFoundError: If no document exists 537 with that ID. 538 """ 539 logger.debug("Deleting document id=%d", id) 540 await self._core._session.delete(f"/documents/{id}/")
Permanently delete a document.
Arguments:
- id: Numeric ID of the document to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
542 async def download(self, id: int, *, original: bool = False) -> bytes: 543 """Download the binary content of a document. 544 545 Args: 546 id: Numeric ID of the document to download. 547 original: If ``False`` *(default)*, returns the archived PDF. 548 If ``True``, returns the original uploaded file. 549 550 Returns: 551 Raw file bytes. 552 """ 553 endpoint = "download" if original else "archive" 554 resp = await self._core._session.get_download(f"/documents/{id}/{endpoint}/") 555 content_type = resp.headers.get("content-type", "") 556 if "text/html" in content_type or resp.content[:9].lower().startswith(b"<!doctype"): 557 raise ServerError( 558 f"Download returned an HTML page (content-type: {content_type!r}). " 559 "The server redirected to a login page even after re-attaching auth.", 560 status_code=None, 561 ) 562 return resp.content
Download the binary content of a document.
Arguments:
- id: Numeric ID of the document to download.
- original: If
False(default), returns the archived PDF. IfTrue, returns the original uploaded file.
Returns:
Raw file bytes.
564 async def upload( 565 self, 566 file: str | Path, 567 *, 568 title: str | None = None, 569 created: date | str | None = None, 570 correspondent: int | str | None | _Unset = UNSET, 571 document_type: int | str | None | _Unset = UNSET, 572 storage_path: int | str | None | _Unset = UNSET, 573 tags: List[int | str] | None = None, 574 archive_serial_number: int | None | _Unset = UNSET, 575 custom_fields: List[dict[str, Any]] | None = None, 576 wait: bool = False, 577 poll_interval: float | None = None, 578 poll_timeout: float | None = None, 579 ) -> str | Document: 580 """Upload a document to paperless-ngx. 581 582 Args: 583 file: Path to the file to upload. 584 title: Title to assign to the document. 585 created: Creation date as an ISO-8601 string (``"YYYY-MM-DD"``) or a 586 :class:`~datetime.date` object. 587 correspondent: Correspondent to assign, as an ID or name. 588 document_type: Document type to assign, as an ID or name. 589 storage_path: Storage path to assign, as an ID or name. 590 tags: Tags to assign, as IDs or names. 591 archive_serial_number: Archive serial number to assign. 592 custom_fields: List of ``{"field": <field_id>, "value": ...}`` dicts. 593 wait: If ``False`` *(default)*, returns immediately with the task ID. 594 If ``True``, polls until processing completes. 595 poll_interval: Override the client-level ``poll_interval`` (in seconds). 596 poll_timeout: Override the client-level ``poll_timeout`` (in seconds). 597 598 Returns: 599 The Celery task ID string when ``wait=False``, or the fully 600 processed :class:`~easypaperless.models.documents.Document` 601 when ``wait=True``. 602 603 Raises: 604 ~easypaperless.exceptions.UploadError: If processing fails. 605 ~easypaperless.exceptions.TaskTimeoutError: If timeout is exceeded. 606 """ 607 resolver = self._core._resolver 608 file_path = Path(file) 609 file_bytes = file_path.read_bytes() 610 logger.info("Uploading %r (%d bytes)", file_path.name, len(file_bytes)) 611 612 data: dict[str, Any] = {} 613 if title is not None: 614 data["title"] = title 615 if created is not None: 616 data["created"] = self._format_date_value(created) 617 if not isinstance(correspondent, _Unset) and correspondent is not None: 618 data["correspondent"] = await resolver.resolve("correspondents", correspondent) 619 if not isinstance(document_type, _Unset) and document_type is not None: 620 data["document_type"] = await resolver.resolve("document_types", document_type) 621 if not isinstance(storage_path, _Unset) and storage_path is not None: 622 data["storage_path"] = await resolver.resolve("storage_paths", storage_path) 623 if tags is not None: 624 resolved = await resolver.resolve_list("tags", tags) 625 data["tags"] = resolved 626 if not isinstance(archive_serial_number, _Unset) and archive_serial_number is not None: 627 data["archive_serial_number"] = archive_serial_number 628 if custom_fields is not None: 629 data["custom_fields"] = json.dumps(custom_fields) 630 631 files = {"document": (file_path.name, file_bytes)} 632 resp = await self._core._session.post("/documents/post_document/", data=data, files=files) 633 task_id: str = resp.text.strip('"') 634 logger.debug("Upload accepted, task_id=%r", task_id) 635 636 if not wait: 637 return task_id 638 639 interval = poll_interval if poll_interval is not None else self._core._poll_interval 640 timeout = poll_timeout if poll_timeout is not None else self._core._poll_timeout 641 return await self._poll_task(task_id, poll_interval=interval, poll_timeout=timeout)
Upload a document to paperless-ngx.
Arguments:
- file: Path to the file to upload.
- title: Title to assign to the document.
- created: Creation date as an ISO-8601 string (
"YYYY-MM-DD") or a~datetime.dateobject. - correspondent: Correspondent to assign, as an ID or name.
- document_type: Document type to assign, as an ID or name.
- storage_path: Storage path to assign, as an ID or name.
- tags: Tags to assign, as IDs or names.
- archive_serial_number: Archive serial number to assign.
- custom_fields: List of
{"field": <field_id>, "value": ...}dicts. - wait: If
False(default), returns immediately with the task ID. IfTrue, polls until processing completes. - poll_interval: Override the client-level
poll_interval(in seconds). - poll_timeout: Override the client-level
poll_timeout(in seconds).
Returns:
The Celery task ID string when
wait=False, or the fully processed~easypaperless.models.documents.Documentwhenwait=True.
Raises:
- ~easypaperless.exceptions.UploadError: If processing fails.
- ~easypaperless.exceptions.TaskTimeoutError: If timeout is exceeded.
696 async def bulk_add_tag(self, document_ids: List[int], tag: int | str) -> None: 697 """Add a tag to multiple documents in a single request. 698 699 Args: 700 document_ids: List of document IDs to tag. 701 tag: Tag to add, as an ID or name. 702 """ 703 tag_id = await self._core._resolver.resolve("tags", tag) 704 await self._bulk_edit(document_ids, "add_tag", tag=tag_id)
Add a tag to multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to tag.
- tag: Tag to add, as an ID or name.
706 async def bulk_remove_tag(self, document_ids: List[int], tag: int | str) -> None: 707 """Remove a tag from multiple documents in a single request. 708 709 Args: 710 document_ids: List of document IDs to un-tag. 711 tag: Tag to remove, as an ID or name. 712 """ 713 tag_id = await self._core._resolver.resolve("tags", tag) 714 await self._bulk_edit(document_ids, "remove_tag", tag=tag_id)
Remove a tag from multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to un-tag.
- tag: Tag to remove, as an ID or name.
735 async def bulk_delete(self, document_ids: List[int]) -> None: 736 """Permanently delete multiple documents in a single request. 737 738 Args: 739 document_ids: List of document IDs to delete. 740 """ 741 await self._bulk_edit(document_ids, "delete")
Permanently delete multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to delete.
743 async def bulk_set_correspondent( 744 self, document_ids: List[int], correspondent: int | str | None 745 ) -> None: 746 """Assign a correspondent to multiple documents in a single request. 747 748 Args: 749 document_ids: List of document IDs to modify. 750 correspondent: Correspondent to assign, as an ID or name. 751 Pass ``None`` to clear. 752 """ 753 cor_id: int | None = None 754 if correspondent is not None: 755 cor_id = await self._core._resolver.resolve("correspondents", correspondent) 756 await self._bulk_edit(document_ids, "set_correspondent", correspondent=cor_id)
Assign a correspondent to multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to modify.
- correspondent: Correspondent to assign, as an ID or name.
Pass
Noneto clear.
758 async def bulk_set_document_type( 759 self, document_ids: List[int], document_type: int | str | None 760 ) -> None: 761 """Assign a document type to multiple documents in a single request. 762 763 Args: 764 document_ids: List of document IDs to modify. 765 document_type: Document type to assign, as an ID or name. 766 Pass ``None`` to clear. 767 """ 768 dt_id: int | None = None 769 if document_type is not None: 770 dt_id = await self._core._resolver.resolve("document_types", document_type) 771 await self._bulk_edit(document_ids, "set_document_type", document_type=dt_id)
Assign a document type to multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to modify.
- document_type: Document type to assign, as an ID or name.
Pass
Noneto clear.
773 async def bulk_set_storage_path( 774 self, document_ids: List[int], storage_path: int | str | None 775 ) -> None: 776 """Assign a storage path to multiple documents in a single request. 777 778 Args: 779 document_ids: List of document IDs to modify. 780 storage_path: Storage path to assign, as an ID or name. 781 Pass ``None`` to clear. 782 """ 783 sp_id: int | None = None 784 if storage_path is not None: 785 sp_id = await self._core._resolver.resolve("storage_paths", storage_path) 786 await self._bulk_edit(document_ids, "set_storage_path", storage_path=sp_id)
Assign a storage path to multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to modify.
- storage_path: Storage path to assign, as an ID or name.
Pass
Noneto clear.
788 async def bulk_modify_custom_fields( 789 self, 790 document_ids: List[int], 791 *, 792 add_fields: List[dict[str, Any]] | None = None, 793 remove_fields: List[int] | None = None, 794 ) -> None: 795 """Add and/or remove custom field values on multiple documents. 796 797 Args: 798 document_ids: List of document IDs to modify. 799 add_fields: Custom-field value dicts to add. 800 remove_fields: Custom-field IDs whose values should be removed. 801 """ 802 await self._bulk_edit( 803 document_ids, 804 "modify_custom_fields", 805 add_custom_fields=add_fields or [], 806 remove_custom_fields=remove_fields or [], 807 )
Add and/or remove custom field values on multiple documents.
Arguments:
- document_ids: List of document IDs to modify.
- add_fields: Custom-field value dicts to add.
- remove_fields: Custom-field IDs whose values should be removed.
809 async def bulk_set_permissions( 810 self, 811 document_ids: List[int], 812 *, 813 set_permissions: SetPermissions | None = None, 814 owner: int | None = None, 815 merge: bool = False, 816 ) -> None: 817 """Set permissions and/or owner on multiple documents. 818 819 Args: 820 document_ids: List of document IDs to modify. 821 set_permissions: Explicit view/change permission sets. 822 owner: Numeric user ID to assign as document owner. 823 merge: When ``True``, new permissions are merged with existing ones. 824 """ 825 params: dict[str, Any] = {"merge": merge} 826 if set_permissions is not None: 827 params["set_permissions"] = set_permissions.model_dump() 828 if owner is not None: 829 params["owner"] = owner 830 await self._bulk_edit(document_ids, "set_permissions", **params)
Set permissions and/or owner on multiple documents.
Arguments:
- document_ids: List of document IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as document owner.
- merge: When
True, new permissions are merged with existing ones.
42class NotesResource: 43 """Accessor for document notes: ``client.documents.notes``.""" 44 45 def __init__(self, core: _ClientCore) -> None: 46 self._core = core 47 48 async def list(self, document_id: int) -> List[DocumentNote]: 49 """Fetch all notes attached to a document. 50 51 Args: 52 document_id: Numeric ID of the document whose notes to retrieve. 53 54 Returns: 55 List of :class:`~easypaperless.models.documents.DocumentNote` objects, 56 ordered by creation time. 57 58 Raises: 59 ~easypaperless.exceptions.NotFoundError: If no document exists 60 with that ID. 61 """ 62 logger.debug("Fetching notes for document id=%d", document_id) 63 resp = await self._core._session.get(f"/documents/{document_id}/notes/") 64 return [DocumentNote.model_validate(item) for item in resp.json()] 65 66 async def create(self, document_id: int, *, note: str) -> DocumentNote: 67 """Create a new note on a document. 68 69 Args: 70 document_id: Numeric ID of the document to annotate. 71 note: Text content of the note. 72 73 Returns: 74 The newly created :class:`~easypaperless.models.documents.DocumentNote`. 75 76 Raises: 77 ~easypaperless.exceptions.NotFoundError: If no document exists 78 with that ID. 79 """ 80 logger.debug("Creating note for document id=%d", document_id) 81 resp = await self._core._session.post( 82 f"/documents/{document_id}/notes/", 83 json={"note": note}, 84 ) 85 data = resp.json() 86 if isinstance(data, list): 87 return DocumentNote.model_validate(data[-1]) 88 return DocumentNote.model_validate(data) 89 90 async def delete(self, document_id: int, note_id: int) -> None: 91 """Delete a note from a document. 92 93 Args: 94 document_id: Numeric ID of the document that owns the note. 95 note_id: Numeric ID of the note to delete. 96 97 Raises: 98 ~easypaperless.exceptions.NotFoundError: If no document or note 99 exists with the given IDs. 100 """ 101 logger.debug("Deleting note id=%d from document id=%d", note_id, document_id) 102 await self._core._session.delete(f"/documents/{document_id}/notes/", params={"id": note_id})
Accessor for document notes: client.documents.notes.
48 async def list(self, document_id: int) -> List[DocumentNote]: 49 """Fetch all notes attached to a document. 50 51 Args: 52 document_id: Numeric ID of the document whose notes to retrieve. 53 54 Returns: 55 List of :class:`~easypaperless.models.documents.DocumentNote` objects, 56 ordered by creation time. 57 58 Raises: 59 ~easypaperless.exceptions.NotFoundError: If no document exists 60 with that ID. 61 """ 62 logger.debug("Fetching notes for document id=%d", document_id) 63 resp = await self._core._session.get(f"/documents/{document_id}/notes/") 64 return [DocumentNote.model_validate(item) for item in resp.json()]
Fetch all notes attached to a document.
Arguments:
- document_id: Numeric ID of the document whose notes to retrieve.
Returns:
List of
~easypaperless.models.documents.DocumentNoteobjects, ordered by creation time.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
66 async def create(self, document_id: int, *, note: str) -> DocumentNote: 67 """Create a new note on a document. 68 69 Args: 70 document_id: Numeric ID of the document to annotate. 71 note: Text content of the note. 72 73 Returns: 74 The newly created :class:`~easypaperless.models.documents.DocumentNote`. 75 76 Raises: 77 ~easypaperless.exceptions.NotFoundError: If no document exists 78 with that ID. 79 """ 80 logger.debug("Creating note for document id=%d", document_id) 81 resp = await self._core._session.post( 82 f"/documents/{document_id}/notes/", 83 json={"note": note}, 84 ) 85 data = resp.json() 86 if isinstance(data, list): 87 return DocumentNote.model_validate(data[-1]) 88 return DocumentNote.model_validate(data)
Create a new note on a document.
Arguments:
- document_id: Numeric ID of the document to annotate.
- note: Text content of the note.
Returns:
The newly created
~easypaperless.models.documents.DocumentNote.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
90 async def delete(self, document_id: int, note_id: int) -> None: 91 """Delete a note from a document. 92 93 Args: 94 document_id: Numeric ID of the document that owns the note. 95 note_id: Numeric ID of the note to delete. 96 97 Raises: 98 ~easypaperless.exceptions.NotFoundError: If no document or note 99 exists with the given IDs. 100 """ 101 logger.debug("Deleting note id=%d from document id=%d", note_id, document_id) 102 await self._core._session.delete(f"/documents/{document_id}/notes/", params={"id": note_id})
Delete a note from a document.
Arguments:
- document_id: Numeric ID of the document that owns the note.
- note_id: Numeric ID of the note to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document or note exists with the given IDs.
17class StoragePathsResource: 18 """Accessor for storage paths: ``client.storage_paths``.""" 19 20 def __init__(self, core: _ClientCore) -> None: 21 self._core = core 22 23 async def list( 24 self, 25 *, 26 ids: List[int] | None = None, 27 name_contains: str | None = None, 28 name_exact: str | None = None, 29 path_contains: str | None = None, 30 path_exact: str | None = None, 31 page: int | None = None, 32 page_size: int | None = None, 33 ordering: str | None = None, 34 descending: bool = False, 35 ) -> List[StoragePath]: 36 """Return storage paths defined in paperless-ngx. 37 38 Args: 39 ids: Return only storage paths whose ID is in this list. 40 name_contains: Case-insensitive substring filter on name. 41 name_exact: Case-insensitive exact match on name. 42 path_contains: Case-insensitive substring filter on path template. 43 path_exact: Case-insensitive exact match on path template. 44 page: Return only this specific page (1-based). 45 page_size: Number of results per page. 46 ordering: Field to sort by. 47 descending: When ``True``, reverses the sort direction. 48 49 Returns: 50 List of :class:`~easypaperless.models.storage_paths.StoragePath` objects. 51 """ 52 params: dict[str, Any] = {} 53 if ids is not None: 54 params["id__in"] = ",".join(str(i) for i in ids) 55 if name_contains is not None: 56 params["name__icontains"] = name_contains 57 if name_exact is not None: 58 params["name__iexact"] = name_exact 59 if path_contains is not None: 60 params["path__icontains"] = path_contains 61 if path_exact is not None: 62 params["path__iexact"] = path_exact 63 if page is not None: 64 params["page"] = page 65 if page_size is not None: 66 params["page_size"] = page_size 67 if ordering is not None: 68 params["ordering"] = f"-{ordering}" if descending else ordering 69 return cast( 70 List[StoragePath], 71 await self._core._list_resource("storage_paths", StoragePath, params or None), 72 ) 73 74 async def get(self, id: int) -> StoragePath: 75 """Fetch a single storage path by its ID. 76 77 Args: 78 id: Numeric storage-path ID. 79 80 Returns: 81 The :class:`~easypaperless.models.storage_paths.StoragePath` with the given ID. 82 83 Raises: 84 ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID. 85 """ 86 return cast(StoragePath, await self._core._get_resource("storage_paths", id, StoragePath)) 87 88 async def create( 89 self, 90 *, 91 name: str, 92 path: str | None = None, 93 match: str | None | _Unset = UNSET, 94 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 95 is_insensitive: bool = True, 96 owner: int | None | _Unset = UNSET, 97 set_permissions: SetPermissions | None = None, 98 ) -> StoragePath: 99 """Create a new storage path. 100 101 Args: 102 name: Storage-path name. Must be unique. 103 path: Template string for the archive file path. 104 match: Auto-matching pattern. 105 matching_algorithm: Controls how ``match`` is applied. 106 is_insensitive: When ``True``, ``match`` is case-insensitive. 107 Defaults to ``True``, matching the paperless-ngx API default. 108 owner: Numeric user ID to assign as owner. 109 set_permissions: Explicit view/change permission sets. 110 111 Returns: 112 The newly created :class:`~easypaperless.models.storage_paths.StoragePath`. 113 """ 114 return cast( 115 StoragePath, 116 await self._core._create_resource( 117 "storage_paths", 118 StoragePath, 119 owner=owner, 120 set_permissions=set_permissions, 121 name=name, 122 path=path, 123 match=match, 124 matching_algorithm=matching_algorithm, 125 is_insensitive=is_insensitive, 126 ), 127 ) 128 129 async def update( 130 self, 131 id: int, 132 *, 133 name: str | None | _Unset = UNSET, 134 path: str | None | _Unset = UNSET, 135 match: str | None | _Unset = UNSET, 136 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 137 is_insensitive: bool | None | _Unset = UNSET, 138 owner: int | None | _Unset = UNSET, 139 set_permissions: SetPermissions | None | _Unset = UNSET, 140 ) -> StoragePath: 141 """Partially update a storage path (PATCH semantics). 142 143 Args: 144 id: Numeric ID of the storage path to update. 145 name: Storage-path name. 146 path: Template string for the archive file path. 147 match: Auto-matching pattern. 148 matching_algorithm: Controls how ``match`` is applied. 149 is_insensitive: When ``True``, ``match`` is case-insensitive. 150 owner: Numeric user ID to assign as owner. 151 Pass ``None`` to clear the owner. 152 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 153 set_permissions: Explicit view/change permission sets. 154 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 155 156 Returns: 157 The updated :class:`~easypaperless.models.storage_paths.StoragePath`. 158 """ 159 _set_perms: dict[str, Any] | _Unset = ( 160 UNSET 161 if isinstance(set_permissions, _Unset) 162 else (set_permissions or SetPermissions()).model_dump() 163 ) 164 return cast( 165 StoragePath, 166 await self._core._update_resource( 167 "storage_paths", 168 id, 169 StoragePath, 170 name=name, 171 path=path, 172 match=match, 173 matching_algorithm=matching_algorithm, 174 is_insensitive=is_insensitive, 175 owner=owner, 176 set_permissions=_set_perms, 177 ), 178 ) 179 180 async def delete(self, id: int) -> None: 181 """Delete a storage path. 182 183 Args: 184 id: Numeric ID of the storage path to delete. 185 186 Raises: 187 ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID. 188 """ 189 await self._core._delete_resource("storage_paths", id) 190 191 async def bulk_delete(self, ids: List[int]) -> None: 192 """Permanently delete multiple storage paths in a single request. 193 194 Args: 195 ids: List of storage path IDs to delete. 196 """ 197 await self._core._bulk_edit_objects("storage_paths", ids, "delete") 198 199 async def bulk_set_permissions( 200 self, 201 ids: List[int], 202 *, 203 set_permissions: SetPermissions | None = None, 204 owner: int | None = None, 205 merge: bool = False, 206 ) -> None: 207 """Set permissions and/or owner on multiple storage paths. 208 209 Args: 210 ids: List of storage path IDs to modify. 211 set_permissions: Explicit view/change permission sets. 212 owner: Numeric user ID to assign as owner. 213 merge: When ``True``, new permissions are merged with existing ones. 214 """ 215 params: dict[str, Any] = {"merge": merge} 216 if set_permissions is not None: 217 params["permissions"] = set_permissions.model_dump() 218 if owner is not None: 219 params["owner"] = owner 220 await self._core._bulk_edit_objects("storage_paths", ids, "set_permissions", **params)
Accessor for storage paths: client.storage_paths.
23 async def list( 24 self, 25 *, 26 ids: List[int] | None = None, 27 name_contains: str | None = None, 28 name_exact: str | None = None, 29 path_contains: str | None = None, 30 path_exact: str | None = None, 31 page: int | None = None, 32 page_size: int | None = None, 33 ordering: str | None = None, 34 descending: bool = False, 35 ) -> List[StoragePath]: 36 """Return storage paths defined in paperless-ngx. 37 38 Args: 39 ids: Return only storage paths whose ID is in this list. 40 name_contains: Case-insensitive substring filter on name. 41 name_exact: Case-insensitive exact match on name. 42 path_contains: Case-insensitive substring filter on path template. 43 path_exact: Case-insensitive exact match on path template. 44 page: Return only this specific page (1-based). 45 page_size: Number of results per page. 46 ordering: Field to sort by. 47 descending: When ``True``, reverses the sort direction. 48 49 Returns: 50 List of :class:`~easypaperless.models.storage_paths.StoragePath` objects. 51 """ 52 params: dict[str, Any] = {} 53 if ids is not None: 54 params["id__in"] = ",".join(str(i) for i in ids) 55 if name_contains is not None: 56 params["name__icontains"] = name_contains 57 if name_exact is not None: 58 params["name__iexact"] = name_exact 59 if path_contains is not None: 60 params["path__icontains"] = path_contains 61 if path_exact is not None: 62 params["path__iexact"] = path_exact 63 if page is not None: 64 params["page"] = page 65 if page_size is not None: 66 params["page_size"] = page_size 67 if ordering is not None: 68 params["ordering"] = f"-{ordering}" if descending else ordering 69 return cast( 70 List[StoragePath], 71 await self._core._list_resource("storage_paths", StoragePath, params or None), 72 )
Return storage paths defined in paperless-ngx.
Arguments:
- ids: Return only storage paths whose ID is in this list.
- name_contains: Case-insensitive substring filter on name.
- name_exact: Case-insensitive exact match on name.
- path_contains: Case-insensitive substring filter on path template.
- path_exact: Case-insensitive exact match on path template.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.storage_paths.StoragePathobjects.
74 async def get(self, id: int) -> StoragePath: 75 """Fetch a single storage path by its ID. 76 77 Args: 78 id: Numeric storage-path ID. 79 80 Returns: 81 The :class:`~easypaperless.models.storage_paths.StoragePath` with the given ID. 82 83 Raises: 84 ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID. 85 """ 86 return cast(StoragePath, await self._core._get_resource("storage_paths", id, StoragePath))
Fetch a single storage path by its ID.
Arguments:
- id: Numeric storage-path ID.
Returns:
The
~easypaperless.models.storage_paths.StoragePathwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID.
88 async def create( 89 self, 90 *, 91 name: str, 92 path: str | None = None, 93 match: str | None | _Unset = UNSET, 94 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 95 is_insensitive: bool = True, 96 owner: int | None | _Unset = UNSET, 97 set_permissions: SetPermissions | None = None, 98 ) -> StoragePath: 99 """Create a new storage path. 100 101 Args: 102 name: Storage-path name. Must be unique. 103 path: Template string for the archive file path. 104 match: Auto-matching pattern. 105 matching_algorithm: Controls how ``match`` is applied. 106 is_insensitive: When ``True``, ``match`` is case-insensitive. 107 Defaults to ``True``, matching the paperless-ngx API default. 108 owner: Numeric user ID to assign as owner. 109 set_permissions: Explicit view/change permission sets. 110 111 Returns: 112 The newly created :class:`~easypaperless.models.storage_paths.StoragePath`. 113 """ 114 return cast( 115 StoragePath, 116 await self._core._create_resource( 117 "storage_paths", 118 StoragePath, 119 owner=owner, 120 set_permissions=set_permissions, 121 name=name, 122 path=path, 123 match=match, 124 matching_algorithm=matching_algorithm, 125 is_insensitive=is_insensitive, 126 ), 127 )
Create a new storage path.
Arguments:
- name: Storage-path name. Must be unique.
- path: Template string for the archive file path.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. Defaults toTrue, matching the paperless-ngx API default. - owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.storage_paths.StoragePath.
129 async def update( 130 self, 131 id: int, 132 *, 133 name: str | None | _Unset = UNSET, 134 path: str | None | _Unset = UNSET, 135 match: str | None | _Unset = UNSET, 136 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 137 is_insensitive: bool | None | _Unset = UNSET, 138 owner: int | None | _Unset = UNSET, 139 set_permissions: SetPermissions | None | _Unset = UNSET, 140 ) -> StoragePath: 141 """Partially update a storage path (PATCH semantics). 142 143 Args: 144 id: Numeric ID of the storage path to update. 145 name: Storage-path name. 146 path: Template string for the archive file path. 147 match: Auto-matching pattern. 148 matching_algorithm: Controls how ``match`` is applied. 149 is_insensitive: When ``True``, ``match`` is case-insensitive. 150 owner: Numeric user ID to assign as owner. 151 Pass ``None`` to clear the owner. 152 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 153 set_permissions: Explicit view/change permission sets. 154 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 155 156 Returns: 157 The updated :class:`~easypaperless.models.storage_paths.StoragePath`. 158 """ 159 _set_perms: dict[str, Any] | _Unset = ( 160 UNSET 161 if isinstance(set_permissions, _Unset) 162 else (set_permissions or SetPermissions()).model_dump() 163 ) 164 return cast( 165 StoragePath, 166 await self._core._update_resource( 167 "storage_paths", 168 id, 169 StoragePath, 170 name=name, 171 path=path, 172 match=match, 173 matching_algorithm=matching_algorithm, 174 is_insensitive=is_insensitive, 175 owner=owner, 176 set_permissions=_set_perms, 177 ), 178 )
Partially update a storage path (PATCH semantics).
Arguments:
- id: Numeric ID of the storage path to update.
- name: Storage-path name.
- path: Template string for the archive file path.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. - owner: Numeric user ID to assign as owner.
Pass
Noneto clear the owner. Omit (or pass~easypaperless.UNSET) to leave unchanged. - set_permissions: Explicit view/change permission sets.
Omit (or pass
~easypaperless.UNSET) to leave unchanged.
Returns:
The updated
~easypaperless.models.storage_paths.StoragePath.
180 async def delete(self, id: int) -> None: 181 """Delete a storage path. 182 183 Args: 184 id: Numeric ID of the storage path to delete. 185 186 Raises: 187 ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID. 188 """ 189 await self._core._delete_resource("storage_paths", id)
Delete a storage path.
Arguments:
- id: Numeric ID of the storage path to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID.
191 async def bulk_delete(self, ids: List[int]) -> None: 192 """Permanently delete multiple storage paths in a single request. 193 194 Args: 195 ids: List of storage path IDs to delete. 196 """ 197 await self._core._bulk_edit_objects("storage_paths", ids, "delete")
Permanently delete multiple storage paths in a single request.
Arguments:
- ids: List of storage path IDs to delete.
199 async def bulk_set_permissions( 200 self, 201 ids: List[int], 202 *, 203 set_permissions: SetPermissions | None = None, 204 owner: int | None = None, 205 merge: bool = False, 206 ) -> None: 207 """Set permissions and/or owner on multiple storage paths. 208 209 Args: 210 ids: List of storage path IDs to modify. 211 set_permissions: Explicit view/change permission sets. 212 owner: Numeric user ID to assign as owner. 213 merge: When ``True``, new permissions are merged with existing ones. 214 """ 215 params: dict[str, Any] = {"merge": merge} 216 if set_permissions is not None: 217 params["permissions"] = set_permissions.model_dump() 218 if owner is not None: 219 params["owner"] = owner 220 await self._core._bulk_edit_objects("storage_paths", ids, "set_permissions", **params)
Set permissions and/or owner on multiple storage paths.
Arguments:
- ids: List of storage path IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as owner.
- merge: When
True, new permissions are merged with existing ones.
17class TagsResource: 18 """Accessor for tags: ``client.tags``.""" 19 20 def __init__(self, core: _ClientCore) -> None: 21 self._core = core 22 23 async def list( 24 self, 25 *, 26 ids: List[int] | None = None, 27 name_contains: str | None = None, 28 name_exact: str | None = None, 29 page: int | None = None, 30 page_size: int | None = None, 31 ordering: str | None = None, 32 descending: bool = False, 33 ) -> List[Tag]: 34 """Return tags defined in paperless-ngx. 35 36 Args: 37 ids: Return only tags whose ID is in this list. 38 name_contains: Case-insensitive substring filter on tag name. 39 name_exact: Case-insensitive exact match on tag name. 40 page: Return only this specific page (1-based). 41 page_size: Number of results per page. 42 ordering: Field to sort by. 43 descending: When ``True``, reverses the sort direction. 44 45 Returns: 46 List of :class:`~easypaperless.models.tags.Tag` objects. 47 """ 48 params: dict[str, Any] = {} 49 if ids is not None: 50 params["id__in"] = ",".join(str(i) for i in ids) 51 if name_contains is not None: 52 params["name__icontains"] = name_contains 53 if name_exact is not None: 54 params["name__iexact"] = name_exact 55 if page is not None: 56 params["page"] = page 57 if page_size is not None: 58 params["page_size"] = page_size 59 if ordering is not None: 60 params["ordering"] = f"-{ordering}" if descending else ordering 61 return cast( 62 List[Tag], 63 await self._core._list_resource("tags", Tag, params or None), 64 ) 65 66 async def get(self, id: int) -> Tag: 67 """Fetch a single tag by its ID. 68 69 Args: 70 id: Numeric tag ID. 71 72 Returns: 73 The :class:`~easypaperless.models.tags.Tag` with the given ID. 74 75 Raises: 76 ~easypaperless.exceptions.NotFoundError: If no tag exists with 77 that ID. 78 """ 79 return cast(Tag, await self._core._get_resource("tags", id, Tag)) 80 81 async def create( 82 self, 83 *, 84 name: str, 85 color: str | None | _Unset = UNSET, 86 is_inbox_tag: bool | None | _Unset = UNSET, 87 match: str | None | _Unset = UNSET, 88 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 89 is_insensitive: bool = True, 90 parent: int | None | _Unset = UNSET, 91 owner: int | None | _Unset = UNSET, 92 set_permissions: SetPermissions | None = None, 93 ) -> Tag: 94 """Create a new tag. 95 96 Args: 97 name: Tag name. Must be unique. 98 color: Background colour as a CSS hex string. 99 is_inbox_tag: When ``True``, newly ingested documents get this tag. 100 match: Auto-matching pattern. 101 matching_algorithm: Controls how ``match`` is applied. 102 is_insensitive: When ``True``, ``match`` is case-insensitive. 103 Defaults to ``True``, matching the paperless-ngx API default. 104 parent: ID of parent tag for hierarchical trees. 105 owner: Numeric user ID to assign as owner. 106 set_permissions: Explicit view/change permission sets. 107 108 Returns: 109 The newly created :class:`~easypaperless.models.tags.Tag`. 110 """ 111 return cast( 112 Tag, 113 await self._core._create_resource( 114 "tags", 115 Tag, 116 owner=owner, 117 set_permissions=set_permissions, 118 name=name, 119 color=color, 120 is_inbox_tag=is_inbox_tag, 121 match=match, 122 matching_algorithm=matching_algorithm, 123 is_insensitive=is_insensitive, 124 parent=parent, 125 ), 126 ) 127 128 async def update( 129 self, 130 id: int, 131 *, 132 name: str | None | _Unset = UNSET, 133 color: str | None | _Unset = UNSET, 134 is_inbox_tag: bool | None | _Unset = UNSET, 135 match: str | None | _Unset = UNSET, 136 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 137 is_insensitive: bool | None | _Unset = UNSET, 138 parent: int | None | _Unset = UNSET, 139 owner: int | None | _Unset = UNSET, 140 set_permissions: SetPermissions | None | _Unset = UNSET, 141 ) -> Tag: 142 """Partially update a tag (PATCH semantics). 143 144 Args: 145 id: Numeric ID of the tag to update. 146 name: Tag name. 147 color: Background colour as a CSS hex string. 148 is_inbox_tag: When ``True``, newly ingested documents get this tag. 149 match: Auto-matching pattern. 150 matching_algorithm: Controls how ``match`` is applied. 151 is_insensitive: When ``True``, ``match`` is case-insensitive. 152 parent: ID of parent tag. 153 Pass ``None`` to clear (make root tag). 154 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 155 owner: Numeric user ID to assign as owner. 156 Pass ``None`` to clear the owner. 157 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 158 set_permissions: Explicit view/change permission sets. 159 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 160 161 Returns: 162 The updated :class:`~easypaperless.models.tags.Tag`. 163 """ 164 _set_perms: dict[str, Any] | _Unset = ( 165 UNSET 166 if isinstance(set_permissions, _Unset) 167 else (set_permissions or SetPermissions()).model_dump() 168 ) 169 return cast( 170 Tag, 171 await self._core._update_resource( 172 "tags", 173 id, 174 Tag, 175 name=name, 176 color=color, 177 is_inbox_tag=is_inbox_tag, 178 match=match, 179 matching_algorithm=matching_algorithm, 180 is_insensitive=is_insensitive, 181 parent=parent, 182 owner=owner, 183 set_permissions=_set_perms, 184 ), 185 ) 186 187 async def delete(self, id: int) -> None: 188 """Delete a tag. 189 190 Args: 191 id: Numeric ID of the tag to delete. 192 193 Raises: 194 ~easypaperless.exceptions.NotFoundError: If no tag exists with 195 that ID. 196 """ 197 await self._core._delete_resource("tags", id) 198 199 async def bulk_delete(self, ids: List[int]) -> None: 200 """Permanently delete multiple tags in a single request. 201 202 Args: 203 ids: List of tag IDs to delete. 204 """ 205 await self._core._bulk_edit_objects("tags", ids, "delete") 206 207 async def bulk_set_permissions( 208 self, 209 ids: List[int], 210 *, 211 set_permissions: SetPermissions | None = None, 212 owner: int | None = None, 213 merge: bool = False, 214 ) -> None: 215 """Set permissions and/or owner on multiple tags. 216 217 Args: 218 ids: List of tag IDs to modify. 219 set_permissions: Explicit view/change permission sets. 220 owner: Numeric user ID to assign as owner. 221 merge: When ``True``, new permissions are merged with existing ones. 222 """ 223 params: dict[str, Any] = {"merge": merge} 224 if set_permissions is not None: 225 params["permissions"] = set_permissions.model_dump() 226 if owner is not None: 227 params["owner"] = owner 228 await self._core._bulk_edit_objects("tags", ids, "set_permissions", **params)
Accessor for tags: client.tags.
23 async def list( 24 self, 25 *, 26 ids: List[int] | None = None, 27 name_contains: str | None = None, 28 name_exact: str | None = None, 29 page: int | None = None, 30 page_size: int | None = None, 31 ordering: str | None = None, 32 descending: bool = False, 33 ) -> List[Tag]: 34 """Return tags defined in paperless-ngx. 35 36 Args: 37 ids: Return only tags whose ID is in this list. 38 name_contains: Case-insensitive substring filter on tag name. 39 name_exact: Case-insensitive exact match on tag name. 40 page: Return only this specific page (1-based). 41 page_size: Number of results per page. 42 ordering: Field to sort by. 43 descending: When ``True``, reverses the sort direction. 44 45 Returns: 46 List of :class:`~easypaperless.models.tags.Tag` objects. 47 """ 48 params: dict[str, Any] = {} 49 if ids is not None: 50 params["id__in"] = ",".join(str(i) for i in ids) 51 if name_contains is not None: 52 params["name__icontains"] = name_contains 53 if name_exact is not None: 54 params["name__iexact"] = name_exact 55 if page is not None: 56 params["page"] = page 57 if page_size is not None: 58 params["page_size"] = page_size 59 if ordering is not None: 60 params["ordering"] = f"-{ordering}" if descending else ordering 61 return cast( 62 List[Tag], 63 await self._core._list_resource("tags", Tag, params or None), 64 )
Return tags defined in paperless-ngx.
Arguments:
- ids: Return only tags whose ID is in this list.
- name_contains: Case-insensitive substring filter on tag name.
- name_exact: Case-insensitive exact match on tag name.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.tags.Tagobjects.
66 async def get(self, id: int) -> Tag: 67 """Fetch a single tag by its ID. 68 69 Args: 70 id: Numeric tag ID. 71 72 Returns: 73 The :class:`~easypaperless.models.tags.Tag` with the given ID. 74 75 Raises: 76 ~easypaperless.exceptions.NotFoundError: If no tag exists with 77 that ID. 78 """ 79 return cast(Tag, await self._core._get_resource("tags", id, Tag))
Fetch a single tag by its ID.
Arguments:
- id: Numeric tag ID.
Returns:
The
~easypaperless.models.tags.Tagwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no tag exists with that ID.
81 async def create( 82 self, 83 *, 84 name: str, 85 color: str | None | _Unset = UNSET, 86 is_inbox_tag: bool | None | _Unset = UNSET, 87 match: str | None | _Unset = UNSET, 88 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 89 is_insensitive: bool = True, 90 parent: int | None | _Unset = UNSET, 91 owner: int | None | _Unset = UNSET, 92 set_permissions: SetPermissions | None = None, 93 ) -> Tag: 94 """Create a new tag. 95 96 Args: 97 name: Tag name. Must be unique. 98 color: Background colour as a CSS hex string. 99 is_inbox_tag: When ``True``, newly ingested documents get this tag. 100 match: Auto-matching pattern. 101 matching_algorithm: Controls how ``match`` is applied. 102 is_insensitive: When ``True``, ``match`` is case-insensitive. 103 Defaults to ``True``, matching the paperless-ngx API default. 104 parent: ID of parent tag for hierarchical trees. 105 owner: Numeric user ID to assign as owner. 106 set_permissions: Explicit view/change permission sets. 107 108 Returns: 109 The newly created :class:`~easypaperless.models.tags.Tag`. 110 """ 111 return cast( 112 Tag, 113 await self._core._create_resource( 114 "tags", 115 Tag, 116 owner=owner, 117 set_permissions=set_permissions, 118 name=name, 119 color=color, 120 is_inbox_tag=is_inbox_tag, 121 match=match, 122 matching_algorithm=matching_algorithm, 123 is_insensitive=is_insensitive, 124 parent=parent, 125 ), 126 )
Create a new tag.
Arguments:
- name: Tag name. Must be unique.
- color: Background colour as a CSS hex string.
- is_inbox_tag: When
True, newly ingested documents get this tag. - match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. Defaults toTrue, matching the paperless-ngx API default. - parent: ID of parent tag for hierarchical trees.
- owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.tags.Tag.
128 async def update( 129 self, 130 id: int, 131 *, 132 name: str | None | _Unset = UNSET, 133 color: str | None | _Unset = UNSET, 134 is_inbox_tag: bool | None | _Unset = UNSET, 135 match: str | None | _Unset = UNSET, 136 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 137 is_insensitive: bool | None | _Unset = UNSET, 138 parent: int | None | _Unset = UNSET, 139 owner: int | None | _Unset = UNSET, 140 set_permissions: SetPermissions | None | _Unset = UNSET, 141 ) -> Tag: 142 """Partially update a tag (PATCH semantics). 143 144 Args: 145 id: Numeric ID of the tag to update. 146 name: Tag name. 147 color: Background colour as a CSS hex string. 148 is_inbox_tag: When ``True``, newly ingested documents get this tag. 149 match: Auto-matching pattern. 150 matching_algorithm: Controls how ``match`` is applied. 151 is_insensitive: When ``True``, ``match`` is case-insensitive. 152 parent: ID of parent tag. 153 Pass ``None`` to clear (make root tag). 154 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 155 owner: Numeric user ID to assign as owner. 156 Pass ``None`` to clear the owner. 157 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 158 set_permissions: Explicit view/change permission sets. 159 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 160 161 Returns: 162 The updated :class:`~easypaperless.models.tags.Tag`. 163 """ 164 _set_perms: dict[str, Any] | _Unset = ( 165 UNSET 166 if isinstance(set_permissions, _Unset) 167 else (set_permissions or SetPermissions()).model_dump() 168 ) 169 return cast( 170 Tag, 171 await self._core._update_resource( 172 "tags", 173 id, 174 Tag, 175 name=name, 176 color=color, 177 is_inbox_tag=is_inbox_tag, 178 match=match, 179 matching_algorithm=matching_algorithm, 180 is_insensitive=is_insensitive, 181 parent=parent, 182 owner=owner, 183 set_permissions=_set_perms, 184 ), 185 )
Partially update a tag (PATCH semantics).
Arguments:
- id: Numeric ID of the tag to update.
- name: Tag name.
- color: Background colour as a CSS hex string.
- is_inbox_tag: When
True, newly ingested documents get this tag. - match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. - parent: ID of parent tag.
Pass
Noneto clear (make root tag). Omit (or pass~easypaperless.UNSET) to leave unchanged. - owner: Numeric user ID to assign as owner.
Pass
Noneto clear the owner. Omit (or pass~easypaperless.UNSET) to leave unchanged. - set_permissions: Explicit view/change permission sets.
Omit (or pass
~easypaperless.UNSET) to leave unchanged.
Returns:
The updated
~easypaperless.models.tags.Tag.
187 async def delete(self, id: int) -> None: 188 """Delete a tag. 189 190 Args: 191 id: Numeric ID of the tag to delete. 192 193 Raises: 194 ~easypaperless.exceptions.NotFoundError: If no tag exists with 195 that ID. 196 """ 197 await self._core._delete_resource("tags", id)
Delete a tag.
Arguments:
- id: Numeric ID of the tag to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no tag exists with that ID.
199 async def bulk_delete(self, ids: List[int]) -> None: 200 """Permanently delete multiple tags in a single request. 201 202 Args: 203 ids: List of tag IDs to delete. 204 """ 205 await self._core._bulk_edit_objects("tags", ids, "delete")
Permanently delete multiple tags in a single request.
Arguments:
- ids: List of tag IDs to delete.
207 async def bulk_set_permissions( 208 self, 209 ids: List[int], 210 *, 211 set_permissions: SetPermissions | None = None, 212 owner: int | None = None, 213 merge: bool = False, 214 ) -> None: 215 """Set permissions and/or owner on multiple tags. 216 217 Args: 218 ids: List of tag IDs to modify. 219 set_permissions: Explicit view/change permission sets. 220 owner: Numeric user ID to assign as owner. 221 merge: When ``True``, new permissions are merged with existing ones. 222 """ 223 params: dict[str, Any] = {"merge": merge} 224 if set_permissions is not None: 225 params["permissions"] = set_permissions.model_dump() 226 if owner is not None: 227 params["owner"] = owner 228 await self._core._bulk_edit_objects("tags", ids, "set_permissions", **params)
Set permissions and/or owner on multiple tags.
Arguments:
- ids: List of tag IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as owner.
- merge: When
True, new permissions are merged with existing ones.
17class SyncCorrespondentsResource: 18 """Sync accessor for correspondents: ``client.correspondents``.""" 19 20 def __init__(self, async_correspondents: CorrespondentsResource, run: Any) -> None: 21 self._async_correspondents = async_correspondents 22 self._run = run 23 24 def list( 25 self, 26 *, 27 ids: List[int] | None = None, 28 name_contains: str | None = None, 29 name_exact: str | None = None, 30 page: int | None = None, 31 page_size: int | None = None, 32 ordering: str | None = None, 33 descending: bool = False, 34 ) -> List[Correspondent]: 35 """Return correspondents defined in paperless-ngx. 36 37 Args: 38 ids: Return only correspondents whose ID is in this list. 39 name_contains: Case-insensitive substring filter on name. 40 name_exact: Case-insensitive exact match on name. 41 page: Return only this specific page (1-based). 42 page_size: Number of results per page. 43 ordering: Field to sort by. 44 descending: When ``True``, reverses the sort direction. 45 46 Returns: 47 List of :class:`~easypaperless.models.correspondents.Correspondent` objects. 48 """ 49 return cast( 50 List[Correspondent], 51 self._run( 52 self._async_correspondents.list( 53 ids=ids, 54 name_contains=name_contains, 55 name_exact=name_exact, 56 page=page, 57 page_size=page_size, 58 ordering=ordering, 59 descending=descending, 60 ) 61 ), 62 ) 63 64 def get(self, id: int) -> Correspondent: 65 """Fetch a single correspondent by its ID. 66 67 Args: 68 id: Numeric correspondent ID. 69 70 Returns: 71 The :class:`~easypaperless.models.correspondents.Correspondent` with the given ID. 72 73 Raises: 74 ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID. 75 """ 76 return cast(Correspondent, self._run(self._async_correspondents.get(id))) 77 78 def create( 79 self, 80 *, 81 name: str, 82 match: str | None | _Unset = UNSET, 83 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 84 is_insensitive: bool = True, 85 owner: int | None | _Unset = UNSET, 86 set_permissions: SetPermissions | None = None, 87 ) -> Correspondent: 88 """Create a new correspondent. 89 90 Args: 91 name: Correspondent name. Must be unique. 92 match: Auto-matching pattern. 93 matching_algorithm: Controls how ``match`` is applied. 94 is_insensitive: When ``True``, ``match`` is case-insensitive. 95 Defaults to ``True``, matching the paperless-ngx API default. 96 owner: Numeric user ID to assign as owner. 97 set_permissions: Explicit view/change permission sets. 98 99 Returns: 100 The newly created :class:`~easypaperless.models.correspondents.Correspondent`. 101 """ 102 return cast( 103 Correspondent, 104 self._run( 105 self._async_correspondents.create( 106 name=name, 107 match=match, 108 matching_algorithm=matching_algorithm, 109 is_insensitive=is_insensitive, 110 owner=owner, 111 set_permissions=set_permissions, 112 ) 113 ), 114 ) 115 116 def update( 117 self, 118 id: int, 119 *, 120 name: str | None | _Unset = UNSET, 121 match: str | None | _Unset = UNSET, 122 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 123 is_insensitive: bool | None | _Unset = UNSET, 124 owner: int | None | _Unset = UNSET, 125 set_permissions: SetPermissions | None | _Unset = UNSET, 126 ) -> Correspondent: 127 """Partially update a correspondent (PATCH semantics). 128 129 Args: 130 id: Numeric ID of the correspondent to update. 131 name: Correspondent name. 132 match: Auto-matching pattern. 133 matching_algorithm: Controls how ``match`` is applied. 134 is_insensitive: When ``True``, ``match`` is case-insensitive. 135 owner: Numeric user ID to assign as owner. 136 Pass ``None`` to clear the owner. 137 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 138 set_permissions: Explicit view/change permission sets. 139 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 140 141 Returns: 142 The updated :class:`~easypaperless.models.correspondents.Correspondent`. 143 """ 144 return cast( 145 Correspondent, 146 self._run( 147 self._async_correspondents.update( 148 id, 149 name=name, 150 match=match, 151 matching_algorithm=matching_algorithm, 152 is_insensitive=is_insensitive, 153 owner=owner, 154 set_permissions=set_permissions, 155 ) 156 ), 157 ) 158 159 def delete(self, id: int) -> None: 160 """Delete a correspondent. 161 162 Args: 163 id: Numeric ID of the correspondent to delete. 164 165 Raises: 166 ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID. 167 """ 168 self._run(self._async_correspondents.delete(id)) 169 170 def bulk_delete(self, ids: List[int]) -> None: 171 """Permanently delete multiple correspondents in a single request. 172 173 Args: 174 ids: List of correspondent IDs to delete. 175 """ 176 self._run(self._async_correspondents.bulk_delete(ids)) 177 178 def bulk_set_permissions( 179 self, 180 ids: List[int], 181 *, 182 set_permissions: SetPermissions | None = None, 183 owner: int | None = None, 184 merge: bool = False, 185 ) -> None: 186 """Set permissions and/or owner on multiple correspondents. 187 188 Args: 189 ids: List of correspondent IDs to modify. 190 set_permissions: Explicit view/change permission sets. 191 owner: Numeric user ID to assign as owner. 192 merge: When ``True``, new permissions are merged with existing ones. 193 """ 194 self._run( 195 self._async_correspondents.bulk_set_permissions( 196 ids, set_permissions=set_permissions, owner=owner, merge=merge 197 ) 198 )
Sync accessor for correspondents: client.correspondents.
24 def list( 25 self, 26 *, 27 ids: List[int] | None = None, 28 name_contains: str | None = None, 29 name_exact: str | None = None, 30 page: int | None = None, 31 page_size: int | None = None, 32 ordering: str | None = None, 33 descending: bool = False, 34 ) -> List[Correspondent]: 35 """Return correspondents defined in paperless-ngx. 36 37 Args: 38 ids: Return only correspondents whose ID is in this list. 39 name_contains: Case-insensitive substring filter on name. 40 name_exact: Case-insensitive exact match on name. 41 page: Return only this specific page (1-based). 42 page_size: Number of results per page. 43 ordering: Field to sort by. 44 descending: When ``True``, reverses the sort direction. 45 46 Returns: 47 List of :class:`~easypaperless.models.correspondents.Correspondent` objects. 48 """ 49 return cast( 50 List[Correspondent], 51 self._run( 52 self._async_correspondents.list( 53 ids=ids, 54 name_contains=name_contains, 55 name_exact=name_exact, 56 page=page, 57 page_size=page_size, 58 ordering=ordering, 59 descending=descending, 60 ) 61 ), 62 )
Return correspondents defined in paperless-ngx.
Arguments:
- ids: Return only correspondents whose ID is in this list.
- name_contains: Case-insensitive substring filter on name.
- name_exact: Case-insensitive exact match on name.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.correspondents.Correspondentobjects.
64 def get(self, id: int) -> Correspondent: 65 """Fetch a single correspondent by its ID. 66 67 Args: 68 id: Numeric correspondent ID. 69 70 Returns: 71 The :class:`~easypaperless.models.correspondents.Correspondent` with the given ID. 72 73 Raises: 74 ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID. 75 """ 76 return cast(Correspondent, self._run(self._async_correspondents.get(id)))
Fetch a single correspondent by its ID.
Arguments:
- id: Numeric correspondent ID.
Returns:
The
~easypaperless.models.correspondents.Correspondentwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID.
78 def create( 79 self, 80 *, 81 name: str, 82 match: str | None | _Unset = UNSET, 83 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 84 is_insensitive: bool = True, 85 owner: int | None | _Unset = UNSET, 86 set_permissions: SetPermissions | None = None, 87 ) -> Correspondent: 88 """Create a new correspondent. 89 90 Args: 91 name: Correspondent name. Must be unique. 92 match: Auto-matching pattern. 93 matching_algorithm: Controls how ``match`` is applied. 94 is_insensitive: When ``True``, ``match`` is case-insensitive. 95 Defaults to ``True``, matching the paperless-ngx API default. 96 owner: Numeric user ID to assign as owner. 97 set_permissions: Explicit view/change permission sets. 98 99 Returns: 100 The newly created :class:`~easypaperless.models.correspondents.Correspondent`. 101 """ 102 return cast( 103 Correspondent, 104 self._run( 105 self._async_correspondents.create( 106 name=name, 107 match=match, 108 matching_algorithm=matching_algorithm, 109 is_insensitive=is_insensitive, 110 owner=owner, 111 set_permissions=set_permissions, 112 ) 113 ), 114 )
Create a new correspondent.
Arguments:
- name: Correspondent name. Must be unique.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. Defaults toTrue, matching the paperless-ngx API default. - owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.correspondents.Correspondent.
116 def update( 117 self, 118 id: int, 119 *, 120 name: str | None | _Unset = UNSET, 121 match: str | None | _Unset = UNSET, 122 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 123 is_insensitive: bool | None | _Unset = UNSET, 124 owner: int | None | _Unset = UNSET, 125 set_permissions: SetPermissions | None | _Unset = UNSET, 126 ) -> Correspondent: 127 """Partially update a correspondent (PATCH semantics). 128 129 Args: 130 id: Numeric ID of the correspondent to update. 131 name: Correspondent name. 132 match: Auto-matching pattern. 133 matching_algorithm: Controls how ``match`` is applied. 134 is_insensitive: When ``True``, ``match`` is case-insensitive. 135 owner: Numeric user ID to assign as owner. 136 Pass ``None`` to clear the owner. 137 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 138 set_permissions: Explicit view/change permission sets. 139 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 140 141 Returns: 142 The updated :class:`~easypaperless.models.correspondents.Correspondent`. 143 """ 144 return cast( 145 Correspondent, 146 self._run( 147 self._async_correspondents.update( 148 id, 149 name=name, 150 match=match, 151 matching_algorithm=matching_algorithm, 152 is_insensitive=is_insensitive, 153 owner=owner, 154 set_permissions=set_permissions, 155 ) 156 ), 157 )
Partially update a correspondent (PATCH semantics).
Arguments:
- id: Numeric ID of the correspondent to update.
- name: Correspondent name.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. - owner: Numeric user ID to assign as owner.
Pass
Noneto clear the owner. Omit (or pass~easypaperless.UNSET) to leave unchanged. - set_permissions: Explicit view/change permission sets.
Omit (or pass
~easypaperless.UNSET) to leave unchanged.
Returns:
The updated
~easypaperless.models.correspondents.Correspondent.
159 def delete(self, id: int) -> None: 160 """Delete a correspondent. 161 162 Args: 163 id: Numeric ID of the correspondent to delete. 164 165 Raises: 166 ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID. 167 """ 168 self._run(self._async_correspondents.delete(id))
Delete a correspondent.
Arguments:
- id: Numeric ID of the correspondent to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no correspondent exists with that ID.
170 def bulk_delete(self, ids: List[int]) -> None: 171 """Permanently delete multiple correspondents in a single request. 172 173 Args: 174 ids: List of correspondent IDs to delete. 175 """ 176 self._run(self._async_correspondents.bulk_delete(ids))
Permanently delete multiple correspondents in a single request.
Arguments:
- ids: List of correspondent IDs to delete.
178 def bulk_set_permissions( 179 self, 180 ids: List[int], 181 *, 182 set_permissions: SetPermissions | None = None, 183 owner: int | None = None, 184 merge: bool = False, 185 ) -> None: 186 """Set permissions and/or owner on multiple correspondents. 187 188 Args: 189 ids: List of correspondent IDs to modify. 190 set_permissions: Explicit view/change permission sets. 191 owner: Numeric user ID to assign as owner. 192 merge: When ``True``, new permissions are merged with existing ones. 193 """ 194 self._run( 195 self._async_correspondents.bulk_set_permissions( 196 ids, set_permissions=set_permissions, owner=owner, merge=merge 197 ) 198 )
Set permissions and/or owner on multiple correspondents.
Arguments:
- ids: List of correspondent IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as owner.
- merge: When
True, new permissions are merged with existing ones.
16class SyncCustomFieldsResource: 17 """Sync accessor for custom fields: ``client.custom_fields``.""" 18 19 def __init__(self, async_custom_fields: CustomFieldsResource, run: Any) -> None: 20 self._async_custom_fields = async_custom_fields 21 self._run = run 22 23 def list( 24 self, 25 *, 26 name_contains: str | None = None, 27 name_exact: str | None = None, 28 page: int | None = None, 29 page_size: int | None = None, 30 ordering: str | None = None, 31 descending: bool = False, 32 ) -> List[CustomField]: 33 """Return all custom fields defined in paperless-ngx. 34 35 Args: 36 name_contains: Case-insensitive substring filter on name. 37 name_exact: Case-insensitive exact match on name. 38 page: Return only this specific page (1-based). 39 page_size: Number of results per page. 40 ordering: Field to sort by. 41 descending: When ``True``, reverses the sort direction. 42 43 Returns: 44 List of :class:`~easypaperless.models.custom_fields.CustomField` objects. 45 """ 46 return cast( 47 List[CustomField], 48 self._run( 49 self._async_custom_fields.list( 50 name_contains=name_contains, 51 name_exact=name_exact, 52 page=page, 53 page_size=page_size, 54 ordering=ordering, 55 descending=descending, 56 ) 57 ), 58 ) 59 60 def get(self, id: int) -> CustomField: 61 """Fetch a single custom field by its ID. 62 63 Args: 64 id: Numeric custom-field ID. 65 66 Returns: 67 The :class:`~easypaperless.models.custom_fields.CustomField` with the given ID. 68 69 Raises: 70 ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID. 71 """ 72 return cast(CustomField, self._run(self._async_custom_fields.get(id))) 73 74 def create( 75 self, 76 *, 77 name: str, 78 data_type: str, 79 extra_data: Any | None = None, 80 owner: int | None | _Unset = UNSET, 81 set_permissions: SetPermissions | None = None, 82 ) -> CustomField: 83 """Create a new custom field. 84 85 Args: 86 name: Field name shown in the UI. Must be unique. 87 data_type: Value type. One of ``"string"``, ``"boolean"``, 88 ``"integer"``, ``"float"``, ``"monetary"``, ``"date"``, 89 ``"url"``, ``"documentlink"``, ``"select"``. 90 extra_data: Additional configuration for the field type. 91 owner: Numeric user ID to assign as owner. 92 set_permissions: Explicit view/change permission sets. 93 94 Returns: 95 The newly created :class:`~easypaperless.models.custom_fields.CustomField`. 96 """ 97 return cast( 98 CustomField, 99 self._run( 100 self._async_custom_fields.create( 101 name=name, 102 data_type=data_type, 103 extra_data=extra_data, 104 owner=owner, 105 set_permissions=set_permissions, 106 ) 107 ), 108 ) 109 110 def update( 111 self, 112 id: int, 113 *, 114 name: str | None | _Unset = UNSET, 115 data_type: str | None | _Unset = UNSET, 116 extra_data: Any | None | _Unset = UNSET, 117 ) -> CustomField: 118 """Partially update a custom field (PATCH semantics). 119 120 Args: 121 id: Numeric ID of the custom field to update. 122 name: Field name shown in the UI. 123 data_type: Value type (e.g. ``"string"``, ``"boolean"``, ``"integer"``). 124 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 125 extra_data: Additional configuration for the field type. 126 127 Returns: 128 The updated :class:`~easypaperless.models.custom_fields.CustomField`. 129 """ 130 return cast( 131 CustomField, 132 self._run( 133 self._async_custom_fields.update( 134 id, 135 name=name, 136 data_type=data_type, 137 extra_data=extra_data, 138 ) 139 ), 140 ) 141 142 def delete(self, id: int) -> None: 143 """Delete a custom field. 144 145 Args: 146 id: Numeric ID of the custom field to delete. 147 148 Raises: 149 ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID. 150 """ 151 self._run(self._async_custom_fields.delete(id))
Sync accessor for custom fields: client.custom_fields.
23 def list( 24 self, 25 *, 26 name_contains: str | None = None, 27 name_exact: str | None = None, 28 page: int | None = None, 29 page_size: int | None = None, 30 ordering: str | None = None, 31 descending: bool = False, 32 ) -> List[CustomField]: 33 """Return all custom fields defined in paperless-ngx. 34 35 Args: 36 name_contains: Case-insensitive substring filter on name. 37 name_exact: Case-insensitive exact match on name. 38 page: Return only this specific page (1-based). 39 page_size: Number of results per page. 40 ordering: Field to sort by. 41 descending: When ``True``, reverses the sort direction. 42 43 Returns: 44 List of :class:`~easypaperless.models.custom_fields.CustomField` objects. 45 """ 46 return cast( 47 List[CustomField], 48 self._run( 49 self._async_custom_fields.list( 50 name_contains=name_contains, 51 name_exact=name_exact, 52 page=page, 53 page_size=page_size, 54 ordering=ordering, 55 descending=descending, 56 ) 57 ), 58 )
Return all custom fields defined in paperless-ngx.
Arguments:
- name_contains: Case-insensitive substring filter on name.
- name_exact: Case-insensitive exact match on name.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.custom_fields.CustomFieldobjects.
60 def get(self, id: int) -> CustomField: 61 """Fetch a single custom field by its ID. 62 63 Args: 64 id: Numeric custom-field ID. 65 66 Returns: 67 The :class:`~easypaperless.models.custom_fields.CustomField` with the given ID. 68 69 Raises: 70 ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID. 71 """ 72 return cast(CustomField, self._run(self._async_custom_fields.get(id)))
Fetch a single custom field by its ID.
Arguments:
- id: Numeric custom-field ID.
Returns:
The
~easypaperless.models.custom_fields.CustomFieldwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID.
74 def create( 75 self, 76 *, 77 name: str, 78 data_type: str, 79 extra_data: Any | None = None, 80 owner: int | None | _Unset = UNSET, 81 set_permissions: SetPermissions | None = None, 82 ) -> CustomField: 83 """Create a new custom field. 84 85 Args: 86 name: Field name shown in the UI. Must be unique. 87 data_type: Value type. One of ``"string"``, ``"boolean"``, 88 ``"integer"``, ``"float"``, ``"monetary"``, ``"date"``, 89 ``"url"``, ``"documentlink"``, ``"select"``. 90 extra_data: Additional configuration for the field type. 91 owner: Numeric user ID to assign as owner. 92 set_permissions: Explicit view/change permission sets. 93 94 Returns: 95 The newly created :class:`~easypaperless.models.custom_fields.CustomField`. 96 """ 97 return cast( 98 CustomField, 99 self._run( 100 self._async_custom_fields.create( 101 name=name, 102 data_type=data_type, 103 extra_data=extra_data, 104 owner=owner, 105 set_permissions=set_permissions, 106 ) 107 ), 108 )
Create a new custom field.
Arguments:
- name: Field name shown in the UI. Must be unique.
- data_type: Value type. One of
"string","boolean","integer","float","monetary","date","url","documentlink","select". - extra_data: Additional configuration for the field type.
- owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.custom_fields.CustomField.
110 def update( 111 self, 112 id: int, 113 *, 114 name: str | None | _Unset = UNSET, 115 data_type: str | None | _Unset = UNSET, 116 extra_data: Any | None | _Unset = UNSET, 117 ) -> CustomField: 118 """Partially update a custom field (PATCH semantics). 119 120 Args: 121 id: Numeric ID of the custom field to update. 122 name: Field name shown in the UI. 123 data_type: Value type (e.g. ``"string"``, ``"boolean"``, ``"integer"``). 124 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 125 extra_data: Additional configuration for the field type. 126 127 Returns: 128 The updated :class:`~easypaperless.models.custom_fields.CustomField`. 129 """ 130 return cast( 131 CustomField, 132 self._run( 133 self._async_custom_fields.update( 134 id, 135 name=name, 136 data_type=data_type, 137 extra_data=extra_data, 138 ) 139 ), 140 )
Partially update a custom field (PATCH semantics).
Arguments:
- id: Numeric ID of the custom field to update.
- name: Field name shown in the UI.
- data_type: Value type (e.g.
"string","boolean","integer"). Omit (or pass~easypaperless.UNSET) to leave unchanged. - extra_data: Additional configuration for the field type.
Returns:
The updated
~easypaperless.models.custom_fields.CustomField.
142 def delete(self, id: int) -> None: 143 """Delete a custom field. 144 145 Args: 146 id: Numeric ID of the custom field to delete. 147 148 Raises: 149 ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID. 150 """ 151 self._run(self._async_custom_fields.delete(id))
Delete a custom field.
Arguments:
- id: Numeric ID of the custom field to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no custom field exists with that ID.
17class SyncDocumentTypesResource: 18 """Sync accessor for document types: ``client.document_types``.""" 19 20 def __init__(self, async_document_types: DocumentTypesResource, run: Any) -> None: 21 self._async_document_types = async_document_types 22 self._run = run 23 24 def list( 25 self, 26 *, 27 ids: List[int] | None = None, 28 name_contains: str | None = None, 29 name_exact: str | None = None, 30 page: int | None = None, 31 page_size: int | None = None, 32 ordering: str | None = None, 33 descending: bool = False, 34 ) -> List[DocumentType]: 35 """Return document types defined in paperless-ngx. 36 37 Args: 38 ids: Return only document types whose ID is in this list. 39 name_contains: Case-insensitive substring filter on name. 40 name_exact: Case-insensitive exact match on name. 41 page: Return only this specific page (1-based). 42 page_size: Number of results per page. 43 ordering: Field to sort by. 44 descending: When ``True``, reverses the sort direction. 45 46 Returns: 47 List of :class:`~easypaperless.models.document_types.DocumentType` objects. 48 """ 49 return cast( 50 List[DocumentType], 51 self._run( 52 self._async_document_types.list( 53 ids=ids, 54 name_contains=name_contains, 55 name_exact=name_exact, 56 page=page, 57 page_size=page_size, 58 ordering=ordering, 59 descending=descending, 60 ) 61 ), 62 ) 63 64 def get(self, id: int) -> DocumentType: 65 """Fetch a single document type by its ID. 66 67 Args: 68 id: Numeric document-type ID. 69 70 Returns: 71 The :class:`~easypaperless.models.document_types.DocumentType` with the given ID. 72 73 Raises: 74 ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID. 75 """ 76 return cast(DocumentType, self._run(self._async_document_types.get(id))) 77 78 def create( 79 self, 80 *, 81 name: str, 82 match: str | None | _Unset = UNSET, 83 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 84 is_insensitive: bool = True, 85 owner: int | None | _Unset = UNSET, 86 set_permissions: SetPermissions | None = None, 87 ) -> DocumentType: 88 """Create a new document type. 89 90 Args: 91 name: Document-type name. Must be unique. 92 match: Auto-matching pattern. 93 matching_algorithm: Controls how ``match`` is applied. 94 is_insensitive: When ``True``, ``match`` is case-insensitive. 95 Defaults to ``True``, matching the paperless-ngx API default. 96 owner: Numeric user ID to assign as owner. 97 set_permissions: Explicit view/change permission sets. 98 99 Returns: 100 The newly created :class:`~easypaperless.models.document_types.DocumentType`. 101 """ 102 return cast( 103 DocumentType, 104 self._run( 105 self._async_document_types.create( 106 name=name, 107 match=match, 108 matching_algorithm=matching_algorithm, 109 is_insensitive=is_insensitive, 110 owner=owner, 111 set_permissions=set_permissions, 112 ) 113 ), 114 ) 115 116 def update( 117 self, 118 id: int, 119 *, 120 name: str | None | _Unset = UNSET, 121 match: str | None | _Unset = UNSET, 122 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 123 is_insensitive: bool | None | _Unset = UNSET, 124 owner: int | None | _Unset = UNSET, 125 set_permissions: SetPermissions | None | _Unset = UNSET, 126 ) -> DocumentType: 127 """Partially update a document type (PATCH semantics). 128 129 Args: 130 id: Numeric ID of the document type to update. 131 name: Document-type name. 132 match: Auto-matching pattern. 133 matching_algorithm: Controls how ``match`` is applied. 134 is_insensitive: When ``True``, ``match`` is case-insensitive. 135 owner: Numeric user ID to assign as owner. 136 Pass ``None`` to clear the owner. 137 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 138 set_permissions: Explicit view/change permission sets. 139 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 140 141 Returns: 142 The updated :class:`~easypaperless.models.document_types.DocumentType`. 143 """ 144 return cast( 145 DocumentType, 146 self._run( 147 self._async_document_types.update( 148 id, 149 name=name, 150 match=match, 151 matching_algorithm=matching_algorithm, 152 is_insensitive=is_insensitive, 153 owner=owner, 154 set_permissions=set_permissions, 155 ) 156 ), 157 ) 158 159 def delete(self, id: int) -> None: 160 """Delete a document type. 161 162 Args: 163 id: Numeric ID of the document type to delete. 164 165 Raises: 166 ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID. 167 """ 168 self._run(self._async_document_types.delete(id)) 169 170 def bulk_delete(self, ids: List[int]) -> None: 171 """Permanently delete multiple document types in a single request. 172 173 Args: 174 ids: List of document type IDs to delete. 175 """ 176 self._run(self._async_document_types.bulk_delete(ids)) 177 178 def bulk_set_permissions( 179 self, 180 ids: List[int], 181 *, 182 set_permissions: SetPermissions | None = None, 183 owner: int | None = None, 184 merge: bool = False, 185 ) -> None: 186 """Set permissions and/or owner on multiple document types. 187 188 Args: 189 ids: List of document type IDs to modify. 190 set_permissions: Explicit view/change permission sets. 191 owner: Numeric user ID to assign as owner. 192 merge: When ``True``, new permissions are merged with existing ones. 193 """ 194 self._run( 195 self._async_document_types.bulk_set_permissions( 196 ids, set_permissions=set_permissions, owner=owner, merge=merge 197 ) 198 )
Sync accessor for document types: client.document_types.
24 def list( 25 self, 26 *, 27 ids: List[int] | None = None, 28 name_contains: str | None = None, 29 name_exact: str | None = None, 30 page: int | None = None, 31 page_size: int | None = None, 32 ordering: str | None = None, 33 descending: bool = False, 34 ) -> List[DocumentType]: 35 """Return document types defined in paperless-ngx. 36 37 Args: 38 ids: Return only document types whose ID is in this list. 39 name_contains: Case-insensitive substring filter on name. 40 name_exact: Case-insensitive exact match on name. 41 page: Return only this specific page (1-based). 42 page_size: Number of results per page. 43 ordering: Field to sort by. 44 descending: When ``True``, reverses the sort direction. 45 46 Returns: 47 List of :class:`~easypaperless.models.document_types.DocumentType` objects. 48 """ 49 return cast( 50 List[DocumentType], 51 self._run( 52 self._async_document_types.list( 53 ids=ids, 54 name_contains=name_contains, 55 name_exact=name_exact, 56 page=page, 57 page_size=page_size, 58 ordering=ordering, 59 descending=descending, 60 ) 61 ), 62 )
Return document types defined in paperless-ngx.
Arguments:
- ids: Return only document types whose ID is in this list.
- name_contains: Case-insensitive substring filter on name.
- name_exact: Case-insensitive exact match on name.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.document_types.DocumentTypeobjects.
64 def get(self, id: int) -> DocumentType: 65 """Fetch a single document type by its ID. 66 67 Args: 68 id: Numeric document-type ID. 69 70 Returns: 71 The :class:`~easypaperless.models.document_types.DocumentType` with the given ID. 72 73 Raises: 74 ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID. 75 """ 76 return cast(DocumentType, self._run(self._async_document_types.get(id)))
Fetch a single document type by its ID.
Arguments:
- id: Numeric document-type ID.
Returns:
The
~easypaperless.models.document_types.DocumentTypewith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID.
78 def create( 79 self, 80 *, 81 name: str, 82 match: str | None | _Unset = UNSET, 83 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 84 is_insensitive: bool = True, 85 owner: int | None | _Unset = UNSET, 86 set_permissions: SetPermissions | None = None, 87 ) -> DocumentType: 88 """Create a new document type. 89 90 Args: 91 name: Document-type name. Must be unique. 92 match: Auto-matching pattern. 93 matching_algorithm: Controls how ``match`` is applied. 94 is_insensitive: When ``True``, ``match`` is case-insensitive. 95 Defaults to ``True``, matching the paperless-ngx API default. 96 owner: Numeric user ID to assign as owner. 97 set_permissions: Explicit view/change permission sets. 98 99 Returns: 100 The newly created :class:`~easypaperless.models.document_types.DocumentType`. 101 """ 102 return cast( 103 DocumentType, 104 self._run( 105 self._async_document_types.create( 106 name=name, 107 match=match, 108 matching_algorithm=matching_algorithm, 109 is_insensitive=is_insensitive, 110 owner=owner, 111 set_permissions=set_permissions, 112 ) 113 ), 114 )
Create a new document type.
Arguments:
- name: Document-type name. Must be unique.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. Defaults toTrue, matching the paperless-ngx API default. - owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.document_types.DocumentType.
116 def update( 117 self, 118 id: int, 119 *, 120 name: str | None | _Unset = UNSET, 121 match: str | None | _Unset = UNSET, 122 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 123 is_insensitive: bool | None | _Unset = UNSET, 124 owner: int | None | _Unset = UNSET, 125 set_permissions: SetPermissions | None | _Unset = UNSET, 126 ) -> DocumentType: 127 """Partially update a document type (PATCH semantics). 128 129 Args: 130 id: Numeric ID of the document type to update. 131 name: Document-type name. 132 match: Auto-matching pattern. 133 matching_algorithm: Controls how ``match`` is applied. 134 is_insensitive: When ``True``, ``match`` is case-insensitive. 135 owner: Numeric user ID to assign as owner. 136 Pass ``None`` to clear the owner. 137 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 138 set_permissions: Explicit view/change permission sets. 139 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 140 141 Returns: 142 The updated :class:`~easypaperless.models.document_types.DocumentType`. 143 """ 144 return cast( 145 DocumentType, 146 self._run( 147 self._async_document_types.update( 148 id, 149 name=name, 150 match=match, 151 matching_algorithm=matching_algorithm, 152 is_insensitive=is_insensitive, 153 owner=owner, 154 set_permissions=set_permissions, 155 ) 156 ), 157 )
Partially update a document type (PATCH semantics).
Arguments:
- id: Numeric ID of the document type to update.
- name: Document-type name.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. - owner: Numeric user ID to assign as owner.
Pass
Noneto clear the owner. Omit (or pass~easypaperless.UNSET) to leave unchanged. - set_permissions: Explicit view/change permission sets.
Omit (or pass
~easypaperless.UNSET) to leave unchanged.
Returns:
The updated
~easypaperless.models.document_types.DocumentType.
159 def delete(self, id: int) -> None: 160 """Delete a document type. 161 162 Args: 163 id: Numeric ID of the document type to delete. 164 165 Raises: 166 ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID. 167 """ 168 self._run(self._async_document_types.delete(id))
Delete a document type.
Arguments:
- id: Numeric ID of the document type to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document type exists with that ID.
170 def bulk_delete(self, ids: List[int]) -> None: 171 """Permanently delete multiple document types in a single request. 172 173 Args: 174 ids: List of document type IDs to delete. 175 """ 176 self._run(self._async_document_types.bulk_delete(ids))
Permanently delete multiple document types in a single request.
Arguments:
- ids: List of document type IDs to delete.
178 def bulk_set_permissions( 179 self, 180 ids: List[int], 181 *, 182 set_permissions: SetPermissions | None = None, 183 owner: int | None = None, 184 merge: bool = False, 185 ) -> None: 186 """Set permissions and/or owner on multiple document types. 187 188 Args: 189 ids: List of document type IDs to modify. 190 set_permissions: Explicit view/change permission sets. 191 owner: Numeric user ID to assign as owner. 192 merge: When ``True``, new permissions are merged with existing ones. 193 """ 194 self._run( 195 self._async_document_types.bulk_set_permissions( 196 ids, set_permissions=set_permissions, owner=owner, merge=merge 197 ) 198 )
Set permissions and/or owner on multiple document types.
Arguments:
- ids: List of document type IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as owner.
- merge: When
True, new permissions are merged with existing ones.
72class SyncDocumentsResource: 73 """Sync accessor for documents: ``client.documents``.""" 74 75 def __init__(self, async_documents: DocumentsResource, run: Any) -> None: 76 self._async_documents = async_documents 77 self._run = run 78 self.notes = SyncNotesResource(async_documents.notes, run) 79 80 def get(self, id: int, *, include_metadata: bool = False) -> Document: 81 """Fetch a single document by its ID. 82 83 Args: 84 id: Numeric paperless-ngx document ID. 85 include_metadata: When ``True``, the extended file-level metadata 86 is fetched concurrently and attached to the document. 87 Default: ``False``. 88 89 Returns: 90 The :class:`~easypaperless.models.documents.Document` with the 91 given ID. 92 93 Raises: 94 ~easypaperless.exceptions.NotFoundError: If no document exists 95 with that ID. 96 """ 97 return cast( 98 Document, self._run(self._async_documents.get(id, include_metadata=include_metadata)) 99 ) 100 101 def get_metadata(self, id: int) -> DocumentMetadata: 102 """Fetch the extended file-level metadata for a document. 103 104 Args: 105 id: Numeric paperless-ngx document ID. 106 107 Returns: 108 A :class:`~easypaperless.models.documents.DocumentMetadata` instance. 109 110 Raises: 111 ~easypaperless.exceptions.NotFoundError: If no document exists 112 with that ID. 113 """ 114 return cast(DocumentMetadata, self._run(self._async_documents.get_metadata(id))) 115 116 def list( 117 self, 118 *, 119 search: str | None = None, 120 search_mode: str = "title_or_content", 121 ids: List[int] | None = None, 122 tags: List[int | str] | None = None, 123 any_tags: List[int | str] | None = None, 124 exclude_tags: List[int | str] | None = None, 125 correspondent: int | str | None | _Unset = UNSET, 126 any_correspondent: List[int | str] | None = None, 127 exclude_correspondents: List[int | str] | None = None, 128 document_type: int | str | None | _Unset = UNSET, 129 document_type_name_contains: str | None = None, 130 document_type_name_exact: str | None = None, 131 any_document_type: List[int | str] | None = None, 132 exclude_document_types: List[int | str] | None = None, 133 storage_path: int | str | None | _Unset = UNSET, 134 any_storage_paths: List[int | str] | None = None, 135 exclude_storage_paths: List[int | str] | None = None, 136 owner: int | None | _Unset = UNSET, 137 exclude_owners: List[int] | None = None, 138 custom_fields: List[int | str] | None = None, 139 any_custom_fields: List[int | str] | None = None, 140 exclude_custom_fields: List[int | str] | None = None, 141 custom_field_query: List[Any] | None = None, 142 archive_serial_number: int | None | _Unset = UNSET, 143 archive_serial_number_from: int | None = None, 144 archive_serial_number_till: int | None = None, 145 created_after: date | str | None = None, 146 created_before: date | str | None = None, 147 added_after: date | datetime | str | None = None, 148 added_from: date | datetime | str | None = None, 149 added_before: date | datetime | str | None = None, 150 added_until: date | datetime | str | None = None, 151 modified_after: date | datetime | str | None = None, 152 modified_from: date | datetime | str | None = None, 153 modified_before: date | datetime | str | None = None, 154 modified_until: date | datetime | str | None = None, 155 checksum: str | None = None, 156 page_size: int = 25, 157 page: int | None = None, 158 ordering: str | None = None, 159 descending: bool = False, 160 max_results: int | None = None, 161 on_page: Callable[[int, int | None], None] | None = None, 162 ) -> List[Document]: 163 """Return a filtered list of documents. 164 165 All tag, correspondent, document-type, storage-path, and custom-field 166 parameters accept either integer IDs or string names. 167 168 Args: 169 search: Search string. Behaviour depends on ``search_mode``. 170 search_mode: How ``search`` is applied. One of: 171 ``"title_or_content"`` *(default)*, ``"title"``, ``"query"``, 172 ``"original_filename"``. 173 ids: Return only documents whose ID is in this list. 174 tags: Documents must have **all** of these tags (AND semantics). 175 any_tags: Documents must have **at least one** of these tags. 176 exclude_tags: Documents must have **none** of these tags. 177 correspondent: Filter to documents assigned to this correspondent. 178 Pass ``None`` to return only documents with no correspondent set. 179 any_correspondent: Filter to documents assigned to any of these. 180 exclude_correspondents: Exclude documents assigned to any of these. 181 document_type: Filter to documents of exactly this type. 182 Pass ``None`` to return only documents with no document type set. 183 document_type_name_contains: Case-insensitive substring filter on document type name. 184 document_type_name_exact: Case-insensitive exact match on document type name. 185 any_document_type: Filter to documents whose type is any of these. 186 exclude_document_types: Exclude documents whose type is any of these. 187 storage_path: Filter to documents assigned to this storage path. 188 Pass ``None`` to return only documents with no storage path set. 189 any_storage_paths: Filter to documents assigned to any of these paths. 190 exclude_storage_paths: Exclude documents assigned to any of these paths. 191 owner: Filter to documents owned by this user ID. 192 Pass ``None`` to return only documents with no owner set. 193 exclude_owners: Exclude documents owned by any of these user IDs. 194 custom_fields: Documents must have **all** of these custom fields set. 195 any_custom_fields: Documents must have **at least one** of these fields. 196 exclude_custom_fields: Documents must have **none** of these fields. 197 custom_field_query: Filter documents by custom field values. 198 archive_serial_number: Filter by exact archive serial number. 199 Pass ``None`` to return only documents with no ASN set. 200 archive_serial_number_from: Filter by ASN >= this value. 201 archive_serial_number_till: Filter by ASN <= this value. 202 created_after: Only documents created after this date. 203 created_before: Only documents created before this date. 204 added_after: Only documents added after this date/time. 205 added_from: Only documents added on or after this date/time. 206 added_before: Only documents added before this date/time. 207 added_until: Only documents added on or before this date/time. 208 modified_after: Only documents modified after this date/time. 209 modified_from: Only documents modified on or after this date/time. 210 modified_before: Only documents modified before this date/time. 211 modified_until: Only documents modified on or before this date/time. 212 checksum: MD5 checksum of the original file (exact match). 213 page_size: Number of results per API page. Default: ``25``. 214 page: Return only this specific page (1-based). 215 ordering: Field name to sort by. 216 descending: When ``True``, reverses the sort direction. 217 max_results: Stop after collecting this many documents. 218 on_page: Callback invoked after each page fetch. 219 220 Returns: 221 List of :class:`~easypaperless.models.documents.Document` objects. 222 """ 223 return cast( 224 List[Document], 225 self._run( 226 self._async_documents.list( 227 search=search, 228 search_mode=search_mode, 229 ids=ids, 230 tags=tags, 231 any_tags=any_tags, 232 exclude_tags=exclude_tags, 233 correspondent=correspondent, 234 any_correspondent=any_correspondent, 235 exclude_correspondents=exclude_correspondents, 236 document_type=document_type, 237 document_type_name_contains=document_type_name_contains, 238 document_type_name_exact=document_type_name_exact, 239 any_document_type=any_document_type, 240 exclude_document_types=exclude_document_types, 241 storage_path=storage_path, 242 any_storage_paths=any_storage_paths, 243 exclude_storage_paths=exclude_storage_paths, 244 owner=owner, 245 exclude_owners=exclude_owners, 246 custom_fields=custom_fields, 247 any_custom_fields=any_custom_fields, 248 exclude_custom_fields=exclude_custom_fields, 249 custom_field_query=custom_field_query, 250 archive_serial_number=archive_serial_number, 251 archive_serial_number_from=archive_serial_number_from, 252 archive_serial_number_till=archive_serial_number_till, 253 created_after=created_after, 254 created_before=created_before, 255 added_after=added_after, 256 added_from=added_from, 257 added_before=added_before, 258 added_until=added_until, 259 modified_after=modified_after, 260 modified_from=modified_from, 261 modified_before=modified_before, 262 modified_until=modified_until, 263 checksum=checksum, 264 page_size=page_size, 265 page=page, 266 ordering=ordering, 267 descending=descending, 268 max_results=max_results, 269 on_page=on_page, 270 ) 271 ), 272 ) 273 274 def update( 275 self, 276 id: int, 277 *, 278 title: str | None | _Unset = UNSET, 279 content: str | None | _Unset = UNSET, 280 created: date | str | None | _Unset = UNSET, 281 correspondent: int | str | None | _Unset = UNSET, 282 document_type: int | str | None | _Unset = UNSET, 283 storage_path: int | str | None | _Unset = UNSET, 284 tags: List[int | str] | None | _Unset = UNSET, 285 archive_serial_number: int | None | _Unset = UNSET, 286 custom_fields: List[dict[str, Any]] | None | _Unset = UNSET, 287 owner: int | None | _Unset = UNSET, 288 set_permissions: SetPermissions | None | _Unset = UNSET, 289 remove_inbox_tags: bool | None | _Unset = UNSET, 290 ) -> Document: 291 """Partially update a document (PATCH semantics). 292 293 Args: 294 id: Numeric ID of the document to update. 295 title: New document title. 296 content: OCR text content of the document. 297 created: Creation date as an ISO-8601 string (``"YYYY-MM-DD"``) or a 298 :class:`~datetime.date` object. 299 correspondent: Correspondent to assign, as an ID or name. 300 Pass ``None`` to clear the correspondent. 301 document_type: Document type to assign, as an ID or name. 302 Pass ``None`` to clear the document type. 303 storage_path: Storage path to assign, as an ID or name. 304 Pass ``None`` to clear the storage path. 305 tags: Full replacement list of tags (IDs or names). 306 archive_serial_number: Archive serial number to assign. 307 Pass ``None`` to clear the archive serial number. 308 custom_fields: List of ``{"field": <field_id>, "value": ...}`` dicts. 309 owner: Numeric user ID to assign as document owner. 310 Pass ``None`` to clear the owner. 311 set_permissions: Explicit view/change permission sets. 312 remove_inbox_tags: When ``True``, removes all inbox tags from the document. 313 314 Returns: 315 The updated :class:`~easypaperless.models.documents.Document`. 316 """ 317 return cast( 318 Document, 319 self._run( 320 self._async_documents.update( 321 id, 322 title=title, 323 content=content, 324 created=created, 325 correspondent=correspondent, 326 document_type=document_type, 327 storage_path=storage_path, 328 tags=tags, 329 archive_serial_number=archive_serial_number, 330 custom_fields=custom_fields, 331 owner=owner, 332 set_permissions=set_permissions, 333 remove_inbox_tags=remove_inbox_tags, 334 ) 335 ), 336 ) 337 338 def delete(self, id: int) -> None: 339 """Permanently delete a document. 340 341 Args: 342 id: Numeric ID of the document to delete. 343 344 Raises: 345 ~easypaperless.exceptions.NotFoundError: If no document exists 346 with that ID. 347 """ 348 self._run(self._async_documents.delete(id)) 349 350 def download(self, id: int, *, original: bool = False) -> bytes: 351 """Download the binary content of a document. 352 353 Args: 354 id: Numeric ID of the document to download. 355 original: If ``False`` *(default)*, returns the archived PDF. 356 If ``True``, returns the original uploaded file. 357 358 Returns: 359 Raw file bytes. 360 """ 361 return cast(bytes, self._run(self._async_documents.download(id, original=original))) 362 363 def upload( 364 self, 365 file: str | Path, 366 *, 367 title: str | None = None, 368 created: date | str | None = None, 369 correspondent: int | str | None | _Unset = UNSET, 370 document_type: int | str | None | _Unset = UNSET, 371 storage_path: int | str | None | _Unset = UNSET, 372 tags: List[int | str] | None = None, 373 archive_serial_number: int | None | _Unset = UNSET, 374 custom_fields: List[dict[str, Any]] | None = None, 375 wait: bool = False, 376 poll_interval: float | None = None, 377 poll_timeout: float | None = None, 378 ) -> str | Document: 379 """Upload a document to paperless-ngx. 380 381 Args: 382 file: Path to the file to upload. 383 title: Title to assign to the document. 384 created: Creation date as an ISO-8601 string (``"YYYY-MM-DD"``) or a 385 :class:`~datetime.date` object. 386 correspondent: Correspondent to assign, as an ID or name. 387 document_type: Document type to assign, as an ID or name. 388 storage_path: Storage path to assign, as an ID or name. 389 tags: Tags to assign, as IDs or names. 390 archive_serial_number: Archive serial number to assign. 391 custom_fields: List of ``{"field": <field_id>, "value": ...}`` dicts. 392 wait: If ``False`` *(default)*, returns immediately with the task ID. 393 If ``True``, polls until processing completes. 394 poll_interval: Override the client-level ``poll_interval`` (in seconds). 395 poll_timeout: Override the client-level ``poll_timeout`` (in seconds). 396 397 Returns: 398 The Celery task ID string when ``wait=False``, or the fully 399 processed :class:`~easypaperless.models.documents.Document` 400 when ``wait=True``. 401 402 Raises: 403 ~easypaperless.exceptions.UploadError: If processing fails. 404 ~easypaperless.exceptions.TaskTimeoutError: If timeout is exceeded. 405 """ 406 return cast( 407 str | Document, 408 self._run( 409 self._async_documents.upload( 410 file, 411 title=title, 412 created=created, 413 correspondent=correspondent, 414 document_type=document_type, 415 storage_path=storage_path, 416 tags=tags, 417 archive_serial_number=archive_serial_number, 418 custom_fields=custom_fields, 419 wait=wait, 420 poll_interval=poll_interval, 421 poll_timeout=poll_timeout, 422 ) 423 ), 424 ) 425 426 def bulk_add_tag(self, document_ids: List[int], tag: int | str) -> None: 427 """Add a tag to multiple documents in a single request. 428 429 Args: 430 document_ids: List of document IDs to tag. 431 tag: Tag to add, as an ID or name. 432 """ 433 self._run(self._async_documents.bulk_add_tag(document_ids, tag)) 434 435 def bulk_remove_tag(self, document_ids: List[int], tag: int | str) -> None: 436 """Remove a tag from multiple documents in a single request. 437 438 Args: 439 document_ids: List of document IDs to un-tag. 440 tag: Tag to remove, as an ID or name. 441 """ 442 self._run(self._async_documents.bulk_remove_tag(document_ids, tag)) 443 444 def bulk_modify_tags( 445 self, 446 document_ids: List[int], 447 *, 448 add_tags: List[int | str] | None = None, 449 remove_tags: List[int | str] | None = None, 450 ) -> None: 451 """Add and/or remove tags on multiple documents atomically. 452 453 Args: 454 document_ids: List of document IDs to modify. 455 add_tags: Tags to add, as IDs or names. 456 remove_tags: Tags to remove, as IDs or names. 457 """ 458 self._run( 459 self._async_documents.bulk_modify_tags( 460 document_ids, add_tags=add_tags, remove_tags=remove_tags 461 ) 462 ) 463 464 def bulk_delete(self, document_ids: List[int]) -> None: 465 """Permanently delete multiple documents in a single request. 466 467 Args: 468 document_ids: List of document IDs to delete. 469 """ 470 self._run(self._async_documents.bulk_delete(document_ids)) 471 472 def bulk_set_correspondent( 473 self, document_ids: List[int], correspondent: int | str | None 474 ) -> None: 475 """Assign a correspondent to multiple documents in a single request. 476 477 Args: 478 document_ids: List of document IDs to modify. 479 correspondent: Correspondent to assign, as an ID or name. 480 Pass ``None`` to clear. 481 """ 482 self._run(self._async_documents.bulk_set_correspondent(document_ids, correspondent)) 483 484 def bulk_set_document_type( 485 self, document_ids: List[int], document_type: int | str | None 486 ) -> None: 487 """Assign a document type to multiple documents in a single request. 488 489 Args: 490 document_ids: List of document IDs to modify. 491 document_type: Document type to assign, as an ID or name. 492 Pass ``None`` to clear. 493 """ 494 self._run(self._async_documents.bulk_set_document_type(document_ids, document_type)) 495 496 def bulk_set_storage_path( 497 self, document_ids: List[int], storage_path: int | str | None 498 ) -> None: 499 """Assign a storage path to multiple documents in a single request. 500 501 Args: 502 document_ids: List of document IDs to modify. 503 storage_path: Storage path to assign, as an ID or name. 504 Pass ``None`` to clear. 505 """ 506 self._run(self._async_documents.bulk_set_storage_path(document_ids, storage_path)) 507 508 def bulk_modify_custom_fields( 509 self, 510 document_ids: List[int], 511 *, 512 add_fields: List[dict[str, Any]] | None = None, 513 remove_fields: List[int] | None = None, 514 ) -> None: 515 """Add and/or remove custom field values on multiple documents. 516 517 Args: 518 document_ids: List of document IDs to modify. 519 add_fields: Custom-field value dicts to add. 520 remove_fields: Custom-field IDs whose values should be removed. 521 """ 522 self._run( 523 self._async_documents.bulk_modify_custom_fields( 524 document_ids, add_fields=add_fields, remove_fields=remove_fields 525 ) 526 ) 527 528 def bulk_set_permissions( 529 self, 530 document_ids: List[int], 531 *, 532 set_permissions: SetPermissions | None = None, 533 owner: int | None = None, 534 merge: bool = False, 535 ) -> None: 536 """Set permissions and/or owner on multiple documents. 537 538 Args: 539 document_ids: List of document IDs to modify. 540 set_permissions: Explicit view/change permission sets. 541 owner: Numeric user ID to assign as document owner. 542 merge: When ``True``, new permissions are merged with existing ones. 543 """ 544 self._run( 545 self._async_documents.bulk_set_permissions( 546 document_ids, 547 set_permissions=set_permissions, 548 owner=owner, 549 merge=merge, 550 ) 551 )
Sync accessor for documents: client.documents.
80 def get(self, id: int, *, include_metadata: bool = False) -> Document: 81 """Fetch a single document by its ID. 82 83 Args: 84 id: Numeric paperless-ngx document ID. 85 include_metadata: When ``True``, the extended file-level metadata 86 is fetched concurrently and attached to the document. 87 Default: ``False``. 88 89 Returns: 90 The :class:`~easypaperless.models.documents.Document` with the 91 given ID. 92 93 Raises: 94 ~easypaperless.exceptions.NotFoundError: If no document exists 95 with that ID. 96 """ 97 return cast( 98 Document, self._run(self._async_documents.get(id, include_metadata=include_metadata)) 99 )
Fetch a single document by its ID.
Arguments:
- id: Numeric paperless-ngx document ID.
- include_metadata: When
True, the extended file-level metadata is fetched concurrently and attached to the document. Default:False.
Returns:
The
~easypaperless.models.documents.Documentwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
101 def get_metadata(self, id: int) -> DocumentMetadata: 102 """Fetch the extended file-level metadata for a document. 103 104 Args: 105 id: Numeric paperless-ngx document ID. 106 107 Returns: 108 A :class:`~easypaperless.models.documents.DocumentMetadata` instance. 109 110 Raises: 111 ~easypaperless.exceptions.NotFoundError: If no document exists 112 with that ID. 113 """ 114 return cast(DocumentMetadata, self._run(self._async_documents.get_metadata(id)))
Fetch the extended file-level metadata for a document.
Arguments:
- id: Numeric paperless-ngx document ID.
Returns:
A
~easypaperless.models.documents.DocumentMetadatainstance.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
116 def list( 117 self, 118 *, 119 search: str | None = None, 120 search_mode: str = "title_or_content", 121 ids: List[int] | None = None, 122 tags: List[int | str] | None = None, 123 any_tags: List[int | str] | None = None, 124 exclude_tags: List[int | str] | None = None, 125 correspondent: int | str | None | _Unset = UNSET, 126 any_correspondent: List[int | str] | None = None, 127 exclude_correspondents: List[int | str] | None = None, 128 document_type: int | str | None | _Unset = UNSET, 129 document_type_name_contains: str | None = None, 130 document_type_name_exact: str | None = None, 131 any_document_type: List[int | str] | None = None, 132 exclude_document_types: List[int | str] | None = None, 133 storage_path: int | str | None | _Unset = UNSET, 134 any_storage_paths: List[int | str] | None = None, 135 exclude_storage_paths: List[int | str] | None = None, 136 owner: int | None | _Unset = UNSET, 137 exclude_owners: List[int] | None = None, 138 custom_fields: List[int | str] | None = None, 139 any_custom_fields: List[int | str] | None = None, 140 exclude_custom_fields: List[int | str] | None = None, 141 custom_field_query: List[Any] | None = None, 142 archive_serial_number: int | None | _Unset = UNSET, 143 archive_serial_number_from: int | None = None, 144 archive_serial_number_till: int | None = None, 145 created_after: date | str | None = None, 146 created_before: date | str | None = None, 147 added_after: date | datetime | str | None = None, 148 added_from: date | datetime | str | None = None, 149 added_before: date | datetime | str | None = None, 150 added_until: date | datetime | str | None = None, 151 modified_after: date | datetime | str | None = None, 152 modified_from: date | datetime | str | None = None, 153 modified_before: date | datetime | str | None = None, 154 modified_until: date | datetime | str | None = None, 155 checksum: str | None = None, 156 page_size: int = 25, 157 page: int | None = None, 158 ordering: str | None = None, 159 descending: bool = False, 160 max_results: int | None = None, 161 on_page: Callable[[int, int | None], None] | None = None, 162 ) -> List[Document]: 163 """Return a filtered list of documents. 164 165 All tag, correspondent, document-type, storage-path, and custom-field 166 parameters accept either integer IDs or string names. 167 168 Args: 169 search: Search string. Behaviour depends on ``search_mode``. 170 search_mode: How ``search`` is applied. One of: 171 ``"title_or_content"`` *(default)*, ``"title"``, ``"query"``, 172 ``"original_filename"``. 173 ids: Return only documents whose ID is in this list. 174 tags: Documents must have **all** of these tags (AND semantics). 175 any_tags: Documents must have **at least one** of these tags. 176 exclude_tags: Documents must have **none** of these tags. 177 correspondent: Filter to documents assigned to this correspondent. 178 Pass ``None`` to return only documents with no correspondent set. 179 any_correspondent: Filter to documents assigned to any of these. 180 exclude_correspondents: Exclude documents assigned to any of these. 181 document_type: Filter to documents of exactly this type. 182 Pass ``None`` to return only documents with no document type set. 183 document_type_name_contains: Case-insensitive substring filter on document type name. 184 document_type_name_exact: Case-insensitive exact match on document type name. 185 any_document_type: Filter to documents whose type is any of these. 186 exclude_document_types: Exclude documents whose type is any of these. 187 storage_path: Filter to documents assigned to this storage path. 188 Pass ``None`` to return only documents with no storage path set. 189 any_storage_paths: Filter to documents assigned to any of these paths. 190 exclude_storage_paths: Exclude documents assigned to any of these paths. 191 owner: Filter to documents owned by this user ID. 192 Pass ``None`` to return only documents with no owner set. 193 exclude_owners: Exclude documents owned by any of these user IDs. 194 custom_fields: Documents must have **all** of these custom fields set. 195 any_custom_fields: Documents must have **at least one** of these fields. 196 exclude_custom_fields: Documents must have **none** of these fields. 197 custom_field_query: Filter documents by custom field values. 198 archive_serial_number: Filter by exact archive serial number. 199 Pass ``None`` to return only documents with no ASN set. 200 archive_serial_number_from: Filter by ASN >= this value. 201 archive_serial_number_till: Filter by ASN <= this value. 202 created_after: Only documents created after this date. 203 created_before: Only documents created before this date. 204 added_after: Only documents added after this date/time. 205 added_from: Only documents added on or after this date/time. 206 added_before: Only documents added before this date/time. 207 added_until: Only documents added on or before this date/time. 208 modified_after: Only documents modified after this date/time. 209 modified_from: Only documents modified on or after this date/time. 210 modified_before: Only documents modified before this date/time. 211 modified_until: Only documents modified on or before this date/time. 212 checksum: MD5 checksum of the original file (exact match). 213 page_size: Number of results per API page. Default: ``25``. 214 page: Return only this specific page (1-based). 215 ordering: Field name to sort by. 216 descending: When ``True``, reverses the sort direction. 217 max_results: Stop after collecting this many documents. 218 on_page: Callback invoked after each page fetch. 219 220 Returns: 221 List of :class:`~easypaperless.models.documents.Document` objects. 222 """ 223 return cast( 224 List[Document], 225 self._run( 226 self._async_documents.list( 227 search=search, 228 search_mode=search_mode, 229 ids=ids, 230 tags=tags, 231 any_tags=any_tags, 232 exclude_tags=exclude_tags, 233 correspondent=correspondent, 234 any_correspondent=any_correspondent, 235 exclude_correspondents=exclude_correspondents, 236 document_type=document_type, 237 document_type_name_contains=document_type_name_contains, 238 document_type_name_exact=document_type_name_exact, 239 any_document_type=any_document_type, 240 exclude_document_types=exclude_document_types, 241 storage_path=storage_path, 242 any_storage_paths=any_storage_paths, 243 exclude_storage_paths=exclude_storage_paths, 244 owner=owner, 245 exclude_owners=exclude_owners, 246 custom_fields=custom_fields, 247 any_custom_fields=any_custom_fields, 248 exclude_custom_fields=exclude_custom_fields, 249 custom_field_query=custom_field_query, 250 archive_serial_number=archive_serial_number, 251 archive_serial_number_from=archive_serial_number_from, 252 archive_serial_number_till=archive_serial_number_till, 253 created_after=created_after, 254 created_before=created_before, 255 added_after=added_after, 256 added_from=added_from, 257 added_before=added_before, 258 added_until=added_until, 259 modified_after=modified_after, 260 modified_from=modified_from, 261 modified_before=modified_before, 262 modified_until=modified_until, 263 checksum=checksum, 264 page_size=page_size, 265 page=page, 266 ordering=ordering, 267 descending=descending, 268 max_results=max_results, 269 on_page=on_page, 270 ) 271 ), 272 )
Return a filtered list of documents.
All tag, correspondent, document-type, storage-path, and custom-field parameters accept either integer IDs or string names.
Arguments:
- search: Search string. Behaviour depends on
search_mode. - search_mode: How
searchis applied. One of:"title_or_content"(default),"title","query","original_filename". - ids: Return only documents whose ID is in this list.
- tags: Documents must have all of these tags (AND semantics).
- any_tags: Documents must have at least one of these tags.
- exclude_tags: Documents must have none of these tags.
- correspondent: Filter to documents assigned to this correspondent.
Pass
Noneto return only documents with no correspondent set. - any_correspondent: Filter to documents assigned to any of these.
- exclude_correspondents: Exclude documents assigned to any of these.
- document_type: Filter to documents of exactly this type.
Pass
Noneto return only documents with no document type set. - document_type_name_contains: Case-insensitive substring filter on document type name.
- document_type_name_exact: Case-insensitive exact match on document type name.
- any_document_type: Filter to documents whose type is any of these.
- exclude_document_types: Exclude documents whose type is any of these.
- storage_path: Filter to documents assigned to this storage path.
Pass
Noneto return only documents with no storage path set. - any_storage_paths: Filter to documents assigned to any of these paths.
- exclude_storage_paths: Exclude documents assigned to any of these paths.
- owner: Filter to documents owned by this user ID.
Pass
Noneto return only documents with no owner set. - exclude_owners: Exclude documents owned by any of these user IDs.
- custom_fields: Documents must have all of these custom fields set.
- any_custom_fields: Documents must have at least one of these fields.
- exclude_custom_fields: Documents must have none of these fields.
- custom_field_query: Filter documents by custom field values.
- archive_serial_number: Filter by exact archive serial number.
Pass
Noneto return only documents with no ASN set. - archive_serial_number_from: Filter by ASN >= this value.
- archive_serial_number_till: Filter by ASN <= this value.
- created_after: Only documents created after this date.
- created_before: Only documents created before this date.
- added_after: Only documents added after this date/time.
- added_from: Only documents added on or after this date/time.
- added_before: Only documents added before this date/time.
- added_until: Only documents added on or before this date/time.
- modified_after: Only documents modified after this date/time.
- modified_from: Only documents modified on or after this date/time.
- modified_before: Only documents modified before this date/time.
- modified_until: Only documents modified on or before this date/time.
- checksum: MD5 checksum of the original file (exact match).
- page_size: Number of results per API page. Default:
25. - page: Return only this specific page (1-based).
- ordering: Field name to sort by.
- descending: When
True, reverses the sort direction. - max_results: Stop after collecting this many documents.
- on_page: Callback invoked after each page fetch.
Returns:
List of
~easypaperless.models.documents.Documentobjects.
274 def update( 275 self, 276 id: int, 277 *, 278 title: str | None | _Unset = UNSET, 279 content: str | None | _Unset = UNSET, 280 created: date | str | None | _Unset = UNSET, 281 correspondent: int | str | None | _Unset = UNSET, 282 document_type: int | str | None | _Unset = UNSET, 283 storage_path: int | str | None | _Unset = UNSET, 284 tags: List[int | str] | None | _Unset = UNSET, 285 archive_serial_number: int | None | _Unset = UNSET, 286 custom_fields: List[dict[str, Any]] | None | _Unset = UNSET, 287 owner: int | None | _Unset = UNSET, 288 set_permissions: SetPermissions | None | _Unset = UNSET, 289 remove_inbox_tags: bool | None | _Unset = UNSET, 290 ) -> Document: 291 """Partially update a document (PATCH semantics). 292 293 Args: 294 id: Numeric ID of the document to update. 295 title: New document title. 296 content: OCR text content of the document. 297 created: Creation date as an ISO-8601 string (``"YYYY-MM-DD"``) or a 298 :class:`~datetime.date` object. 299 correspondent: Correspondent to assign, as an ID or name. 300 Pass ``None`` to clear the correspondent. 301 document_type: Document type to assign, as an ID or name. 302 Pass ``None`` to clear the document type. 303 storage_path: Storage path to assign, as an ID or name. 304 Pass ``None`` to clear the storage path. 305 tags: Full replacement list of tags (IDs or names). 306 archive_serial_number: Archive serial number to assign. 307 Pass ``None`` to clear the archive serial number. 308 custom_fields: List of ``{"field": <field_id>, "value": ...}`` dicts. 309 owner: Numeric user ID to assign as document owner. 310 Pass ``None`` to clear the owner. 311 set_permissions: Explicit view/change permission sets. 312 remove_inbox_tags: When ``True``, removes all inbox tags from the document. 313 314 Returns: 315 The updated :class:`~easypaperless.models.documents.Document`. 316 """ 317 return cast( 318 Document, 319 self._run( 320 self._async_documents.update( 321 id, 322 title=title, 323 content=content, 324 created=created, 325 correspondent=correspondent, 326 document_type=document_type, 327 storage_path=storage_path, 328 tags=tags, 329 archive_serial_number=archive_serial_number, 330 custom_fields=custom_fields, 331 owner=owner, 332 set_permissions=set_permissions, 333 remove_inbox_tags=remove_inbox_tags, 334 ) 335 ), 336 )
Partially update a document (PATCH semantics).
Arguments:
- id: Numeric ID of the document to update.
- title: New document title.
- content: OCR text content of the document.
- created: Creation date as an ISO-8601 string (
"YYYY-MM-DD") or a~datetime.dateobject. - correspondent: Correspondent to assign, as an ID or name.
Pass
Noneto clear the correspondent. - document_type: Document type to assign, as an ID or name.
Pass
Noneto clear the document type. - storage_path: Storage path to assign, as an ID or name.
Pass
Noneto clear the storage path. - tags: Full replacement list of tags (IDs or names).
- archive_serial_number: Archive serial number to assign.
Pass
Noneto clear the archive serial number. - custom_fields: List of
{"field": <field_id>, "value": ...}dicts. - owner: Numeric user ID to assign as document owner.
Pass
Noneto clear the owner. - set_permissions: Explicit view/change permission sets.
- remove_inbox_tags: When
True, removes all inbox tags from the document.
Returns:
The updated
~easypaperless.models.documents.Document.
338 def delete(self, id: int) -> None: 339 """Permanently delete a document. 340 341 Args: 342 id: Numeric ID of the document to delete. 343 344 Raises: 345 ~easypaperless.exceptions.NotFoundError: If no document exists 346 with that ID. 347 """ 348 self._run(self._async_documents.delete(id))
Permanently delete a document.
Arguments:
- id: Numeric ID of the document to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
350 def download(self, id: int, *, original: bool = False) -> bytes: 351 """Download the binary content of a document. 352 353 Args: 354 id: Numeric ID of the document to download. 355 original: If ``False`` *(default)*, returns the archived PDF. 356 If ``True``, returns the original uploaded file. 357 358 Returns: 359 Raw file bytes. 360 """ 361 return cast(bytes, self._run(self._async_documents.download(id, original=original)))
Download the binary content of a document.
Arguments:
- id: Numeric ID of the document to download.
- original: If
False(default), returns the archived PDF. IfTrue, returns the original uploaded file.
Returns:
Raw file bytes.
363 def upload( 364 self, 365 file: str | Path, 366 *, 367 title: str | None = None, 368 created: date | str | None = None, 369 correspondent: int | str | None | _Unset = UNSET, 370 document_type: int | str | None | _Unset = UNSET, 371 storage_path: int | str | None | _Unset = UNSET, 372 tags: List[int | str] | None = None, 373 archive_serial_number: int | None | _Unset = UNSET, 374 custom_fields: List[dict[str, Any]] | None = None, 375 wait: bool = False, 376 poll_interval: float | None = None, 377 poll_timeout: float | None = None, 378 ) -> str | Document: 379 """Upload a document to paperless-ngx. 380 381 Args: 382 file: Path to the file to upload. 383 title: Title to assign to the document. 384 created: Creation date as an ISO-8601 string (``"YYYY-MM-DD"``) or a 385 :class:`~datetime.date` object. 386 correspondent: Correspondent to assign, as an ID or name. 387 document_type: Document type to assign, as an ID or name. 388 storage_path: Storage path to assign, as an ID or name. 389 tags: Tags to assign, as IDs or names. 390 archive_serial_number: Archive serial number to assign. 391 custom_fields: List of ``{"field": <field_id>, "value": ...}`` dicts. 392 wait: If ``False`` *(default)*, returns immediately with the task ID. 393 If ``True``, polls until processing completes. 394 poll_interval: Override the client-level ``poll_interval`` (in seconds). 395 poll_timeout: Override the client-level ``poll_timeout`` (in seconds). 396 397 Returns: 398 The Celery task ID string when ``wait=False``, or the fully 399 processed :class:`~easypaperless.models.documents.Document` 400 when ``wait=True``. 401 402 Raises: 403 ~easypaperless.exceptions.UploadError: If processing fails. 404 ~easypaperless.exceptions.TaskTimeoutError: If timeout is exceeded. 405 """ 406 return cast( 407 str | Document, 408 self._run( 409 self._async_documents.upload( 410 file, 411 title=title, 412 created=created, 413 correspondent=correspondent, 414 document_type=document_type, 415 storage_path=storage_path, 416 tags=tags, 417 archive_serial_number=archive_serial_number, 418 custom_fields=custom_fields, 419 wait=wait, 420 poll_interval=poll_interval, 421 poll_timeout=poll_timeout, 422 ) 423 ), 424 )
Upload a document to paperless-ngx.
Arguments:
- file: Path to the file to upload.
- title: Title to assign to the document.
- created: Creation date as an ISO-8601 string (
"YYYY-MM-DD") or a~datetime.dateobject. - correspondent: Correspondent to assign, as an ID or name.
- document_type: Document type to assign, as an ID or name.
- storage_path: Storage path to assign, as an ID or name.
- tags: Tags to assign, as IDs or names.
- archive_serial_number: Archive serial number to assign.
- custom_fields: List of
{"field": <field_id>, "value": ...}dicts. - wait: If
False(default), returns immediately with the task ID. IfTrue, polls until processing completes. - poll_interval: Override the client-level
poll_interval(in seconds). - poll_timeout: Override the client-level
poll_timeout(in seconds).
Returns:
The Celery task ID string when
wait=False, or the fully processed~easypaperless.models.documents.Documentwhenwait=True.
Raises:
- ~easypaperless.exceptions.UploadError: If processing fails.
- ~easypaperless.exceptions.TaskTimeoutError: If timeout is exceeded.
426 def bulk_add_tag(self, document_ids: List[int], tag: int | str) -> None: 427 """Add a tag to multiple documents in a single request. 428 429 Args: 430 document_ids: List of document IDs to tag. 431 tag: Tag to add, as an ID or name. 432 """ 433 self._run(self._async_documents.bulk_add_tag(document_ids, tag))
Add a tag to multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to tag.
- tag: Tag to add, as an ID or name.
435 def bulk_remove_tag(self, document_ids: List[int], tag: int | str) -> None: 436 """Remove a tag from multiple documents in a single request. 437 438 Args: 439 document_ids: List of document IDs to un-tag. 440 tag: Tag to remove, as an ID or name. 441 """ 442 self._run(self._async_documents.bulk_remove_tag(document_ids, tag))
Remove a tag from multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to un-tag.
- tag: Tag to remove, as an ID or name.
464 def bulk_delete(self, document_ids: List[int]) -> None: 465 """Permanently delete multiple documents in a single request. 466 467 Args: 468 document_ids: List of document IDs to delete. 469 """ 470 self._run(self._async_documents.bulk_delete(document_ids))
Permanently delete multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to delete.
472 def bulk_set_correspondent( 473 self, document_ids: List[int], correspondent: int | str | None 474 ) -> None: 475 """Assign a correspondent to multiple documents in a single request. 476 477 Args: 478 document_ids: List of document IDs to modify. 479 correspondent: Correspondent to assign, as an ID or name. 480 Pass ``None`` to clear. 481 """ 482 self._run(self._async_documents.bulk_set_correspondent(document_ids, correspondent))
Assign a correspondent to multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to modify.
- correspondent: Correspondent to assign, as an ID or name.
Pass
Noneto clear.
484 def bulk_set_document_type( 485 self, document_ids: List[int], document_type: int | str | None 486 ) -> None: 487 """Assign a document type to multiple documents in a single request. 488 489 Args: 490 document_ids: List of document IDs to modify. 491 document_type: Document type to assign, as an ID or name. 492 Pass ``None`` to clear. 493 """ 494 self._run(self._async_documents.bulk_set_document_type(document_ids, document_type))
Assign a document type to multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to modify.
- document_type: Document type to assign, as an ID or name.
Pass
Noneto clear.
496 def bulk_set_storage_path( 497 self, document_ids: List[int], storage_path: int | str | None 498 ) -> None: 499 """Assign a storage path to multiple documents in a single request. 500 501 Args: 502 document_ids: List of document IDs to modify. 503 storage_path: Storage path to assign, as an ID or name. 504 Pass ``None`` to clear. 505 """ 506 self._run(self._async_documents.bulk_set_storage_path(document_ids, storage_path))
Assign a storage path to multiple documents in a single request.
Arguments:
- document_ids: List of document IDs to modify.
- storage_path: Storage path to assign, as an ID or name.
Pass
Noneto clear.
508 def bulk_modify_custom_fields( 509 self, 510 document_ids: List[int], 511 *, 512 add_fields: List[dict[str, Any]] | None = None, 513 remove_fields: List[int] | None = None, 514 ) -> None: 515 """Add and/or remove custom field values on multiple documents. 516 517 Args: 518 document_ids: List of document IDs to modify. 519 add_fields: Custom-field value dicts to add. 520 remove_fields: Custom-field IDs whose values should be removed. 521 """ 522 self._run( 523 self._async_documents.bulk_modify_custom_fields( 524 document_ids, add_fields=add_fields, remove_fields=remove_fields 525 ) 526 )
Add and/or remove custom field values on multiple documents.
Arguments:
- document_ids: List of document IDs to modify.
- add_fields: Custom-field value dicts to add.
- remove_fields: Custom-field IDs whose values should be removed.
528 def bulk_set_permissions( 529 self, 530 document_ids: List[int], 531 *, 532 set_permissions: SetPermissions | None = None, 533 owner: int | None = None, 534 merge: bool = False, 535 ) -> None: 536 """Set permissions and/or owner on multiple documents. 537 538 Args: 539 document_ids: List of document IDs to modify. 540 set_permissions: Explicit view/change permission sets. 541 owner: Numeric user ID to assign as document owner. 542 merge: When ``True``, new permissions are merged with existing ones. 543 """ 544 self._run( 545 self._async_documents.bulk_set_permissions( 546 document_ids, 547 set_permissions=set_permissions, 548 owner=owner, 549 merge=merge, 550 ) 551 )
Set permissions and/or owner on multiple documents.
Arguments:
- document_ids: List of document IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as document owner.
- merge: When
True, new permissions are merged with existing ones.
19class SyncNotesResource: 20 """Sync accessor for document notes: ``client.documents.notes``.""" 21 22 def __init__(self, async_notes: NotesResource, run: Any) -> None: 23 self._async_notes = async_notes 24 self._run = run 25 26 def list(self, document_id: int) -> List[DocumentNote]: 27 """Fetch all notes attached to a document. 28 29 Args: 30 document_id: Numeric ID of the document whose notes to retrieve. 31 32 Returns: 33 List of :class:`~easypaperless.models.documents.DocumentNote` objects, 34 ordered by creation time. 35 36 Raises: 37 ~easypaperless.exceptions.NotFoundError: If no document exists 38 with that ID. 39 """ 40 return cast(List[DocumentNote], self._run(self._async_notes.list(document_id))) 41 42 def create(self, document_id: int, *, note: str) -> DocumentNote: 43 """Create a new note on a document. 44 45 Args: 46 document_id: Numeric ID of the document to annotate. 47 note: Text content of the note. 48 49 Returns: 50 The newly created :class:`~easypaperless.models.documents.DocumentNote`. 51 52 Raises: 53 ~easypaperless.exceptions.NotFoundError: If no document exists 54 with that ID. 55 """ 56 return cast(DocumentNote, self._run(self._async_notes.create(document_id, note=note))) 57 58 def delete(self, document_id: int, note_id: int) -> None: 59 """Delete a note from a document. 60 61 Args: 62 document_id: Numeric ID of the document that owns the note. 63 note_id: Numeric ID of the note to delete. 64 65 Raises: 66 ~easypaperless.exceptions.NotFoundError: If no document or note 67 exists with the given IDs. 68 """ 69 self._run(self._async_notes.delete(document_id, note_id))
Sync accessor for document notes: client.documents.notes.
26 def list(self, document_id: int) -> List[DocumentNote]: 27 """Fetch all notes attached to a document. 28 29 Args: 30 document_id: Numeric ID of the document whose notes to retrieve. 31 32 Returns: 33 List of :class:`~easypaperless.models.documents.DocumentNote` objects, 34 ordered by creation time. 35 36 Raises: 37 ~easypaperless.exceptions.NotFoundError: If no document exists 38 with that ID. 39 """ 40 return cast(List[DocumentNote], self._run(self._async_notes.list(document_id)))
Fetch all notes attached to a document.
Arguments:
- document_id: Numeric ID of the document whose notes to retrieve.
Returns:
List of
~easypaperless.models.documents.DocumentNoteobjects, ordered by creation time.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
42 def create(self, document_id: int, *, note: str) -> DocumentNote: 43 """Create a new note on a document. 44 45 Args: 46 document_id: Numeric ID of the document to annotate. 47 note: Text content of the note. 48 49 Returns: 50 The newly created :class:`~easypaperless.models.documents.DocumentNote`. 51 52 Raises: 53 ~easypaperless.exceptions.NotFoundError: If no document exists 54 with that ID. 55 """ 56 return cast(DocumentNote, self._run(self._async_notes.create(document_id, note=note)))
Create a new note on a document.
Arguments:
- document_id: Numeric ID of the document to annotate.
- note: Text content of the note.
Returns:
The newly created
~easypaperless.models.documents.DocumentNote.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document exists with that ID.
58 def delete(self, document_id: int, note_id: int) -> None: 59 """Delete a note from a document. 60 61 Args: 62 document_id: Numeric ID of the document that owns the note. 63 note_id: Numeric ID of the note to delete. 64 65 Raises: 66 ~easypaperless.exceptions.NotFoundError: If no document or note 67 exists with the given IDs. 68 """ 69 self._run(self._async_notes.delete(document_id, note_id))
Delete a note from a document.
Arguments:
- document_id: Numeric ID of the document that owns the note.
- note_id: Numeric ID of the note to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no document or note exists with the given IDs.
17class SyncStoragePathsResource: 18 """Sync accessor for storage paths: ``client.storage_paths``.""" 19 20 def __init__(self, async_storage_paths: StoragePathsResource, run: Any) -> None: 21 self._async_storage_paths = async_storage_paths 22 self._run = run 23 24 def list( 25 self, 26 *, 27 ids: List[int] | None = None, 28 name_contains: str | None = None, 29 name_exact: str | None = None, 30 path_contains: str | None = None, 31 path_exact: str | None = None, 32 page: int | None = None, 33 page_size: int | None = None, 34 ordering: str | None = None, 35 descending: bool = False, 36 ) -> List[StoragePath]: 37 """Return storage paths defined in paperless-ngx. 38 39 Args: 40 ids: Return only storage paths whose ID is in this list. 41 name_contains: Case-insensitive substring filter on name. 42 name_exact: Case-insensitive exact match on name. 43 path_contains: Case-insensitive substring filter on path template. 44 path_exact: Case-insensitive exact match on path template. 45 page: Return only this specific page (1-based). 46 page_size: Number of results per page. 47 ordering: Field to sort by. 48 descending: When ``True``, reverses the sort direction. 49 50 Returns: 51 List of :class:`~easypaperless.models.storage_paths.StoragePath` objects. 52 """ 53 return cast( 54 List[StoragePath], 55 self._run( 56 self._async_storage_paths.list( 57 ids=ids, 58 name_contains=name_contains, 59 name_exact=name_exact, 60 path_contains=path_contains, 61 path_exact=path_exact, 62 page=page, 63 page_size=page_size, 64 ordering=ordering, 65 descending=descending, 66 ) 67 ), 68 ) 69 70 def get(self, id: int) -> StoragePath: 71 """Fetch a single storage path by its ID. 72 73 Args: 74 id: Numeric storage-path ID. 75 76 Returns: 77 The :class:`~easypaperless.models.storage_paths.StoragePath` with the given ID. 78 79 Raises: 80 ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID. 81 """ 82 return cast(StoragePath, self._run(self._async_storage_paths.get(id))) 83 84 def create( 85 self, 86 *, 87 name: str, 88 path: str | None = None, 89 match: str | None | _Unset = UNSET, 90 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 91 is_insensitive: bool = True, 92 owner: int | None | _Unset = UNSET, 93 set_permissions: SetPermissions | None = None, 94 ) -> StoragePath: 95 """Create a new storage path. 96 97 Args: 98 name: Storage-path name. Must be unique. 99 path: Template string for the archive file path. 100 match: Auto-matching pattern. 101 matching_algorithm: Controls how ``match`` is applied. 102 is_insensitive: When ``True``, ``match`` is case-insensitive. 103 Defaults to ``True``, matching the paperless-ngx API default. 104 owner: Numeric user ID to assign as owner. 105 set_permissions: Explicit view/change permission sets. 106 107 Returns: 108 The newly created :class:`~easypaperless.models.storage_paths.StoragePath`. 109 """ 110 return cast( 111 StoragePath, 112 self._run( 113 self._async_storage_paths.create( 114 name=name, 115 path=path, 116 match=match, 117 matching_algorithm=matching_algorithm, 118 is_insensitive=is_insensitive, 119 owner=owner, 120 set_permissions=set_permissions, 121 ) 122 ), 123 ) 124 125 def update( 126 self, 127 id: int, 128 *, 129 name: str | None | _Unset = UNSET, 130 path: str | None | _Unset = UNSET, 131 match: str | None | _Unset = UNSET, 132 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 133 is_insensitive: bool | None | _Unset = UNSET, 134 owner: int | None | _Unset = UNSET, 135 set_permissions: SetPermissions | None | _Unset = UNSET, 136 ) -> StoragePath: 137 """Partially update a storage path (PATCH semantics). 138 139 Args: 140 id: Numeric ID of the storage path to update. 141 name: Storage-path name. 142 path: Template string for the archive file path. 143 match: Auto-matching pattern. 144 matching_algorithm: Controls how ``match`` is applied. 145 is_insensitive: When ``True``, ``match`` is case-insensitive. 146 owner: Numeric user ID to assign as owner. 147 Pass ``None`` to clear the owner. 148 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 149 set_permissions: Explicit view/change permission sets. 150 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 151 152 Returns: 153 The updated :class:`~easypaperless.models.storage_paths.StoragePath`. 154 """ 155 return cast( 156 StoragePath, 157 self._run( 158 self._async_storage_paths.update( 159 id, 160 name=name, 161 path=path, 162 match=match, 163 matching_algorithm=matching_algorithm, 164 is_insensitive=is_insensitive, 165 owner=owner, 166 set_permissions=set_permissions, 167 ) 168 ), 169 ) 170 171 def delete(self, id: int) -> None: 172 """Delete a storage path. 173 174 Args: 175 id: Numeric ID of the storage path to delete. 176 177 Raises: 178 ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID. 179 """ 180 self._run(self._async_storage_paths.delete(id)) 181 182 def bulk_delete(self, ids: List[int]) -> None: 183 """Permanently delete multiple storage paths in a single request. 184 185 Args: 186 ids: List of storage path IDs to delete. 187 """ 188 self._run(self._async_storage_paths.bulk_delete(ids)) 189 190 def bulk_set_permissions( 191 self, 192 ids: List[int], 193 *, 194 set_permissions: SetPermissions | None = None, 195 owner: int | None = None, 196 merge: bool = False, 197 ) -> None: 198 """Set permissions and/or owner on multiple storage paths. 199 200 Args: 201 ids: List of storage path IDs to modify. 202 set_permissions: Explicit view/change permission sets. 203 owner: Numeric user ID to assign as owner. 204 merge: When ``True``, new permissions are merged with existing ones. 205 """ 206 self._run( 207 self._async_storage_paths.bulk_set_permissions( 208 ids, set_permissions=set_permissions, owner=owner, merge=merge 209 ) 210 )
Sync accessor for storage paths: client.storage_paths.
24 def list( 25 self, 26 *, 27 ids: List[int] | None = None, 28 name_contains: str | None = None, 29 name_exact: str | None = None, 30 path_contains: str | None = None, 31 path_exact: str | None = None, 32 page: int | None = None, 33 page_size: int | None = None, 34 ordering: str | None = None, 35 descending: bool = False, 36 ) -> List[StoragePath]: 37 """Return storage paths defined in paperless-ngx. 38 39 Args: 40 ids: Return only storage paths whose ID is in this list. 41 name_contains: Case-insensitive substring filter on name. 42 name_exact: Case-insensitive exact match on name. 43 path_contains: Case-insensitive substring filter on path template. 44 path_exact: Case-insensitive exact match on path template. 45 page: Return only this specific page (1-based). 46 page_size: Number of results per page. 47 ordering: Field to sort by. 48 descending: When ``True``, reverses the sort direction. 49 50 Returns: 51 List of :class:`~easypaperless.models.storage_paths.StoragePath` objects. 52 """ 53 return cast( 54 List[StoragePath], 55 self._run( 56 self._async_storage_paths.list( 57 ids=ids, 58 name_contains=name_contains, 59 name_exact=name_exact, 60 path_contains=path_contains, 61 path_exact=path_exact, 62 page=page, 63 page_size=page_size, 64 ordering=ordering, 65 descending=descending, 66 ) 67 ), 68 )
Return storage paths defined in paperless-ngx.
Arguments:
- ids: Return only storage paths whose ID is in this list.
- name_contains: Case-insensitive substring filter on name.
- name_exact: Case-insensitive exact match on name.
- path_contains: Case-insensitive substring filter on path template.
- path_exact: Case-insensitive exact match on path template.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.storage_paths.StoragePathobjects.
70 def get(self, id: int) -> StoragePath: 71 """Fetch a single storage path by its ID. 72 73 Args: 74 id: Numeric storage-path ID. 75 76 Returns: 77 The :class:`~easypaperless.models.storage_paths.StoragePath` with the given ID. 78 79 Raises: 80 ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID. 81 """ 82 return cast(StoragePath, self._run(self._async_storage_paths.get(id)))
Fetch a single storage path by its ID.
Arguments:
- id: Numeric storage-path ID.
Returns:
The
~easypaperless.models.storage_paths.StoragePathwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID.
84 def create( 85 self, 86 *, 87 name: str, 88 path: str | None = None, 89 match: str | None | _Unset = UNSET, 90 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 91 is_insensitive: bool = True, 92 owner: int | None | _Unset = UNSET, 93 set_permissions: SetPermissions | None = None, 94 ) -> StoragePath: 95 """Create a new storage path. 96 97 Args: 98 name: Storage-path name. Must be unique. 99 path: Template string for the archive file path. 100 match: Auto-matching pattern. 101 matching_algorithm: Controls how ``match`` is applied. 102 is_insensitive: When ``True``, ``match`` is case-insensitive. 103 Defaults to ``True``, matching the paperless-ngx API default. 104 owner: Numeric user ID to assign as owner. 105 set_permissions: Explicit view/change permission sets. 106 107 Returns: 108 The newly created :class:`~easypaperless.models.storage_paths.StoragePath`. 109 """ 110 return cast( 111 StoragePath, 112 self._run( 113 self._async_storage_paths.create( 114 name=name, 115 path=path, 116 match=match, 117 matching_algorithm=matching_algorithm, 118 is_insensitive=is_insensitive, 119 owner=owner, 120 set_permissions=set_permissions, 121 ) 122 ), 123 )
Create a new storage path.
Arguments:
- name: Storage-path name. Must be unique.
- path: Template string for the archive file path.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. Defaults toTrue, matching the paperless-ngx API default. - owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.storage_paths.StoragePath.
125 def update( 126 self, 127 id: int, 128 *, 129 name: str | None | _Unset = UNSET, 130 path: str | None | _Unset = UNSET, 131 match: str | None | _Unset = UNSET, 132 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 133 is_insensitive: bool | None | _Unset = UNSET, 134 owner: int | None | _Unset = UNSET, 135 set_permissions: SetPermissions | None | _Unset = UNSET, 136 ) -> StoragePath: 137 """Partially update a storage path (PATCH semantics). 138 139 Args: 140 id: Numeric ID of the storage path to update. 141 name: Storage-path name. 142 path: Template string for the archive file path. 143 match: Auto-matching pattern. 144 matching_algorithm: Controls how ``match`` is applied. 145 is_insensitive: When ``True``, ``match`` is case-insensitive. 146 owner: Numeric user ID to assign as owner. 147 Pass ``None`` to clear the owner. 148 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 149 set_permissions: Explicit view/change permission sets. 150 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 151 152 Returns: 153 The updated :class:`~easypaperless.models.storage_paths.StoragePath`. 154 """ 155 return cast( 156 StoragePath, 157 self._run( 158 self._async_storage_paths.update( 159 id, 160 name=name, 161 path=path, 162 match=match, 163 matching_algorithm=matching_algorithm, 164 is_insensitive=is_insensitive, 165 owner=owner, 166 set_permissions=set_permissions, 167 ) 168 ), 169 )
Partially update a storage path (PATCH semantics).
Arguments:
- id: Numeric ID of the storage path to update.
- name: Storage-path name.
- path: Template string for the archive file path.
- match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. - owner: Numeric user ID to assign as owner.
Pass
Noneto clear the owner. Omit (or pass~easypaperless.UNSET) to leave unchanged. - set_permissions: Explicit view/change permission sets.
Omit (or pass
~easypaperless.UNSET) to leave unchanged.
Returns:
The updated
~easypaperless.models.storage_paths.StoragePath.
171 def delete(self, id: int) -> None: 172 """Delete a storage path. 173 174 Args: 175 id: Numeric ID of the storage path to delete. 176 177 Raises: 178 ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID. 179 """ 180 self._run(self._async_storage_paths.delete(id))
Delete a storage path.
Arguments:
- id: Numeric ID of the storage path to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no storage path exists with that ID.
182 def bulk_delete(self, ids: List[int]) -> None: 183 """Permanently delete multiple storage paths in a single request. 184 185 Args: 186 ids: List of storage path IDs to delete. 187 """ 188 self._run(self._async_storage_paths.bulk_delete(ids))
Permanently delete multiple storage paths in a single request.
Arguments:
- ids: List of storage path IDs to delete.
190 def bulk_set_permissions( 191 self, 192 ids: List[int], 193 *, 194 set_permissions: SetPermissions | None = None, 195 owner: int | None = None, 196 merge: bool = False, 197 ) -> None: 198 """Set permissions and/or owner on multiple storage paths. 199 200 Args: 201 ids: List of storage path IDs to modify. 202 set_permissions: Explicit view/change permission sets. 203 owner: Numeric user ID to assign as owner. 204 merge: When ``True``, new permissions are merged with existing ones. 205 """ 206 self._run( 207 self._async_storage_paths.bulk_set_permissions( 208 ids, set_permissions=set_permissions, owner=owner, merge=merge 209 ) 210 )
Set permissions and/or owner on multiple storage paths.
Arguments:
- ids: List of storage path IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as owner.
- merge: When
True, new permissions are merged with existing ones.
17class SyncTagsResource: 18 """Sync accessor for tags: ``client.tags``.""" 19 20 def __init__(self, async_tags: TagsResource, run: Any) -> None: 21 self._async_tags = async_tags 22 self._run = run 23 24 def list( 25 self, 26 *, 27 ids: List[int] | None = None, 28 name_contains: str | None = None, 29 name_exact: str | None = None, 30 page: int | None = None, 31 page_size: int | None = None, 32 ordering: str | None = None, 33 descending: bool = False, 34 ) -> List[Tag]: 35 """Return tags defined in paperless-ngx. 36 37 Args: 38 ids: Return only tags whose ID is in this list. 39 name_contains: Case-insensitive substring filter on tag name. 40 name_exact: Case-insensitive exact match on tag name. 41 page: Return only this specific page (1-based). 42 page_size: Number of results per page. 43 ordering: Field to sort by. 44 descending: When ``True``, reverses the sort direction. 45 46 Returns: 47 List of :class:`~easypaperless.models.tags.Tag` objects. 48 """ 49 return cast( 50 List[Tag], 51 self._run( 52 self._async_tags.list( 53 ids=ids, 54 name_contains=name_contains, 55 name_exact=name_exact, 56 page=page, 57 page_size=page_size, 58 ordering=ordering, 59 descending=descending, 60 ) 61 ), 62 ) 63 64 def get(self, id: int) -> Tag: 65 """Fetch a single tag by its ID. 66 67 Args: 68 id: Numeric tag ID. 69 70 Returns: 71 The :class:`~easypaperless.models.tags.Tag` with the given ID. 72 73 Raises: 74 ~easypaperless.exceptions.NotFoundError: If no tag exists with 75 that ID. 76 """ 77 return cast(Tag, self._run(self._async_tags.get(id))) 78 79 def create( 80 self, 81 *, 82 name: str, 83 color: str | None = None, 84 is_inbox_tag: bool | None = None, 85 match: str | None | _Unset = UNSET, 86 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 87 is_insensitive: bool = True, 88 parent: int | None | _Unset = UNSET, 89 owner: int | None | _Unset = UNSET, 90 set_permissions: SetPermissions | None = None, 91 ) -> Tag: 92 """Create a new tag. 93 94 Args: 95 name: Tag name. Must be unique. 96 color: Background colour as a CSS hex string. 97 is_inbox_tag: When ``True``, newly ingested documents get this tag. 98 match: Auto-matching pattern. 99 matching_algorithm: Controls how ``match`` is applied. 100 is_insensitive: When ``True``, ``match`` is case-insensitive. 101 Defaults to ``True``, matching the paperless-ngx API default. 102 parent: ID of parent tag for hierarchical trees. 103 owner: Numeric user ID to assign as owner. 104 set_permissions: Explicit view/change permission sets. 105 106 Returns: 107 The newly created :class:`~easypaperless.models.tags.Tag`. 108 """ 109 return cast( 110 Tag, 111 self._run( 112 self._async_tags.create( 113 name=name, 114 color=color, 115 is_inbox_tag=is_inbox_tag, 116 match=match, 117 matching_algorithm=matching_algorithm, 118 is_insensitive=is_insensitive, 119 parent=parent, 120 owner=owner, 121 set_permissions=set_permissions, 122 ) 123 ), 124 ) 125 126 def update( 127 self, 128 id: int, 129 *, 130 name: str | None | _Unset = UNSET, 131 color: str | None | _Unset = UNSET, 132 is_inbox_tag: bool | None | _Unset = UNSET, 133 match: str | None | _Unset = UNSET, 134 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 135 is_insensitive: bool | None | _Unset = UNSET, 136 parent: int | None | _Unset = UNSET, 137 owner: int | None | _Unset = UNSET, 138 set_permissions: SetPermissions | None | _Unset = UNSET, 139 ) -> Tag: 140 """Partially update a tag (PATCH semantics). 141 142 Args: 143 id: Numeric ID of the tag to update. 144 name: Tag name. 145 color: Background colour as a CSS hex string. 146 is_inbox_tag: When ``True``, newly ingested documents get this tag. 147 match: Auto-matching pattern. 148 matching_algorithm: Controls how ``match`` is applied. 149 is_insensitive: When ``True``, ``match`` is case-insensitive. 150 parent: ID of parent tag. 151 Pass ``None`` to clear (make root tag). 152 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 153 owner: Numeric user ID to assign as owner. 154 Pass ``None`` to clear the owner. 155 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 156 set_permissions: Explicit view/change permission sets. 157 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 158 159 Returns: 160 The updated :class:`~easypaperless.models.tags.Tag`. 161 """ 162 return cast( 163 Tag, 164 self._run( 165 self._async_tags.update( 166 id, 167 name=name, 168 color=color, 169 is_inbox_tag=is_inbox_tag, 170 match=match, 171 matching_algorithm=matching_algorithm, 172 is_insensitive=is_insensitive, 173 parent=parent, 174 owner=owner, 175 set_permissions=set_permissions, 176 ) 177 ), 178 ) 179 180 def delete(self, id: int) -> None: 181 """Delete a tag. 182 183 Args: 184 id: Numeric ID of the tag to delete. 185 186 Raises: 187 ~easypaperless.exceptions.NotFoundError: If no tag exists with 188 that ID. 189 """ 190 self._run(self._async_tags.delete(id)) 191 192 def bulk_delete(self, ids: List[int]) -> None: 193 """Permanently delete multiple tags in a single request. 194 195 Args: 196 ids: List of tag IDs to delete. 197 """ 198 self._run(self._async_tags.bulk_delete(ids)) 199 200 def bulk_set_permissions( 201 self, 202 ids: List[int], 203 *, 204 set_permissions: SetPermissions | None = None, 205 owner: int | None = None, 206 merge: bool = False, 207 ) -> None: 208 """Set permissions and/or owner on multiple tags. 209 210 Args: 211 ids: List of tag IDs to modify. 212 set_permissions: Explicit view/change permission sets. 213 owner: Numeric user ID to assign as owner. 214 merge: When ``True``, new permissions are merged with existing ones. 215 """ 216 self._run( 217 self._async_tags.bulk_set_permissions( 218 ids, set_permissions=set_permissions, owner=owner, merge=merge 219 ) 220 )
Sync accessor for tags: client.tags.
24 def list( 25 self, 26 *, 27 ids: List[int] | None = None, 28 name_contains: str | None = None, 29 name_exact: str | None = None, 30 page: int | None = None, 31 page_size: int | None = None, 32 ordering: str | None = None, 33 descending: bool = False, 34 ) -> List[Tag]: 35 """Return tags defined in paperless-ngx. 36 37 Args: 38 ids: Return only tags whose ID is in this list. 39 name_contains: Case-insensitive substring filter on tag name. 40 name_exact: Case-insensitive exact match on tag name. 41 page: Return only this specific page (1-based). 42 page_size: Number of results per page. 43 ordering: Field to sort by. 44 descending: When ``True``, reverses the sort direction. 45 46 Returns: 47 List of :class:`~easypaperless.models.tags.Tag` objects. 48 """ 49 return cast( 50 List[Tag], 51 self._run( 52 self._async_tags.list( 53 ids=ids, 54 name_contains=name_contains, 55 name_exact=name_exact, 56 page=page, 57 page_size=page_size, 58 ordering=ordering, 59 descending=descending, 60 ) 61 ), 62 )
Return tags defined in paperless-ngx.
Arguments:
- ids: Return only tags whose ID is in this list.
- name_contains: Case-insensitive substring filter on tag name.
- name_exact: Case-insensitive exact match on tag name.
- page: Return only this specific page (1-based).
- page_size: Number of results per page.
- ordering: Field to sort by.
- descending: When
True, reverses the sort direction.
Returns:
List of
~easypaperless.models.tags.Tagobjects.
64 def get(self, id: int) -> Tag: 65 """Fetch a single tag by its ID. 66 67 Args: 68 id: Numeric tag ID. 69 70 Returns: 71 The :class:`~easypaperless.models.tags.Tag` with the given ID. 72 73 Raises: 74 ~easypaperless.exceptions.NotFoundError: If no tag exists with 75 that ID. 76 """ 77 return cast(Tag, self._run(self._async_tags.get(id)))
Fetch a single tag by its ID.
Arguments:
- id: Numeric tag ID.
Returns:
The
~easypaperless.models.tags.Tagwith the given ID.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no tag exists with that ID.
79 def create( 80 self, 81 *, 82 name: str, 83 color: str | None = None, 84 is_inbox_tag: bool | None = None, 85 match: str | None | _Unset = UNSET, 86 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 87 is_insensitive: bool = True, 88 parent: int | None | _Unset = UNSET, 89 owner: int | None | _Unset = UNSET, 90 set_permissions: SetPermissions | None = None, 91 ) -> Tag: 92 """Create a new tag. 93 94 Args: 95 name: Tag name. Must be unique. 96 color: Background colour as a CSS hex string. 97 is_inbox_tag: When ``True``, newly ingested documents get this tag. 98 match: Auto-matching pattern. 99 matching_algorithm: Controls how ``match`` is applied. 100 is_insensitive: When ``True``, ``match`` is case-insensitive. 101 Defaults to ``True``, matching the paperless-ngx API default. 102 parent: ID of parent tag for hierarchical trees. 103 owner: Numeric user ID to assign as owner. 104 set_permissions: Explicit view/change permission sets. 105 106 Returns: 107 The newly created :class:`~easypaperless.models.tags.Tag`. 108 """ 109 return cast( 110 Tag, 111 self._run( 112 self._async_tags.create( 113 name=name, 114 color=color, 115 is_inbox_tag=is_inbox_tag, 116 match=match, 117 matching_algorithm=matching_algorithm, 118 is_insensitive=is_insensitive, 119 parent=parent, 120 owner=owner, 121 set_permissions=set_permissions, 122 ) 123 ), 124 )
Create a new tag.
Arguments:
- name: Tag name. Must be unique.
- color: Background colour as a CSS hex string.
- is_inbox_tag: When
True, newly ingested documents get this tag. - match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. Defaults toTrue, matching the paperless-ngx API default. - parent: ID of parent tag for hierarchical trees.
- owner: Numeric user ID to assign as owner.
- set_permissions: Explicit view/change permission sets.
Returns:
The newly created
~easypaperless.models.tags.Tag.
126 def update( 127 self, 128 id: int, 129 *, 130 name: str | None | _Unset = UNSET, 131 color: str | None | _Unset = UNSET, 132 is_inbox_tag: bool | None | _Unset = UNSET, 133 match: str | None | _Unset = UNSET, 134 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 135 is_insensitive: bool | None | _Unset = UNSET, 136 parent: int | None | _Unset = UNSET, 137 owner: int | None | _Unset = UNSET, 138 set_permissions: SetPermissions | None | _Unset = UNSET, 139 ) -> Tag: 140 """Partially update a tag (PATCH semantics). 141 142 Args: 143 id: Numeric ID of the tag to update. 144 name: Tag name. 145 color: Background colour as a CSS hex string. 146 is_inbox_tag: When ``True``, newly ingested documents get this tag. 147 match: Auto-matching pattern. 148 matching_algorithm: Controls how ``match`` is applied. 149 is_insensitive: When ``True``, ``match`` is case-insensitive. 150 parent: ID of parent tag. 151 Pass ``None`` to clear (make root tag). 152 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 153 owner: Numeric user ID to assign as owner. 154 Pass ``None`` to clear the owner. 155 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 156 set_permissions: Explicit view/change permission sets. 157 Omit (or pass :data:`~easypaperless.UNSET`) to leave unchanged. 158 159 Returns: 160 The updated :class:`~easypaperless.models.tags.Tag`. 161 """ 162 return cast( 163 Tag, 164 self._run( 165 self._async_tags.update( 166 id, 167 name=name, 168 color=color, 169 is_inbox_tag=is_inbox_tag, 170 match=match, 171 matching_algorithm=matching_algorithm, 172 is_insensitive=is_insensitive, 173 parent=parent, 174 owner=owner, 175 set_permissions=set_permissions, 176 ) 177 ), 178 )
Partially update a tag (PATCH semantics).
Arguments:
- id: Numeric ID of the tag to update.
- name: Tag name.
- color: Background colour as a CSS hex string.
- is_inbox_tag: When
True, newly ingested documents get this tag. - match: Auto-matching pattern.
- matching_algorithm: Controls how
matchis applied. - is_insensitive: When
True,matchis case-insensitive. - parent: ID of parent tag.
Pass
Noneto clear (make root tag). Omit (or pass~easypaperless.UNSET) to leave unchanged. - owner: Numeric user ID to assign as owner.
Pass
Noneto clear the owner. Omit (or pass~easypaperless.UNSET) to leave unchanged. - set_permissions: Explicit view/change permission sets.
Omit (or pass
~easypaperless.UNSET) to leave unchanged.
Returns:
The updated
~easypaperless.models.tags.Tag.
180 def delete(self, id: int) -> None: 181 """Delete a tag. 182 183 Args: 184 id: Numeric ID of the tag to delete. 185 186 Raises: 187 ~easypaperless.exceptions.NotFoundError: If no tag exists with 188 that ID. 189 """ 190 self._run(self._async_tags.delete(id))
Delete a tag.
Arguments:
- id: Numeric ID of the tag to delete.
Raises:
- ~easypaperless.exceptions.NotFoundError: If no tag exists with that ID.
192 def bulk_delete(self, ids: List[int]) -> None: 193 """Permanently delete multiple tags in a single request. 194 195 Args: 196 ids: List of tag IDs to delete. 197 """ 198 self._run(self._async_tags.bulk_delete(ids))
Permanently delete multiple tags in a single request.
Arguments:
- ids: List of tag IDs to delete.
200 def bulk_set_permissions( 201 self, 202 ids: List[int], 203 *, 204 set_permissions: SetPermissions | None = None, 205 owner: int | None = None, 206 merge: bool = False, 207 ) -> None: 208 """Set permissions and/or owner on multiple tags. 209 210 Args: 211 ids: List of tag IDs to modify. 212 set_permissions: Explicit view/change permission sets. 213 owner: Numeric user ID to assign as owner. 214 merge: When ``True``, new permissions are merged with existing ones. 215 """ 216 self._run( 217 self._async_tags.bulk_set_permissions( 218 ids, set_permissions=set_permissions, owner=owner, merge=merge 219 ) 220 )
Set permissions and/or owner on multiple tags.
Arguments:
- ids: List of tag IDs to modify.
- set_permissions: Explicit view/change permission sets.
- owner: Numeric user ID to assign as owner.
- merge: When
True, new permissions are merged with existing ones.