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 This is a sync wrapper for the async method with exactly the same parameters. 38 See: `easypaperless.CorrespondentsResource.list` 39 """ 40 return cast( 41 List[Correspondent], 42 self._run( 43 self._async_correspondents.list( 44 ids=ids, 45 name_contains=name_contains, 46 name_exact=name_exact, 47 page=page, 48 page_size=page_size, 49 ordering=ordering, 50 descending=descending, 51 ) 52 ), 53 ) 54 55 def get(self, id: int) -> Correspondent: 56 """Fetch a single correspondent by its ID. 57 58 This is a sync wrapper for the async method with exactly the same parameters. 59 See: `easypaperless.CorrespondentsResource.get` 60 """ 61 return cast(Correspondent, self._run(self._async_correspondents.get(id))) 62 63 def create( 64 self, 65 *, 66 name: str, 67 match: str | None | _Unset = UNSET, 68 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 69 is_insensitive: bool = True, 70 owner: int | None | _Unset = UNSET, 71 set_permissions: SetPermissions | None = None, 72 ) -> Correspondent: 73 """Create a new correspondent. 74 75 This is a sync wrapper for the async method with exactly the same parameters. 76 See: `easypaperless.CorrespondentsResource.create` 77 """ 78 return cast( 79 Correspondent, 80 self._run( 81 self._async_correspondents.create( 82 name=name, 83 match=match, 84 matching_algorithm=matching_algorithm, 85 is_insensitive=is_insensitive, 86 owner=owner, 87 set_permissions=set_permissions, 88 ) 89 ), 90 ) 91 92 def update( 93 self, 94 id: int, 95 *, 96 name: str | None | _Unset = UNSET, 97 match: str | None | _Unset = UNSET, 98 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 99 is_insensitive: bool | None | _Unset = UNSET, 100 owner: int | None | _Unset = UNSET, 101 set_permissions: SetPermissions | None | _Unset = UNSET, 102 ) -> Correspondent: 103 """Partially update a correspondent. 104 105 This is a sync wrapper for the async method with exactly the same parameters. 106 See: `easypaperless.CorrespondentsResource.update` 107 """ 108 return cast( 109 Correspondent, 110 self._run( 111 self._async_correspondents.update( 112 id, 113 name=name, 114 match=match, 115 matching_algorithm=matching_algorithm, 116 is_insensitive=is_insensitive, 117 owner=owner, 118 set_permissions=set_permissions, 119 ) 120 ), 121 ) 122 123 def delete(self, id: int) -> None: 124 """Delete a correspondent. 125 126 This is a sync wrapper for the async method with exactly the same parameters. 127 See: `easypaperless.CorrespondentsResource.delete` 128 """ 129 self._run(self._async_correspondents.delete(id)) 130 131 def bulk_delete(self, ids: List[int]) -> None: 132 """Permanently delete multiple correspondents. 133 134 This is a sync wrapper for the async method with exactly the same parameters. 135 See: `easypaperless.CorrespondentsResource.bulk_delete` 136 """ 137 self._run(self._async_correspondents.bulk_delete(ids)) 138 139 def bulk_set_permissions( 140 self, 141 ids: List[int], 142 *, 143 set_permissions: SetPermissions | None = None, 144 owner: int | None = None, 145 merge: bool = False, 146 ) -> None: 147 """Set permissions and/or owner on multiple correspondents. 148 149 This is a sync wrapper for the async method with exactly the same parameters. 150 See: `easypaperless.CorrespondentsResource.bulk_set_permissions` 151 """ 152 self._run( 153 self._async_correspondents.bulk_set_permissions( 154 ids, set_permissions=set_permissions, owner=owner, merge=merge 155 ) 156 )
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 This is a sync wrapper for the async method with exactly the same parameters. 38 See: `easypaperless.CorrespondentsResource.list` 39 """ 40 return cast( 41 List[Correspondent], 42 self._run( 43 self._async_correspondents.list( 44 ids=ids, 45 name_contains=name_contains, 46 name_exact=name_exact, 47 page=page, 48 page_size=page_size, 49 ordering=ordering, 50 descending=descending, 51 ) 52 ), 53 )
Return correspondents defined in paperless-ngx.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CorrespondentsResource.list
55 def get(self, id: int) -> Correspondent: 56 """Fetch a single correspondent by its ID. 57 58 This is a sync wrapper for the async method with exactly the same parameters. 59 See: `easypaperless.CorrespondentsResource.get` 60 """ 61 return cast(Correspondent, self._run(self._async_correspondents.get(id)))
Fetch a single correspondent by its ID.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CorrespondentsResource.get
63 def create( 64 self, 65 *, 66 name: str, 67 match: str | None | _Unset = UNSET, 68 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 69 is_insensitive: bool = True, 70 owner: int | None | _Unset = UNSET, 71 set_permissions: SetPermissions | None = None, 72 ) -> Correspondent: 73 """Create a new correspondent. 74 75 This is a sync wrapper for the async method with exactly the same parameters. 76 See: `easypaperless.CorrespondentsResource.create` 77 """ 78 return cast( 79 Correspondent, 80 self._run( 81 self._async_correspondents.create( 82 name=name, 83 match=match, 84 matching_algorithm=matching_algorithm, 85 is_insensitive=is_insensitive, 86 owner=owner, 87 set_permissions=set_permissions, 88 ) 89 ), 90 )
Create a new correspondent.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CorrespondentsResource.create
92 def update( 93 self, 94 id: int, 95 *, 96 name: str | None | _Unset = UNSET, 97 match: str | None | _Unset = UNSET, 98 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 99 is_insensitive: bool | None | _Unset = UNSET, 100 owner: int | None | _Unset = UNSET, 101 set_permissions: SetPermissions | None | _Unset = UNSET, 102 ) -> Correspondent: 103 """Partially update a correspondent. 104 105 This is a sync wrapper for the async method with exactly the same parameters. 106 See: `easypaperless.CorrespondentsResource.update` 107 """ 108 return cast( 109 Correspondent, 110 self._run( 111 self._async_correspondents.update( 112 id, 113 name=name, 114 match=match, 115 matching_algorithm=matching_algorithm, 116 is_insensitive=is_insensitive, 117 owner=owner, 118 set_permissions=set_permissions, 119 ) 120 ), 121 )
Partially update a correspondent.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CorrespondentsResource.update
123 def delete(self, id: int) -> None: 124 """Delete a correspondent. 125 126 This is a sync wrapper for the async method with exactly the same parameters. 127 See: `easypaperless.CorrespondentsResource.delete` 128 """ 129 self._run(self._async_correspondents.delete(id))
Delete a correspondent.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CorrespondentsResource.delete
131 def bulk_delete(self, ids: List[int]) -> None: 132 """Permanently delete multiple correspondents. 133 134 This is a sync wrapper for the async method with exactly the same parameters. 135 See: `easypaperless.CorrespondentsResource.bulk_delete` 136 """ 137 self._run(self._async_correspondents.bulk_delete(ids))
Permanently delete multiple correspondents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CorrespondentsResource.bulk_delete
139 def bulk_set_permissions( 140 self, 141 ids: List[int], 142 *, 143 set_permissions: SetPermissions | None = None, 144 owner: int | None = None, 145 merge: bool = False, 146 ) -> None: 147 """Set permissions and/or owner on multiple correspondents. 148 149 This is a sync wrapper for the async method with exactly the same parameters. 150 See: `easypaperless.CorrespondentsResource.bulk_set_permissions` 151 """ 152 self._run( 153 self._async_correspondents.bulk_set_permissions( 154 ids, set_permissions=set_permissions, owner=owner, merge=merge 155 ) 156 )
Set permissions and/or owner on multiple correspondents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CorrespondentsResource.bulk_set_permissions
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 This is a sync wrapper for the async method with exactly the same parameters. 36 See: `easypaperless.CustomFieldsResource.list` 37 """ 38 return cast( 39 List[CustomField], 40 self._run( 41 self._async_custom_fields.list( 42 name_contains=name_contains, 43 name_exact=name_exact, 44 page=page, 45 page_size=page_size, 46 ordering=ordering, 47 descending=descending, 48 ) 49 ), 50 ) 51 52 def get(self, id: int) -> CustomField: 53 """Fetch a single custom field by its ID. 54 55 This is a sync wrapper for the async method with exactly the same parameters. 56 See: `easypaperless.CustomFieldsResource.get` 57 """ 58 return cast(CustomField, self._run(self._async_custom_fields.get(id))) 59 60 def create( 61 self, 62 *, 63 name: str, 64 data_type: str, 65 extra_data: Any | None = None, 66 owner: int | None | _Unset = UNSET, 67 set_permissions: SetPermissions | None = None, 68 ) -> CustomField: 69 """Create a new custom field. 70 71 This is a sync wrapper for the async method with exactly the same parameters. 72 See: `easypaperless.CustomFieldsResource.create` 73 """ 74 return cast( 75 CustomField, 76 self._run( 77 self._async_custom_fields.create( 78 name=name, 79 data_type=data_type, 80 extra_data=extra_data, 81 owner=owner, 82 set_permissions=set_permissions, 83 ) 84 ), 85 ) 86 87 def update( 88 self, 89 id: int, 90 *, 91 name: str | None | _Unset = UNSET, 92 data_type: str | None | _Unset = UNSET, 93 extra_data: Any | None | _Unset = UNSET, 94 ) -> CustomField: 95 """Partially update a custom field. 96 97 This is a sync wrapper for the async method with exactly the same parameters. 98 See: `easypaperless.CustomFieldsResource.update` 99 """ 100 return cast( 101 CustomField, 102 self._run( 103 self._async_custom_fields.update( 104 id, 105 name=name, 106 data_type=data_type, 107 extra_data=extra_data, 108 ) 109 ), 110 ) 111 112 def delete(self, id: int) -> None: 113 """Delete a custom field. 114 115 This is a sync wrapper for the async method with exactly the same parameters. 116 See: `easypaperless.CustomFieldsResource.delete` 117 """ 118 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 This is a sync wrapper for the async method with exactly the same parameters. 36 See: `easypaperless.CustomFieldsResource.list` 37 """ 38 return cast( 39 List[CustomField], 40 self._run( 41 self._async_custom_fields.list( 42 name_contains=name_contains, 43 name_exact=name_exact, 44 page=page, 45 page_size=page_size, 46 ordering=ordering, 47 descending=descending, 48 ) 49 ), 50 )
Return all custom fields defined in paperless-ngx.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CustomFieldsResource.list
52 def get(self, id: int) -> CustomField: 53 """Fetch a single custom field by its ID. 54 55 This is a sync wrapper for the async method with exactly the same parameters. 56 See: `easypaperless.CustomFieldsResource.get` 57 """ 58 return cast(CustomField, self._run(self._async_custom_fields.get(id)))
Fetch a single custom field by its ID.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CustomFieldsResource.get
60 def create( 61 self, 62 *, 63 name: str, 64 data_type: str, 65 extra_data: Any | None = None, 66 owner: int | None | _Unset = UNSET, 67 set_permissions: SetPermissions | None = None, 68 ) -> CustomField: 69 """Create a new custom field. 70 71 This is a sync wrapper for the async method with exactly the same parameters. 72 See: `easypaperless.CustomFieldsResource.create` 73 """ 74 return cast( 75 CustomField, 76 self._run( 77 self._async_custom_fields.create( 78 name=name, 79 data_type=data_type, 80 extra_data=extra_data, 81 owner=owner, 82 set_permissions=set_permissions, 83 ) 84 ), 85 )
Create a new custom field.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CustomFieldsResource.create
87 def update( 88 self, 89 id: int, 90 *, 91 name: str | None | _Unset = UNSET, 92 data_type: str | None | _Unset = UNSET, 93 extra_data: Any | None | _Unset = UNSET, 94 ) -> CustomField: 95 """Partially update a custom field. 96 97 This is a sync wrapper for the async method with exactly the same parameters. 98 See: `easypaperless.CustomFieldsResource.update` 99 """ 100 return cast( 101 CustomField, 102 self._run( 103 self._async_custom_fields.update( 104 id, 105 name=name, 106 data_type=data_type, 107 extra_data=extra_data, 108 ) 109 ), 110 )
Partially update a custom field.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CustomFieldsResource.update
112 def delete(self, id: int) -> None: 113 """Delete a custom field. 114 115 This is a sync wrapper for the async method with exactly the same parameters. 116 See: `easypaperless.CustomFieldsResource.delete` 117 """ 118 self._run(self._async_custom_fields.delete(id))
Delete a custom field.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.CustomFieldsResource.delete
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 This is a sync wrapper for the async method with exactly the same parameters. 38 See: `easypaperless.DocumentTypesResource.list` 39 """ 40 return cast( 41 List[DocumentType], 42 self._run( 43 self._async_document_types.list( 44 ids=ids, 45 name_contains=name_contains, 46 name_exact=name_exact, 47 page=page, 48 page_size=page_size, 49 ordering=ordering, 50 descending=descending, 51 ) 52 ), 53 ) 54 55 def get(self, id: int) -> DocumentType: 56 """Fetch a single document type by its ID. 57 58 This is a sync wrapper for the async method with exactly the same parameters. 59 See: `easypaperless.DocumentTypesResource.get` 60 """ 61 return cast(DocumentType, self._run(self._async_document_types.get(id))) 62 63 def create( 64 self, 65 *, 66 name: str, 67 match: str | None | _Unset = UNSET, 68 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 69 is_insensitive: bool = True, 70 owner: int | None | _Unset = UNSET, 71 set_permissions: SetPermissions | None = None, 72 ) -> DocumentType: 73 """Create a new document type. 74 75 This is a sync wrapper for the async method with exactly the same parameters. 76 See: `easypaperless.DocumentTypesResource.create` 77 """ 78 return cast( 79 DocumentType, 80 self._run( 81 self._async_document_types.create( 82 name=name, 83 match=match, 84 matching_algorithm=matching_algorithm, 85 is_insensitive=is_insensitive, 86 owner=owner, 87 set_permissions=set_permissions, 88 ) 89 ), 90 ) 91 92 def update( 93 self, 94 id: int, 95 *, 96 name: str | None | _Unset = UNSET, 97 match: str | None | _Unset = UNSET, 98 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 99 is_insensitive: bool | None | _Unset = UNSET, 100 owner: int | None | _Unset = UNSET, 101 set_permissions: SetPermissions | None | _Unset = UNSET, 102 ) -> DocumentType: 103 """Partially update a document type. 104 105 This is a sync wrapper for the async method with exactly the same parameters. 106 See: `easypaperless.DocumentTypesResource.update` 107 """ 108 return cast( 109 DocumentType, 110 self._run( 111 self._async_document_types.update( 112 id, 113 name=name, 114 match=match, 115 matching_algorithm=matching_algorithm, 116 is_insensitive=is_insensitive, 117 owner=owner, 118 set_permissions=set_permissions, 119 ) 120 ), 121 ) 122 123 def delete(self, id: int) -> None: 124 """Delete a document type. 125 126 This is a sync wrapper for the async method with exactly the same parameters. 127 See: `easypaperless.DocumentTypesResource.delete` 128 """ 129 self._run(self._async_document_types.delete(id)) 130 131 def bulk_delete(self, ids: List[int]) -> None: 132 """Permanently delete multiple document types. 133 134 This is a sync wrapper for the async method with exactly the same parameters. 135 See: `easypaperless.DocumentTypesResource.bulk_delete` 136 """ 137 self._run(self._async_document_types.bulk_delete(ids)) 138 139 def bulk_set_permissions( 140 self, 141 ids: List[int], 142 *, 143 set_permissions: SetPermissions | None = None, 144 owner: int | None = None, 145 merge: bool = False, 146 ) -> None: 147 """Set permissions and/or owner on multiple document types. 148 149 This is a sync wrapper for the async method with exactly the same parameters. 150 See: `easypaperless.DocumentTypesResource.bulk_set_permissions` 151 """ 152 self._run( 153 self._async_document_types.bulk_set_permissions( 154 ids, set_permissions=set_permissions, owner=owner, merge=merge 155 ) 156 )
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 This is a sync wrapper for the async method with exactly the same parameters. 38 See: `easypaperless.DocumentTypesResource.list` 39 """ 40 return cast( 41 List[DocumentType], 42 self._run( 43 self._async_document_types.list( 44 ids=ids, 45 name_contains=name_contains, 46 name_exact=name_exact, 47 page=page, 48 page_size=page_size, 49 ordering=ordering, 50 descending=descending, 51 ) 52 ), 53 )
Return document types defined in paperless-ngx.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentTypesResource.list
55 def get(self, id: int) -> DocumentType: 56 """Fetch a single document type by its ID. 57 58 This is a sync wrapper for the async method with exactly the same parameters. 59 See: `easypaperless.DocumentTypesResource.get` 60 """ 61 return cast(DocumentType, self._run(self._async_document_types.get(id)))
Fetch a single document type by its ID.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentTypesResource.get
63 def create( 64 self, 65 *, 66 name: str, 67 match: str | None | _Unset = UNSET, 68 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 69 is_insensitive: bool = True, 70 owner: int | None | _Unset = UNSET, 71 set_permissions: SetPermissions | None = None, 72 ) -> DocumentType: 73 """Create a new document type. 74 75 This is a sync wrapper for the async method with exactly the same parameters. 76 See: `easypaperless.DocumentTypesResource.create` 77 """ 78 return cast( 79 DocumentType, 80 self._run( 81 self._async_document_types.create( 82 name=name, 83 match=match, 84 matching_algorithm=matching_algorithm, 85 is_insensitive=is_insensitive, 86 owner=owner, 87 set_permissions=set_permissions, 88 ) 89 ), 90 )
Create a new document type.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentTypesResource.create
92 def update( 93 self, 94 id: int, 95 *, 96 name: str | None | _Unset = UNSET, 97 match: str | None | _Unset = UNSET, 98 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 99 is_insensitive: bool | None | _Unset = UNSET, 100 owner: int | None | _Unset = UNSET, 101 set_permissions: SetPermissions | None | _Unset = UNSET, 102 ) -> DocumentType: 103 """Partially update a document type. 104 105 This is a sync wrapper for the async method with exactly the same parameters. 106 See: `easypaperless.DocumentTypesResource.update` 107 """ 108 return cast( 109 DocumentType, 110 self._run( 111 self._async_document_types.update( 112 id, 113 name=name, 114 match=match, 115 matching_algorithm=matching_algorithm, 116 is_insensitive=is_insensitive, 117 owner=owner, 118 set_permissions=set_permissions, 119 ) 120 ), 121 )
Partially update a document type.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentTypesResource.update
123 def delete(self, id: int) -> None: 124 """Delete a document type. 125 126 This is a sync wrapper for the async method with exactly the same parameters. 127 See: `easypaperless.DocumentTypesResource.delete` 128 """ 129 self._run(self._async_document_types.delete(id))
Delete a document type.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentTypesResource.delete
131 def bulk_delete(self, ids: List[int]) -> None: 132 """Permanently delete multiple document types. 133 134 This is a sync wrapper for the async method with exactly the same parameters. 135 See: `easypaperless.DocumentTypesResource.bulk_delete` 136 """ 137 self._run(self._async_document_types.bulk_delete(ids))
Permanently delete multiple document types.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentTypesResource.bulk_delete
139 def bulk_set_permissions( 140 self, 141 ids: List[int], 142 *, 143 set_permissions: SetPermissions | None = None, 144 owner: int | None = None, 145 merge: bool = False, 146 ) -> None: 147 """Set permissions and/or owner on multiple document types. 148 149 This is a sync wrapper for the async method with exactly the same parameters. 150 See: `easypaperless.DocumentTypesResource.bulk_set_permissions` 151 """ 152 self._run( 153 self._async_document_types.bulk_set_permissions( 154 ids, set_permissions=set_permissions, owner=owner, merge=merge 155 ) 156 )
Set permissions and/or owner on multiple document types.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentTypesResource.bulk_set_permissions
51class SyncDocumentsResource: 52 """Sync accessor for documents: ``client.documents``.""" 53 54 def __init__(self, async_documents: DocumentsResource, run: Any) -> None: 55 self._async_documents = async_documents 56 self._run = run 57 self.notes = SyncNotesResource(async_documents.notes, run) 58 59 def get(self, id: int, *, include_metadata: bool = False) -> Document: 60 """Fetch a single document by its ID. 61 62 This is a sync wrapper for the async method with exactly the same parameters. 63 See: `easypaperless.DocumentsResource.get` 64 """ 65 return cast( 66 Document, self._run(self._async_documents.get(id, include_metadata=include_metadata)) 67 ) 68 69 def get_metadata(self, id: int) -> DocumentMetadata: 70 """Fetch the extended file-level metadata for a document. 71 72 This is a sync wrapper for the async method with exactly the same parameters. 73 See: `easypaperless.DocumentsResource.get_metadata` 74 """ 75 return cast(DocumentMetadata, self._run(self._async_documents.get_metadata(id))) 76 77 def list( 78 self, 79 *, 80 search: str | None = None, 81 search_mode: str = "title_or_content", 82 ids: List[int] | None = None, 83 tags: List[int | str] | None = None, 84 any_tags: List[int | str] | None = None, 85 exclude_tags: List[int | str] | None = None, 86 correspondent: int | str | None | _Unset = UNSET, 87 any_correspondent: List[int | str] | None = None, 88 exclude_correspondents: List[int | str] | None = None, 89 document_type: int | str | None | _Unset = UNSET, 90 document_type_name_contains: str | None = None, 91 document_type_name_exact: str | None = None, 92 any_document_type: List[int | str] | None = None, 93 exclude_document_types: List[int | str] | None = None, 94 storage_path: int | str | None | _Unset = UNSET, 95 any_storage_paths: List[int | str] | None = None, 96 exclude_storage_paths: List[int | str] | None = None, 97 owner: int | None | _Unset = UNSET, 98 exclude_owners: List[int] | None = None, 99 custom_fields: List[int | str] | None = None, 100 any_custom_fields: List[int | str] | None = None, 101 exclude_custom_fields: List[int | str] | None = None, 102 custom_field_query: List[Any] | None = None, 103 archive_serial_number: int | None | _Unset = UNSET, 104 archive_serial_number_from: int | None = None, 105 archive_serial_number_till: int | None = None, 106 created_after: date | str | None = None, 107 created_before: date | str | None = None, 108 added_after: date | datetime | str | None = None, 109 added_from: date | datetime | str | None = None, 110 added_before: date | datetime | str | None = None, 111 added_until: date | datetime | str | None = None, 112 modified_after: date | datetime | str | None = None, 113 modified_from: date | datetime | str | None = None, 114 modified_before: date | datetime | str | None = None, 115 modified_until: date | datetime | str | None = None, 116 checksum: str | None = None, 117 page_size: int = 25, 118 page: int | None = None, 119 ordering: str | None = None, 120 descending: bool = False, 121 max_results: int | None = None, 122 on_page: Callable[[int, int | None], None] | None = None, 123 ) -> List[Document]: 124 """Return a filtered list of documents. 125 126 This is a sync wrapper for the async method with exactly the same parameters. 127 See: `easypaperless.DocumentsResource.list` 128 """ 129 return cast( 130 List[Document], 131 self._run( 132 self._async_documents.list( 133 search=search, 134 search_mode=search_mode, 135 ids=ids, 136 tags=tags, 137 any_tags=any_tags, 138 exclude_tags=exclude_tags, 139 correspondent=correspondent, 140 any_correspondent=any_correspondent, 141 exclude_correspondents=exclude_correspondents, 142 document_type=document_type, 143 document_type_name_contains=document_type_name_contains, 144 document_type_name_exact=document_type_name_exact, 145 any_document_type=any_document_type, 146 exclude_document_types=exclude_document_types, 147 storage_path=storage_path, 148 any_storage_paths=any_storage_paths, 149 exclude_storage_paths=exclude_storage_paths, 150 owner=owner, 151 exclude_owners=exclude_owners, 152 custom_fields=custom_fields, 153 any_custom_fields=any_custom_fields, 154 exclude_custom_fields=exclude_custom_fields, 155 custom_field_query=custom_field_query, 156 archive_serial_number=archive_serial_number, 157 archive_serial_number_from=archive_serial_number_from, 158 archive_serial_number_till=archive_serial_number_till, 159 created_after=created_after, 160 created_before=created_before, 161 added_after=added_after, 162 added_from=added_from, 163 added_before=added_before, 164 added_until=added_until, 165 modified_after=modified_after, 166 modified_from=modified_from, 167 modified_before=modified_before, 168 modified_until=modified_until, 169 checksum=checksum, 170 page_size=page_size, 171 page=page, 172 ordering=ordering, 173 descending=descending, 174 max_results=max_results, 175 on_page=on_page, 176 ) 177 ), 178 ) 179 180 def update( 181 self, 182 id: int, 183 *, 184 title: str | None | _Unset = UNSET, 185 content: str | None | _Unset = UNSET, 186 created: date | str | None | _Unset = UNSET, 187 correspondent: int | str | None | _Unset = UNSET, 188 document_type: int | str | None | _Unset = UNSET, 189 storage_path: int | str | None | _Unset = UNSET, 190 tags: List[int | str] | None | _Unset = UNSET, 191 archive_serial_number: int | None | _Unset = UNSET, 192 custom_fields: List[dict[str, Any]] | None | _Unset = UNSET, 193 owner: int | None | _Unset = UNSET, 194 set_permissions: SetPermissions | None | _Unset = UNSET, 195 remove_inbox_tags: bool | None | _Unset = UNSET, 196 ) -> Document: 197 """Partially update a document. 198 199 This is a sync wrapper for the async method with exactly the same parameters. 200 See: `easypaperless.DocumentsResource.update` 201 """ 202 return cast( 203 Document, 204 self._run( 205 self._async_documents.update( 206 id, 207 title=title, 208 content=content, 209 created=created, 210 correspondent=correspondent, 211 document_type=document_type, 212 storage_path=storage_path, 213 tags=tags, 214 archive_serial_number=archive_serial_number, 215 custom_fields=custom_fields, 216 owner=owner, 217 set_permissions=set_permissions, 218 remove_inbox_tags=remove_inbox_tags, 219 ) 220 ), 221 ) 222 223 def delete(self, id: int) -> None: 224 """Permanently delete a document. 225 226 This is a sync wrapper for the async method with exactly the same parameters. 227 See: `easypaperless.DocumentsResource.delete` 228 """ 229 self._run(self._async_documents.delete(id)) 230 231 def download(self, id: int, *, original: bool = False) -> bytes: 232 """Download the binary content of a document. 233 234 This is a sync wrapper for the async method with exactly the same parameters. 235 See: `easypaperless.DocumentsResource.download` 236 """ 237 return cast(bytes, self._run(self._async_documents.download(id, original=original))) 238 239 def upload( 240 self, 241 file: str | Path, 242 *, 243 title: str | None = None, 244 created: date | str | None = None, 245 correspondent: int | str | None | _Unset = UNSET, 246 document_type: int | str | None | _Unset = UNSET, 247 storage_path: int | str | None | _Unset = UNSET, 248 tags: List[int | str] | None = None, 249 archive_serial_number: int | None | _Unset = UNSET, 250 custom_fields: List[dict[str, Any]] | None = None, 251 wait: bool = False, 252 poll_interval: float | None = None, 253 poll_timeout: float | None = None, 254 ) -> str | Document: 255 """Upload a document to paperless-ngx. 256 257 This is a sync wrapper for the async method with exactly the same parameters. 258 See: `easypaperless.DocumentsResource.upload` 259 """ 260 return cast( 261 str | Document, 262 self._run( 263 self._async_documents.upload( 264 file, 265 title=title, 266 created=created, 267 correspondent=correspondent, 268 document_type=document_type, 269 storage_path=storage_path, 270 tags=tags, 271 archive_serial_number=archive_serial_number, 272 custom_fields=custom_fields, 273 wait=wait, 274 poll_interval=poll_interval, 275 poll_timeout=poll_timeout, 276 ) 277 ), 278 ) 279 280 def bulk_add_tag(self, document_ids: List[int], tag: int | str) -> None: 281 """Add a tag to multiple documents. 282 283 This is a sync wrapper for the async method with exactly the same parameters. 284 See: `easypaperless.DocumentsResource.bulk_add_tag` 285 """ 286 self._run(self._async_documents.bulk_add_tag(document_ids, tag)) 287 288 def bulk_remove_tag(self, document_ids: List[int], tag: int | str) -> None: 289 """Remove a tag from multiple documents. 290 291 This is a sync wrapper for the async method with exactly the same parameters. 292 See: `easypaperless.DocumentsResource.bulk_remove_tag` 293 """ 294 self._run(self._async_documents.bulk_remove_tag(document_ids, tag)) 295 296 def bulk_modify_tags( 297 self, 298 document_ids: List[int], 299 *, 300 add_tags: List[int | str] | None = None, 301 remove_tags: List[int | str] | None = None, 302 ) -> None: 303 """Add and/or remove tags on multiple documents atomically. 304 305 This is a sync wrapper for the async method with exactly the same parameters. 306 See: `easypaperless.DocumentsResource.bulk_modify_tags` 307 """ 308 self._run( 309 self._async_documents.bulk_modify_tags( 310 document_ids, add_tags=add_tags, remove_tags=remove_tags 311 ) 312 ) 313 314 def bulk_delete(self, document_ids: List[int]) -> None: 315 """Permanently delete multiple documents. 316 317 This is a sync wrapper for the async method with exactly the same parameters. 318 See: `easypaperless.DocumentsResource.bulk_delete` 319 """ 320 self._run(self._async_documents.bulk_delete(document_ids)) 321 322 def bulk_set_correspondent( 323 self, document_ids: List[int], correspondent: int | str | None 324 ) -> None: 325 """Assign a correspondent to multiple documents. 326 327 This is a sync wrapper for the async method with exactly the same parameters. 328 See: `easypaperless.DocumentsResource.bulk_set_correspondent` 329 """ 330 self._run(self._async_documents.bulk_set_correspondent(document_ids, correspondent)) 331 332 def bulk_set_document_type( 333 self, document_ids: List[int], document_type: int | str | None 334 ) -> None: 335 """Assign a document type to multiple documents. 336 337 This is a sync wrapper for the async method with exactly the same parameters. 338 See: `easypaperless.DocumentsResource.bulk_set_document_type` 339 """ 340 self._run(self._async_documents.bulk_set_document_type(document_ids, document_type)) 341 342 def bulk_set_storage_path( 343 self, document_ids: List[int], storage_path: int | str | None 344 ) -> None: 345 """Assign a storage path to multiple documents. 346 347 This is a sync wrapper for the async method with exactly the same parameters. 348 See: `easypaperless.DocumentsResource.bulk_set_storage_path` 349 """ 350 self._run(self._async_documents.bulk_set_storage_path(document_ids, storage_path)) 351 352 def bulk_modify_custom_fields( 353 self, 354 document_ids: List[int], 355 *, 356 add_fields: List[dict[str, Any]] | None = None, 357 remove_fields: List[int] | None = None, 358 ) -> None: 359 """Add and/or remove custom field values on multiple documents. 360 361 This is a sync wrapper for the async method with exactly the same parameters. 362 See: `easypaperless.DocumentsResource.bulk_modify_custom_fields` 363 """ 364 self._run( 365 self._async_documents.bulk_modify_custom_fields( 366 document_ids, add_fields=add_fields, remove_fields=remove_fields 367 ) 368 ) 369 370 def bulk_set_permissions( 371 self, 372 document_ids: List[int], 373 *, 374 set_permissions: SetPermissions | None = None, 375 owner: int | None = None, 376 merge: bool = False, 377 ) -> None: 378 """Set permissions and/or owner on multiple documents. 379 380 This is a sync wrapper for the async method with exactly the same parameters. 381 See: `easypaperless.DocumentsResource.bulk_set_permissions` 382 """ 383 self._run( 384 self._async_documents.bulk_set_permissions( 385 document_ids, 386 set_permissions=set_permissions, 387 owner=owner, 388 merge=merge, 389 ) 390 )
Sync accessor for documents: client.documents.
59 def get(self, id: int, *, include_metadata: bool = False) -> Document: 60 """Fetch a single document by its ID. 61 62 This is a sync wrapper for the async method with exactly the same parameters. 63 See: `easypaperless.DocumentsResource.get` 64 """ 65 return cast( 66 Document, self._run(self._async_documents.get(id, include_metadata=include_metadata)) 67 )
Fetch a single document by its ID.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.get
69 def get_metadata(self, id: int) -> DocumentMetadata: 70 """Fetch the extended file-level metadata for a document. 71 72 This is a sync wrapper for the async method with exactly the same parameters. 73 See: `easypaperless.DocumentsResource.get_metadata` 74 """ 75 return cast(DocumentMetadata, self._run(self._async_documents.get_metadata(id)))
Fetch the extended file-level metadata for a document.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.get_metadata
77 def list( 78 self, 79 *, 80 search: str | None = None, 81 search_mode: str = "title_or_content", 82 ids: List[int] | None = None, 83 tags: List[int | str] | None = None, 84 any_tags: List[int | str] | None = None, 85 exclude_tags: List[int | str] | None = None, 86 correspondent: int | str | None | _Unset = UNSET, 87 any_correspondent: List[int | str] | None = None, 88 exclude_correspondents: List[int | str] | None = None, 89 document_type: int | str | None | _Unset = UNSET, 90 document_type_name_contains: str | None = None, 91 document_type_name_exact: str | None = None, 92 any_document_type: List[int | str] | None = None, 93 exclude_document_types: List[int | str] | None = None, 94 storage_path: int | str | None | _Unset = UNSET, 95 any_storage_paths: List[int | str] | None = None, 96 exclude_storage_paths: List[int | str] | None = None, 97 owner: int | None | _Unset = UNSET, 98 exclude_owners: List[int] | None = None, 99 custom_fields: List[int | str] | None = None, 100 any_custom_fields: List[int | str] | None = None, 101 exclude_custom_fields: List[int | str] | None = None, 102 custom_field_query: List[Any] | None = None, 103 archive_serial_number: int | None | _Unset = UNSET, 104 archive_serial_number_from: int | None = None, 105 archive_serial_number_till: int | None = None, 106 created_after: date | str | None = None, 107 created_before: date | str | None = None, 108 added_after: date | datetime | str | None = None, 109 added_from: date | datetime | str | None = None, 110 added_before: date | datetime | str | None = None, 111 added_until: date | datetime | str | None = None, 112 modified_after: date | datetime | str | None = None, 113 modified_from: date | datetime | str | None = None, 114 modified_before: date | datetime | str | None = None, 115 modified_until: date | datetime | str | None = None, 116 checksum: str | None = None, 117 page_size: int = 25, 118 page: int | None = None, 119 ordering: str | None = None, 120 descending: bool = False, 121 max_results: int | None = None, 122 on_page: Callable[[int, int | None], None] | None = None, 123 ) -> List[Document]: 124 """Return a filtered list of documents. 125 126 This is a sync wrapper for the async method with exactly the same parameters. 127 See: `easypaperless.DocumentsResource.list` 128 """ 129 return cast( 130 List[Document], 131 self._run( 132 self._async_documents.list( 133 search=search, 134 search_mode=search_mode, 135 ids=ids, 136 tags=tags, 137 any_tags=any_tags, 138 exclude_tags=exclude_tags, 139 correspondent=correspondent, 140 any_correspondent=any_correspondent, 141 exclude_correspondents=exclude_correspondents, 142 document_type=document_type, 143 document_type_name_contains=document_type_name_contains, 144 document_type_name_exact=document_type_name_exact, 145 any_document_type=any_document_type, 146 exclude_document_types=exclude_document_types, 147 storage_path=storage_path, 148 any_storage_paths=any_storage_paths, 149 exclude_storage_paths=exclude_storage_paths, 150 owner=owner, 151 exclude_owners=exclude_owners, 152 custom_fields=custom_fields, 153 any_custom_fields=any_custom_fields, 154 exclude_custom_fields=exclude_custom_fields, 155 custom_field_query=custom_field_query, 156 archive_serial_number=archive_serial_number, 157 archive_serial_number_from=archive_serial_number_from, 158 archive_serial_number_till=archive_serial_number_till, 159 created_after=created_after, 160 created_before=created_before, 161 added_after=added_after, 162 added_from=added_from, 163 added_before=added_before, 164 added_until=added_until, 165 modified_after=modified_after, 166 modified_from=modified_from, 167 modified_before=modified_before, 168 modified_until=modified_until, 169 checksum=checksum, 170 page_size=page_size, 171 page=page, 172 ordering=ordering, 173 descending=descending, 174 max_results=max_results, 175 on_page=on_page, 176 ) 177 ), 178 )
Return a filtered list of documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.list
180 def update( 181 self, 182 id: int, 183 *, 184 title: str | None | _Unset = UNSET, 185 content: str | None | _Unset = UNSET, 186 created: date | str | None | _Unset = UNSET, 187 correspondent: int | str | None | _Unset = UNSET, 188 document_type: int | str | None | _Unset = UNSET, 189 storage_path: int | str | None | _Unset = UNSET, 190 tags: List[int | str] | None | _Unset = UNSET, 191 archive_serial_number: int | None | _Unset = UNSET, 192 custom_fields: List[dict[str, Any]] | None | _Unset = UNSET, 193 owner: int | None | _Unset = UNSET, 194 set_permissions: SetPermissions | None | _Unset = UNSET, 195 remove_inbox_tags: bool | None | _Unset = UNSET, 196 ) -> Document: 197 """Partially update a document. 198 199 This is a sync wrapper for the async method with exactly the same parameters. 200 See: `easypaperless.DocumentsResource.update` 201 """ 202 return cast( 203 Document, 204 self._run( 205 self._async_documents.update( 206 id, 207 title=title, 208 content=content, 209 created=created, 210 correspondent=correspondent, 211 document_type=document_type, 212 storage_path=storage_path, 213 tags=tags, 214 archive_serial_number=archive_serial_number, 215 custom_fields=custom_fields, 216 owner=owner, 217 set_permissions=set_permissions, 218 remove_inbox_tags=remove_inbox_tags, 219 ) 220 ), 221 )
Partially update a document.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.update
223 def delete(self, id: int) -> None: 224 """Permanently delete a document. 225 226 This is a sync wrapper for the async method with exactly the same parameters. 227 See: `easypaperless.DocumentsResource.delete` 228 """ 229 self._run(self._async_documents.delete(id))
Permanently delete a document.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.delete
231 def download(self, id: int, *, original: bool = False) -> bytes: 232 """Download the binary content of a document. 233 234 This is a sync wrapper for the async method with exactly the same parameters. 235 See: `easypaperless.DocumentsResource.download` 236 """ 237 return cast(bytes, self._run(self._async_documents.download(id, original=original)))
Download the binary content of a document.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.download
239 def upload( 240 self, 241 file: str | Path, 242 *, 243 title: str | None = None, 244 created: date | str | None = None, 245 correspondent: int | str | None | _Unset = UNSET, 246 document_type: int | str | None | _Unset = UNSET, 247 storage_path: int | str | None | _Unset = UNSET, 248 tags: List[int | str] | None = None, 249 archive_serial_number: int | None | _Unset = UNSET, 250 custom_fields: List[dict[str, Any]] | None = None, 251 wait: bool = False, 252 poll_interval: float | None = None, 253 poll_timeout: float | None = None, 254 ) -> str | Document: 255 """Upload a document to paperless-ngx. 256 257 This is a sync wrapper for the async method with exactly the same parameters. 258 See: `easypaperless.DocumentsResource.upload` 259 """ 260 return cast( 261 str | Document, 262 self._run( 263 self._async_documents.upload( 264 file, 265 title=title, 266 created=created, 267 correspondent=correspondent, 268 document_type=document_type, 269 storage_path=storage_path, 270 tags=tags, 271 archive_serial_number=archive_serial_number, 272 custom_fields=custom_fields, 273 wait=wait, 274 poll_interval=poll_interval, 275 poll_timeout=poll_timeout, 276 ) 277 ), 278 )
Upload a document to paperless-ngx.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.upload
280 def bulk_add_tag(self, document_ids: List[int], tag: int | str) -> None: 281 """Add a tag to multiple documents. 282 283 This is a sync wrapper for the async method with exactly the same parameters. 284 See: `easypaperless.DocumentsResource.bulk_add_tag` 285 """ 286 self._run(self._async_documents.bulk_add_tag(document_ids, tag))
Add a tag to multiple documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.bulk_add_tag
288 def bulk_remove_tag(self, document_ids: List[int], tag: int | str) -> None: 289 """Remove a tag from multiple documents. 290 291 This is a sync wrapper for the async method with exactly the same parameters. 292 See: `easypaperless.DocumentsResource.bulk_remove_tag` 293 """ 294 self._run(self._async_documents.bulk_remove_tag(document_ids, tag))
Remove a tag from multiple documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.bulk_remove_tag
314 def bulk_delete(self, document_ids: List[int]) -> None: 315 """Permanently delete multiple documents. 316 317 This is a sync wrapper for the async method with exactly the same parameters. 318 See: `easypaperless.DocumentsResource.bulk_delete` 319 """ 320 self._run(self._async_documents.bulk_delete(document_ids))
Permanently delete multiple documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.bulk_delete
322 def bulk_set_correspondent( 323 self, document_ids: List[int], correspondent: int | str | None 324 ) -> None: 325 """Assign a correspondent to multiple documents. 326 327 This is a sync wrapper for the async method with exactly the same parameters. 328 See: `easypaperless.DocumentsResource.bulk_set_correspondent` 329 """ 330 self._run(self._async_documents.bulk_set_correspondent(document_ids, correspondent))
Assign a correspondent to multiple documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.bulk_set_correspondent
332 def bulk_set_document_type( 333 self, document_ids: List[int], document_type: int | str | None 334 ) -> None: 335 """Assign a document type to multiple documents. 336 337 This is a sync wrapper for the async method with exactly the same parameters. 338 See: `easypaperless.DocumentsResource.bulk_set_document_type` 339 """ 340 self._run(self._async_documents.bulk_set_document_type(document_ids, document_type))
Assign a document type to multiple documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.bulk_set_document_type
342 def bulk_set_storage_path( 343 self, document_ids: List[int], storage_path: int | str | None 344 ) -> None: 345 """Assign a storage path to multiple documents. 346 347 This is a sync wrapper for the async method with exactly the same parameters. 348 See: `easypaperless.DocumentsResource.bulk_set_storage_path` 349 """ 350 self._run(self._async_documents.bulk_set_storage_path(document_ids, storage_path))
Assign a storage path to multiple documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.bulk_set_storage_path
352 def bulk_modify_custom_fields( 353 self, 354 document_ids: List[int], 355 *, 356 add_fields: List[dict[str, Any]] | None = None, 357 remove_fields: List[int] | None = None, 358 ) -> None: 359 """Add and/or remove custom field values on multiple documents. 360 361 This is a sync wrapper for the async method with exactly the same parameters. 362 See: `easypaperless.DocumentsResource.bulk_modify_custom_fields` 363 """ 364 self._run( 365 self._async_documents.bulk_modify_custom_fields( 366 document_ids, add_fields=add_fields, remove_fields=remove_fields 367 ) 368 )
Add and/or remove custom field values on multiple documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.bulk_modify_custom_fields
370 def bulk_set_permissions( 371 self, 372 document_ids: List[int], 373 *, 374 set_permissions: SetPermissions | None = None, 375 owner: int | None = None, 376 merge: bool = False, 377 ) -> None: 378 """Set permissions and/or owner on multiple documents. 379 380 This is a sync wrapper for the async method with exactly the same parameters. 381 See: `easypaperless.DocumentsResource.bulk_set_permissions` 382 """ 383 self._run( 384 self._async_documents.bulk_set_permissions( 385 document_ids, 386 set_permissions=set_permissions, 387 owner=owner, 388 merge=merge, 389 ) 390 )
Set permissions and/or owner on multiple documents.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.DocumentsResource.bulk_set_permissions
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 This is a sync wrapper for the async method with exactly the same parameters. 30 See: `easypaperless.NotesResource.list` 31 """ 32 return cast(List[DocumentNote], self._run(self._async_notes.list(document_id))) 33 34 def create(self, document_id: int, *, note: str) -> DocumentNote: 35 """Create a new note on a document. 36 37 This is a sync wrapper for the async method with exactly the same parameters. 38 See: `easypaperless.NotesResource.create` 39 """ 40 return cast(DocumentNote, self._run(self._async_notes.create(document_id, note=note))) 41 42 def delete(self, document_id: int, note_id: int) -> None: 43 """Delete a note from a document. 44 45 This is a sync wrapper for the async method with exactly the same parameters. 46 See: `easypaperless.NotesResource.delete` 47 """ 48 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 This is a sync wrapper for the async method with exactly the same parameters. 30 See: `easypaperless.NotesResource.list` 31 """ 32 return cast(List[DocumentNote], self._run(self._async_notes.list(document_id)))
Fetch all notes attached to a document.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.NotesResource.list
34 def create(self, document_id: int, *, note: str) -> DocumentNote: 35 """Create a new note on a document. 36 37 This is a sync wrapper for the async method with exactly the same parameters. 38 See: `easypaperless.NotesResource.create` 39 """ 40 return cast(DocumentNote, self._run(self._async_notes.create(document_id, note=note)))
Create a new note on a document.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.NotesResource.create
42 def delete(self, document_id: int, note_id: int) -> None: 43 """Delete a note from a document. 44 45 This is a sync wrapper for the async method with exactly the same parameters. 46 See: `easypaperless.NotesResource.delete` 47 """ 48 self._run(self._async_notes.delete(document_id, note_id))
Delete a note from a document.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.NotesResource.delete
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 This is a sync wrapper for the async method with exactly the same parameters. 40 See: `easypaperless.StoragePathsResource.list` 41 """ 42 return cast( 43 List[StoragePath], 44 self._run( 45 self._async_storage_paths.list( 46 ids=ids, 47 name_contains=name_contains, 48 name_exact=name_exact, 49 path_contains=path_contains, 50 path_exact=path_exact, 51 page=page, 52 page_size=page_size, 53 ordering=ordering, 54 descending=descending, 55 ) 56 ), 57 ) 58 59 def get(self, id: int) -> StoragePath: 60 """Fetch a single storage path by its ID. 61 62 This is a sync wrapper for the async method with exactly the same parameters. 63 See: `easypaperless.StoragePathsResource.get` 64 """ 65 return cast(StoragePath, self._run(self._async_storage_paths.get(id))) 66 67 def create( 68 self, 69 *, 70 name: str, 71 path: str | None = None, 72 match: str | None | _Unset = UNSET, 73 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 74 is_insensitive: bool = True, 75 owner: int | None | _Unset = UNSET, 76 set_permissions: SetPermissions | None = None, 77 ) -> StoragePath: 78 """Create a new storage path. 79 80 This is a sync wrapper for the async method with exactly the same parameters. 81 See: `easypaperless.StoragePathsResource.create` 82 """ 83 return cast( 84 StoragePath, 85 self._run( 86 self._async_storage_paths.create( 87 name=name, 88 path=path, 89 match=match, 90 matching_algorithm=matching_algorithm, 91 is_insensitive=is_insensitive, 92 owner=owner, 93 set_permissions=set_permissions, 94 ) 95 ), 96 ) 97 98 def update( 99 self, 100 id: int, 101 *, 102 name: str | None | _Unset = UNSET, 103 path: str | None | _Unset = UNSET, 104 match: str | None | _Unset = UNSET, 105 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 106 is_insensitive: bool | None | _Unset = UNSET, 107 owner: int | None | _Unset = UNSET, 108 set_permissions: SetPermissions | None | _Unset = UNSET, 109 ) -> StoragePath: 110 """Partially update a storage path. 111 112 This is a sync wrapper for the async method with exactly the same parameters. 113 See: `easypaperless.StoragePathsResource.update` 114 """ 115 return cast( 116 StoragePath, 117 self._run( 118 self._async_storage_paths.update( 119 id, 120 name=name, 121 path=path, 122 match=match, 123 matching_algorithm=matching_algorithm, 124 is_insensitive=is_insensitive, 125 owner=owner, 126 set_permissions=set_permissions, 127 ) 128 ), 129 ) 130 131 def delete(self, id: int) -> None: 132 """Delete a storage path. 133 134 This is a sync wrapper for the async method with exactly the same parameters. 135 See: `easypaperless.StoragePathsResource.delete` 136 """ 137 self._run(self._async_storage_paths.delete(id)) 138 139 def bulk_delete(self, ids: List[int]) -> None: 140 """Permanently delete multiple storage paths. 141 142 This is a sync wrapper for the async method with exactly the same parameters. 143 See: `easypaperless.StoragePathsResource.bulk_delete` 144 """ 145 self._run(self._async_storage_paths.bulk_delete(ids)) 146 147 def bulk_set_permissions( 148 self, 149 ids: List[int], 150 *, 151 set_permissions: SetPermissions | None = None, 152 owner: int | None = None, 153 merge: bool = False, 154 ) -> None: 155 """Set permissions and/or owner on multiple storage paths. 156 157 This is a sync wrapper for the async method with exactly the same parameters. 158 See: `easypaperless.StoragePathsResource.bulk_set_permissions` 159 """ 160 self._run( 161 self._async_storage_paths.bulk_set_permissions( 162 ids, set_permissions=set_permissions, owner=owner, merge=merge 163 ) 164 )
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 This is a sync wrapper for the async method with exactly the same parameters. 40 See: `easypaperless.StoragePathsResource.list` 41 """ 42 return cast( 43 List[StoragePath], 44 self._run( 45 self._async_storage_paths.list( 46 ids=ids, 47 name_contains=name_contains, 48 name_exact=name_exact, 49 path_contains=path_contains, 50 path_exact=path_exact, 51 page=page, 52 page_size=page_size, 53 ordering=ordering, 54 descending=descending, 55 ) 56 ), 57 )
Return storage paths defined in paperless-ngx.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.StoragePathsResource.list
59 def get(self, id: int) -> StoragePath: 60 """Fetch a single storage path by its ID. 61 62 This is a sync wrapper for the async method with exactly the same parameters. 63 See: `easypaperless.StoragePathsResource.get` 64 """ 65 return cast(StoragePath, self._run(self._async_storage_paths.get(id)))
Fetch a single storage path by its ID.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.StoragePathsResource.get
67 def create( 68 self, 69 *, 70 name: str, 71 path: str | None = None, 72 match: str | None | _Unset = UNSET, 73 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 74 is_insensitive: bool = True, 75 owner: int | None | _Unset = UNSET, 76 set_permissions: SetPermissions | None = None, 77 ) -> StoragePath: 78 """Create a new storage path. 79 80 This is a sync wrapper for the async method with exactly the same parameters. 81 See: `easypaperless.StoragePathsResource.create` 82 """ 83 return cast( 84 StoragePath, 85 self._run( 86 self._async_storage_paths.create( 87 name=name, 88 path=path, 89 match=match, 90 matching_algorithm=matching_algorithm, 91 is_insensitive=is_insensitive, 92 owner=owner, 93 set_permissions=set_permissions, 94 ) 95 ), 96 )
Create a new storage path.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.StoragePathsResource.create
98 def update( 99 self, 100 id: int, 101 *, 102 name: str | None | _Unset = UNSET, 103 path: str | None | _Unset = UNSET, 104 match: str | None | _Unset = UNSET, 105 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 106 is_insensitive: bool | None | _Unset = UNSET, 107 owner: int | None | _Unset = UNSET, 108 set_permissions: SetPermissions | None | _Unset = UNSET, 109 ) -> StoragePath: 110 """Partially update a storage path. 111 112 This is a sync wrapper for the async method with exactly the same parameters. 113 See: `easypaperless.StoragePathsResource.update` 114 """ 115 return cast( 116 StoragePath, 117 self._run( 118 self._async_storage_paths.update( 119 id, 120 name=name, 121 path=path, 122 match=match, 123 matching_algorithm=matching_algorithm, 124 is_insensitive=is_insensitive, 125 owner=owner, 126 set_permissions=set_permissions, 127 ) 128 ), 129 )
Partially update a storage path.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.StoragePathsResource.update
131 def delete(self, id: int) -> None: 132 """Delete a storage path. 133 134 This is a sync wrapper for the async method with exactly the same parameters. 135 See: `easypaperless.StoragePathsResource.delete` 136 """ 137 self._run(self._async_storage_paths.delete(id))
Delete a storage path.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.StoragePathsResource.delete
139 def bulk_delete(self, ids: List[int]) -> None: 140 """Permanently delete multiple storage paths. 141 142 This is a sync wrapper for the async method with exactly the same parameters. 143 See: `easypaperless.StoragePathsResource.bulk_delete` 144 """ 145 self._run(self._async_storage_paths.bulk_delete(ids))
Permanently delete multiple storage paths.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.StoragePathsResource.bulk_delete
147 def bulk_set_permissions( 148 self, 149 ids: List[int], 150 *, 151 set_permissions: SetPermissions | None = None, 152 owner: int | None = None, 153 merge: bool = False, 154 ) -> None: 155 """Set permissions and/or owner on multiple storage paths. 156 157 This is a sync wrapper for the async method with exactly the same parameters. 158 See: `easypaperless.StoragePathsResource.bulk_set_permissions` 159 """ 160 self._run( 161 self._async_storage_paths.bulk_set_permissions( 162 ids, set_permissions=set_permissions, owner=owner, merge=merge 163 ) 164 )
Set permissions and/or owner on multiple storage paths.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.StoragePathsResource.bulk_set_permissions
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 This is a sync wrapper for the async method with exactly the same parameters. 38 See: `easypaperless.TagsResource.list` 39 """ 40 return cast( 41 List[Tag], 42 self._run( 43 self._async_tags.list( 44 ids=ids, 45 name_contains=name_contains, 46 name_exact=name_exact, 47 page=page, 48 page_size=page_size, 49 ordering=ordering, 50 descending=descending, 51 ) 52 ), 53 ) 54 55 def get(self, id: int) -> Tag: 56 """Fetch a single tag by its ID. 57 58 This is a sync wrapper for the async method with exactly the same parameters. 59 See: `easypaperless.TagsResource.get` 60 """ 61 return cast(Tag, self._run(self._async_tags.get(id))) 62 63 def create( 64 self, 65 *, 66 name: str, 67 color: str | None = None, 68 is_inbox_tag: bool | None = None, 69 match: str | None | _Unset = UNSET, 70 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 71 is_insensitive: bool = True, 72 parent: int | None | _Unset = UNSET, 73 owner: int | None | _Unset = UNSET, 74 set_permissions: SetPermissions | None = None, 75 ) -> Tag: 76 """Create a new tag. 77 78 This is a sync wrapper for the async method with exactly the same parameters. 79 See: `easypaperless.TagsResource.create` 80 """ 81 return cast( 82 Tag, 83 self._run( 84 self._async_tags.create( 85 name=name, 86 color=color, 87 is_inbox_tag=is_inbox_tag, 88 match=match, 89 matching_algorithm=matching_algorithm, 90 is_insensitive=is_insensitive, 91 parent=parent, 92 owner=owner, 93 set_permissions=set_permissions, 94 ) 95 ), 96 ) 97 98 def update( 99 self, 100 id: int, 101 *, 102 name: str | None | _Unset = UNSET, 103 color: str | None | _Unset = UNSET, 104 is_inbox_tag: bool | None | _Unset = UNSET, 105 match: str | None | _Unset = UNSET, 106 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 107 is_insensitive: bool | None | _Unset = UNSET, 108 parent: int | None | _Unset = UNSET, 109 owner: int | None | _Unset = UNSET, 110 set_permissions: SetPermissions | None | _Unset = UNSET, 111 ) -> Tag: 112 """Partially update a tag. 113 114 This is a sync wrapper for the async method with exactly the same parameters. 115 See: `easypaperless.TagsResource.update` 116 """ 117 return cast( 118 Tag, 119 self._run( 120 self._async_tags.update( 121 id, 122 name=name, 123 color=color, 124 is_inbox_tag=is_inbox_tag, 125 match=match, 126 matching_algorithm=matching_algorithm, 127 is_insensitive=is_insensitive, 128 parent=parent, 129 owner=owner, 130 set_permissions=set_permissions, 131 ) 132 ), 133 ) 134 135 def delete(self, id: int) -> None: 136 """Delete a tag. 137 138 This is a sync wrapper for the async method with exactly the same parameters. 139 See: `easypaperless.TagsResource.delete` 140 """ 141 self._run(self._async_tags.delete(id)) 142 143 def bulk_delete(self, ids: List[int]) -> None: 144 """Permanently delete multiple tags. 145 146 This is a sync wrapper for the async method with exactly the same parameters. 147 See: `easypaperless.TagsResource.bulk_delete` 148 """ 149 self._run(self._async_tags.bulk_delete(ids)) 150 151 def bulk_set_permissions( 152 self, 153 ids: List[int], 154 *, 155 set_permissions: SetPermissions | None = None, 156 owner: int | None = None, 157 merge: bool = False, 158 ) -> None: 159 """Set permissions and/or owner on multiple tags. 160 161 This is a sync wrapper for the async method with exactly the same parameters. 162 See: `easypaperless.TagsResource.bulk_set_permissions` 163 """ 164 self._run( 165 self._async_tags.bulk_set_permissions( 166 ids, set_permissions=set_permissions, owner=owner, merge=merge 167 ) 168 )
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 This is a sync wrapper for the async method with exactly the same parameters. 38 See: `easypaperless.TagsResource.list` 39 """ 40 return cast( 41 List[Tag], 42 self._run( 43 self._async_tags.list( 44 ids=ids, 45 name_contains=name_contains, 46 name_exact=name_exact, 47 page=page, 48 page_size=page_size, 49 ordering=ordering, 50 descending=descending, 51 ) 52 ), 53 )
Return tags defined in paperless-ngx.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.TagsResource.list
55 def get(self, id: int) -> Tag: 56 """Fetch a single tag by its ID. 57 58 This is a sync wrapper for the async method with exactly the same parameters. 59 See: `easypaperless.TagsResource.get` 60 """ 61 return cast(Tag, self._run(self._async_tags.get(id)))
Fetch a single tag by its ID.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.TagsResource.get
63 def create( 64 self, 65 *, 66 name: str, 67 color: str | None = None, 68 is_inbox_tag: bool | None = None, 69 match: str | None | _Unset = UNSET, 70 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 71 is_insensitive: bool = True, 72 parent: int | None | _Unset = UNSET, 73 owner: int | None | _Unset = UNSET, 74 set_permissions: SetPermissions | None = None, 75 ) -> Tag: 76 """Create a new tag. 77 78 This is a sync wrapper for the async method with exactly the same parameters. 79 See: `easypaperless.TagsResource.create` 80 """ 81 return cast( 82 Tag, 83 self._run( 84 self._async_tags.create( 85 name=name, 86 color=color, 87 is_inbox_tag=is_inbox_tag, 88 match=match, 89 matching_algorithm=matching_algorithm, 90 is_insensitive=is_insensitive, 91 parent=parent, 92 owner=owner, 93 set_permissions=set_permissions, 94 ) 95 ), 96 )
Create a new tag.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.TagsResource.create
98 def update( 99 self, 100 id: int, 101 *, 102 name: str | None | _Unset = UNSET, 103 color: str | None | _Unset = UNSET, 104 is_inbox_tag: bool | None | _Unset = UNSET, 105 match: str | None | _Unset = UNSET, 106 matching_algorithm: MatchingAlgorithm | None | _Unset = UNSET, 107 is_insensitive: bool | None | _Unset = UNSET, 108 parent: int | None | _Unset = UNSET, 109 owner: int | None | _Unset = UNSET, 110 set_permissions: SetPermissions | None | _Unset = UNSET, 111 ) -> Tag: 112 """Partially update a tag. 113 114 This is a sync wrapper for the async method with exactly the same parameters. 115 See: `easypaperless.TagsResource.update` 116 """ 117 return cast( 118 Tag, 119 self._run( 120 self._async_tags.update( 121 id, 122 name=name, 123 color=color, 124 is_inbox_tag=is_inbox_tag, 125 match=match, 126 matching_algorithm=matching_algorithm, 127 is_insensitive=is_insensitive, 128 parent=parent, 129 owner=owner, 130 set_permissions=set_permissions, 131 ) 132 ), 133 )
Partially update a tag.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.TagsResource.update
135 def delete(self, id: int) -> None: 136 """Delete a tag. 137 138 This is a sync wrapper for the async method with exactly the same parameters. 139 See: `easypaperless.TagsResource.delete` 140 """ 141 self._run(self._async_tags.delete(id))
Delete a tag.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.TagsResource.delete
143 def bulk_delete(self, ids: List[int]) -> None: 144 """Permanently delete multiple tags. 145 146 This is a sync wrapper for the async method with exactly the same parameters. 147 See: `easypaperless.TagsResource.bulk_delete` 148 """ 149 self._run(self._async_tags.bulk_delete(ids))
Permanently delete multiple tags.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.TagsResource.bulk_delete
151 def bulk_set_permissions( 152 self, 153 ids: List[int], 154 *, 155 set_permissions: SetPermissions | None = None, 156 owner: int | None = None, 157 merge: bool = False, 158 ) -> None: 159 """Set permissions and/or owner on multiple tags. 160 161 This is a sync wrapper for the async method with exactly the same parameters. 162 See: `easypaperless.TagsResource.bulk_set_permissions` 163 """ 164 self._run( 165 self._async_tags.bulk_set_permissions( 166 ids, set_permissions=set_permissions, owner=owner, merge=merge 167 ) 168 )
Set permissions and/or owner on multiple tags.
This is a sync wrapper for the async method with exactly the same parameters.
See: easypaperless.TagsResource.bulk_set_permissions