dspace-api-toolkit 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,211 @@
1
+ Metadata-Version: 2.4
2
+ Name: dspace-api-toolkit
3
+ Version: 0.1.1
4
+ Summary: Python toolkit for the DSpace 7+ and DSpace-CRIS REST API: items, submissions, bitstreams (streamed large uploads), access control, communities, collections, versioning
5
+ Author: Stefan Szepe
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/sszepe/dspace-api-toolkit
8
+ Project-URL: Documentation, https://github.com/sszepe/dspace-api-toolkit#readme
9
+ Project-URL: Changelog, https://github.com/sszepe/dspace-api-toolkit/blob/main/CHANGELOG.md
10
+ Project-URL: Issues, https://github.com/sszepe/dspace-api-toolkit/issues
11
+ Project-URL: Compatibility matrix, https://github.com/sszepe/dspace-api-toolkit/actions/workflows/integration-matrix.yml
12
+ Keywords: dspace,dspace-cris,repository,rest-api,institutional-repository,open-access
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Intended Audience :: System Administrators
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Topic :: Internet :: WWW/HTTP
26
+ Classifier: Topic :: Scientific/Engineering
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Requires-Python: >=3.10
29
+ Description-Content-Type: text/markdown
30
+ License-File: LICENSE
31
+ Requires-Dist: requests>=2.31
32
+ Requires-Dist: python-dotenv>=1.0
33
+ Provides-Extra: test
34
+ Requires-Dist: pytest>=7.4; extra == "test"
35
+ Requires-Dist: pytest-cov>=4.1; extra == "test"
36
+ Requires-Dist: responses>=0.23; extra == "test"
37
+ Provides-Extra: integration
38
+ Requires-Dist: pytest>=7.4; extra == "integration"
39
+ Requires-Dist: responses>=0.23; extra == "integration"
40
+ Requires-Dist: pyyaml>=6.0; extra == "integration"
41
+ Provides-Extra: dev
42
+ Requires-Dist: dspace-api-toolkit[integration,test]; extra == "dev"
43
+ Requires-Dist: build>=1.2; extra == "dev"
44
+ Requires-Dist: twine>=5.1; extra == "dev"
45
+ Dynamic: license-file
46
+
47
+ # dspace-api-toolkit
48
+
49
+ [![CI](https://github.com/sszepe/dspace-api-toolkit/actions/workflows/ci.yml/badge.svg)](https://github.com/sszepe/dspace-api-toolkit/actions/workflows/ci.yml)
50
+ [![Compatibility matrix](https://github.com/sszepe/dspace-api-toolkit/actions/workflows/integration-matrix.yml/badge.svg)](https://github.com/sszepe/dspace-api-toolkit/actions/workflows/integration-matrix.yml)
51
+ [![PyPI](https://img.shields.io/pypi/v/dspace-api-toolkit.svg)](https://pypi.org/project/dspace-api-toolkit/)
52
+ [![Python](https://img.shields.io/pypi/pyversions/dspace-api-toolkit.svg)](https://pypi.org/project/dspace-api-toolkit/)
53
+ [![License](https://img.shields.io/pypi/l/dspace-api-toolkit.svg)](LICENSE)
54
+
55
+ A Python toolkit for the REST API of **DSpace 7+** and **DSpace-CRIS**, built
56
+ for repository administrators and integration scripts: batch imports,
57
+ submissions, files of any size, access control, collection setup, versioning -
58
+ and long unattended runs that survive token expiry, rate limits and restarts.
59
+
60
+ Every feature is tested against mocked HTTP with pytest with a target
61
+ 100% coverage **and** against real DSpace / DSpace-CRIS installations started
62
+ with Docker Compose; the results form a [compatibility matrix](#compatibility).
63
+
64
+ ```bash
65
+ pip install dspace-api-toolkit
66
+ ```
67
+
68
+ Requires Python 3.10+. The import name of the dspace-api-toolkit in python code
69
+ using it is `dspace_api`.
70
+
71
+ ## Quick start
72
+
73
+ ```python
74
+ from dspace_api import DSpaceClient, MetadataPatch
75
+
76
+ client = DSpaceClient("https://repo.example.org/server/api", "admin@example.org", "secret")
77
+
78
+ # Submit an item through the submission process, with an embargoed file
79
+ result = client.workspace.submit(
80
+ collection_uuid,
81
+ {"dc.title": "My thesis", "dc.contributor.author": ["Doe, Jane"], "dc.date.issued": "2026"},
82
+ files=["thesis.pdf"],
83
+ file_access_conditions=[{"name": "embargo", "startDate": "2027-01-01"}],
84
+ )
85
+ item_uuid = result["item_uuid"]
86
+
87
+ # Upload a large file - streamed, constant memory, MD5 verified
88
+ bundle = client.bundles.get_or_create_bundle(item_uuid, "ORIGINAL")
89
+ client.bundles.upload_bitstream(bundle["uuid"], "dataset.zip",
90
+ progress=lambda done, total: print(f"{done / total:.0%}"))
91
+
92
+ # Precise metadata edits
93
+ client.metadata.patch_metadata("item", item_uuid,
94
+ MetadataPatch().append("dc.subject", "music").move("dc.contributor.author", 1, 0))
95
+
96
+ # Check permissions before acting
97
+ if client.authorizations.can(("item", item_uuid), "withdrawItem"):
98
+ ...
99
+
100
+ client.close()
101
+ ```
102
+
103
+ More scripts will be added in the [`examples/`](examples/) folder.
104
+
105
+ ## What's covered
106
+
107
+ | Area | Manager | Highlights |
108
+ |---|---|---|
109
+ | Items | `client.items` | create, read, update, delete; `upsert_metadata`, position-aware upserts, move, mapped collections |
110
+ | Metadata | `client.metadata` | `MetadataPatch` builder (archived items, submission sections, files), PATCH any object, schema/field registry, `ensure_fields()` |
111
+ | Submissions | `client.workspace` | create (empty / external source / BibTeX-RIS file), fill forms by field, upload, file & item access conditions, license, CC license, deposit, one-call `submit()` with validation errors |
112
+ | Bundles & files | `client.bundles` | bundles, streamed uploads of any size, replace, download, primary bitstream, move, format registry |
113
+ | Access control | `client.permissions` | resource policies, remove / grant / restore group access with CSV reports, bulk access control script |
114
+ | Permission checks | `client.authorizations` | `can`, `features_on`, `require`, batch checks, admin scope |
115
+ | Versioning | `client.versions` | create versions, `new_version()` flow, histories, drafts |
116
+ | Communities | `client.communities` | create, hierarchy and tree walk, admin group, logo, *Authorized searches |
117
+ | Collections | `client.collections` | role groups (admin, submitters, item/bitstream read, workflow), read restrictions, submission policies, license, item template, mapped items, harvesting, logo |
118
+ | People & groups | `client.epersons`, `client.groups` | users, registration, end-user agreement, groups and members |
119
+ | Site & config | `client.site`, `client.entity_types` | Terms of Use per language, entity types |
120
+ | Search & browse | `client.discovery` | search configuration, `f.<filter>` filters, paged `iter_search`, `count`, facets with all values (`facet_counts`), browse indexes, entries and items |
121
+ | Review workflow | `client.workflow` | workflow items, `pending_tasks`, claim / approve / reject / unclaim, `review()` in one call, `approve_all_steps`, workflow definitions, steps and actions, supervision orders |
122
+ | Relationships | `client.relationships` | configurable entities (plain DSpace): relationship types, `relate` / `unrelate` by label, `related_items` in order, `reorder`, name variants, `ensure_related` |
123
+ | Vocabularies | `client.vocabulary` | vocabularies and authorities, exact `lookup`, `invalid_values` for import validation, form-field vocabularies, hierarchical trees, `to_metadata_value` |
124
+
125
+ Every read accepts `all_languages=`, `projection=` and `embed=` (including
126
+ nested embeds with sizes) to shape the response.
127
+
128
+ ## Configuration
129
+
130
+ Arguments win over environment variables, which win over a `.env` file in the
131
+ working directory (see [`.env.example`](.env.example)):
132
+
133
+ | Variable | Default | |
134
+ |---|---|---|
135
+ | `DSPACE_URL` | `http://localhost:8080/server/api` | REST API root |
136
+ | `DSPACE_TIMEOUT` | `30` | seconds per request |
137
+ | `DSPACE_MAX_RETRIES` | `3` | retries for 429 / 502 / 503 / 504 and connection errors (idempotent requests; 429 for all) |
138
+ | `DSPACE_RETRY_BACKOFF`, `DSPACE_RETRY_MAX_WAIT` | `1.0`, `30` | exponential backoff with jitter, honours `Retry-After` |
139
+ | `DSPACE_TOKEN_REFRESH_MARGIN` | `60` | refresh the login token this many seconds before it expires |
140
+ | `DSPACE_REAUTHENTICATE` | `true` | log in again after a 401 |
141
+ | `DSPACE_ACCEPT_USER_AGREEMENT` | `false` | DSpace-CRIS: accept the end-user agreement for the logged-in user when the server demands it |
142
+ | `DSPACE_ALL_LANGUAGES` | `false` | default for `projection=allLanguages` (DSpace-CRIS, DSpace 10; left out automatically on DSpace 8/9) |
143
+
144
+ `DSpaceConfig(env_file=False)` ignores `.env`; `env_file="prod.env"` reads another file.
145
+
146
+ ## Large files
147
+
148
+ Uploads (`upload_bitstream`, `replace_bitstream`, `workspace.upload_file`)
149
+ stream the multipart body from disk with an exact `Content-Length`: memory
150
+ use stays at one chunk (8 MiB) regardless of file size, the MD5 is computed
151
+ while sending and compared with DSpace's checksum afterwards, and the read
152
+ timeout grows with the file size. The server must allow large requests too:
153
+
154
+ - DSpace `config/application.properties`: `spring.servlet.multipart.max-file-size`
155
+ and `max-request-size` (default 512MB)
156
+ - reverse proxy: nginx `client_max_body_size`, `proxy_request_buffering off`, `proxy_read_timeout`
157
+ - Tomcat connector timeout
158
+
159
+ ## Compatibility
160
+
161
+ The integration suite runs against these Docker Compose stacks (upstream
162
+ compose files of each branch):
163
+
164
+ | Target | |
165
+ |---|---|
166
+ | DSpace 8.x, 9.x, 10.x | `dspace/dspace` images |
167
+ | DSpace-CRIS 2024.02, 2025.02 | `4science/dspace-cris` images |
168
+
169
+ You can run the same suite against your own **test** installation, from a
170
+ clone of the repository:
171
+
172
+ ```bash
173
+ git clone https://github.com/sszepe/dspace-api-toolkit && cd dspace-api-toolkit
174
+ pip install -e ".[integration]"
175
+ DSPACE_IT_PASSWORD=... python -m integration.run_matrix --existing \
176
+ --url https://dspace-test.example.org/server/api --user admin@example.org --name my-test-server
177
+ ```
178
+
179
+ The integration tests require an administrator account. They create and delete test
180
+ data.
181
+
182
+ WARNING: never point the integration matrix to a production instancce!
183
+
184
+ ## Development
185
+
186
+ ```bash
187
+ git clone https://github.com/sszepe/dspace-api-toolkit && cd dspace-api-toolkit
188
+ python -m venv .venv && . .venv/bin/activate
189
+ pip install -e ".[dev]"
190
+ pytest # unit tests, 100% coverage gate
191
+ python -m integration.run_matrix -t dspace-9 # regression tests against a Docker stack
192
+ ```
193
+
194
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the regression test workflow and
195
+ [integration/README.md](integration/README.md) for the matrix details.
196
+
197
+ ## Related projects
198
+
199
+ - [dspace-rest-client](https://pypi.org/project/dspace-rest-client/) - the
200
+ DSpace community's general-purpose Python client.
201
+
202
+ We are very grateful to the team behind dspace-rest-client. Their work inspired this
203
+ project, and we learned a great deal from their approach and implementation. As our
204
+ requirements and goals evolved, we eventually reached a point where we needed to take
205
+ a different direction and develop our own solution. We sincerely appreciate the
206
+ foundation they provided and the work they continue to contribute to the DSpace
207
+ community.
208
+
209
+ ## License
210
+
211
+ BSD 3-Clause, see [LICENSE](LICENSE).
@@ -0,0 +1,32 @@
1
+ dspace_api/__init__.py,sha256=hQ2NozrMopwqhO8qCy0hEA-sqvFfe_Y3t9BS8ZO-L3c,3162
2
+ dspace_api/_base.py,sha256=XbxAQamgpE5OCpczSh1_w6MIECKBBQTaPrZ4gixEPzU,17817
3
+ dspace_api/_containers.py,sha256=M_Wey1_9TfOtz-xFt9lgSOsNHd_jy1-BgTH0ig4_91k,9455
4
+ dspace_api/_version.py,sha256=SQ28QZrV0H9EAMO0c5auOMcGNbDOqDFVROu23L9M5YY,141
5
+ dspace_api/auth.py,sha256=OnfcakZYqTyHWmq2Wrmy4xhwAl6P9_yq4u5BhLyrexk,16946
6
+ dspace_api/authorizations.py,sha256=FCllHqNGpe1PtuL0vy-CSmy5KDLQVjXaYI4H-JZ-_CU,21637
7
+ dspace_api/bundles.py,sha256=sIqC2OkWkhqZZiZJHDCVGumLSEYLMTkP_EG61ZDs-2g,53024
8
+ dspace_api/collections.py,sha256=6Eg1an772tBrHEOkoHjjAg8yfEUIDlYcJQEQ7Tv2PqE,47200
9
+ dspace_api/communities.py,sha256=efx4_8n06JxuuJHIpBwr-ftAZS_Hb_Mx-vQItTgncBI,16568
10
+ dspace_api/config.py,sha256=TaE5RwptaY1noxBOLeAcnLG0OufZ5OCnSSahDITZE5g,9805
11
+ dspace_api/discovery.py,sha256=xUWnGQzr4SJHhKubhOvINk1M7LaGmDa_VXxkEszdJZk,43071
12
+ dspace_api/entity_types.py,sha256=7AwR9wpgb7ahe5sXcHlLkrvdijMoJLk_-AtIag0AGuA,5717
13
+ dspace_api/epersons.py,sha256=WysnatG4MMa9MCaFbMdtmhVM_WbSV2boYot9W_VIMAQ,31193
14
+ dspace_api/exceptions.py,sha256=sMCO32aedUlA9CDly3zUkifj6iHGa3Q-nLMmecNOSOc,3613
15
+ dspace_api/groups.py,sha256=_hYHeNlTUxhbb6Wamh5gBdZ5vHLjK2zFnF9nFO-bkV8,28597
16
+ dspace_api/items.py,sha256=QADNE8pQle_iMAAq2aigwHWToDCcoOiPmO3kHfHOWJ4,20407
17
+ dspace_api/metadata.py,sha256=YYUM902tYsQGH92TfuaDKgUvC6CyH3Ca6vEVESYobpY,32164
18
+ dspace_api/permissions.py,sha256=6IHCCicOhWe6_5gBJ4LvzbttWkRxuW0EP7MdWu3o2ZY,50569
19
+ dspace_api/projection.py,sha256=KIhrO5RDib4Cjp6WbZ0gqXwC-TGhPbCmkDbsRFrZlr4,11570
20
+ dspace_api/relationships.py,sha256=wwAwP2I2HrExXny-KzYyVWmdZYNyYOBPnmQbZnHsPsA,34087
21
+ dspace_api/session.py,sha256=8pkbrk00sPTOPaELHCTfgAGdtmkJrn_MNWkRIqWSdck,22845
22
+ dspace_api/site.py,sha256=cxsSGHS43AP0Ofr4tdaItcD3076Kscm4q9hrK7fL_ss,4014
23
+ dspace_api/utils.py,sha256=SLcvNrX2zKG91kQhl8LBWMBHlbH7I8Pyf6f83H7B_3A,14747
24
+ dspace_api/versions.py,sha256=W8m0LBjjTWth93huPcfY7usbWIMAsTO-2jgbcL-xDMA,12504
25
+ dspace_api/vocabulary.py,sha256=NyjiUgZXP6uLTqz7Wh2YHjrvbotrJhWcN67ZfLzHqj8,15545
26
+ dspace_api/workflow.py,sha256=QzNm-GKR8VpKUzlwZkNl90tINekZeQtrjtmkjvLmLjs,37398
27
+ dspace_api/workspaces.py,sha256=V1ffWNEC7ruVousgeJrWcmmUp5x-J7BtNPJSNT7bVwM,61538
28
+ dspace_api_toolkit-0.1.1.dist-info/licenses/LICENSE,sha256=cGdr2cpxWWiTzXPtXKHgjt4taK_Sa5q_5IqKo6HZA7Q,1516
29
+ dspace_api_toolkit-0.1.1.dist-info/METADATA,sha256=Ic2llT6RpxEon8GLJTvMm-JLi1g1hRYcejO1x6khQ5Y,11078
30
+ dspace_api_toolkit-0.1.1.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
31
+ dspace_api_toolkit-0.1.1.dist-info/top_level.txt,sha256=3r1x-M8dFCKtGBoM3xmO51XqD7bUQHh2ezP-GBh1Q04,11
32
+ dspace_api_toolkit-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Stefan Szepe and contributors
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ dspace_api