invenio-pidstore-extra 0.2.0__tar.gz
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.
- invenio_pidstore_extra-0.2.0/.gitignore +65 -0
- invenio_pidstore_extra-0.2.0/.gitlab-ci.yml +4 -0
- invenio_pidstore_extra-0.2.0/AUTHORS.rst +13 -0
- invenio_pidstore_extra-0.2.0/CHANGES.rst +19 -0
- invenio_pidstore_extra-0.2.0/CONTRIBUTING.rst +8 -0
- invenio_pidstore_extra-0.2.0/INSTALL.rst +8 -0
- invenio_pidstore_extra-0.2.0/LICENSE +21 -0
- invenio_pidstore_extra-0.2.0/MANIFEST.in +25 -0
- invenio_pidstore_extra-0.2.0/PKG-INFO +32 -0
- invenio_pidstore_extra-0.2.0/README.rst +75 -0
- invenio_pidstore_extra-0.2.0/babel.ini +24 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/__init__.py +15 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/config.py +30 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/dnb-sandbox.py +204 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/ext.py +32 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/providers/__init__.py +14 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/providers/dnb.py +208 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/providers/urn/__init__.py +14 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/providers/urn/errors.py +75 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/providers/urn/request.py +118 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/providers/urn/rest.py +196 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/services/__init__.py +9 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/services/components/__init__.py +13 -0
- invenio_pidstore_extra-0.2.0/invenio_pidstore_extra/services/components/pids.py +121 -0
- invenio_pidstore_extra-0.2.0/pyproject.toml +144 -0
- invenio_pidstore_extra-0.2.0/run-tests.sh +28 -0
- invenio_pidstore_extra-0.2.0/tests/conftest.py +79 -0
- invenio_pidstore_extra-0.2.0/tests/test_invenio_pidstore_extra.py +33 -0
- invenio_pidstore_extra-0.2.0/tests/test_provider_rest.py +131 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
|
|
5
|
+
# Idea software family
|
|
6
|
+
.idea/
|
|
7
|
+
|
|
8
|
+
# C extensions
|
|
9
|
+
*.so
|
|
10
|
+
|
|
11
|
+
# Distribution / packaging
|
|
12
|
+
.Python
|
|
13
|
+
env/
|
|
14
|
+
build/
|
|
15
|
+
develop-eggs/
|
|
16
|
+
dist/
|
|
17
|
+
downloads/
|
|
18
|
+
eggs/
|
|
19
|
+
.eggs/
|
|
20
|
+
lib/
|
|
21
|
+
lib64/
|
|
22
|
+
parts/
|
|
23
|
+
sdist/
|
|
24
|
+
var/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
Pipfile
|
|
29
|
+
Pipfile.lock
|
|
30
|
+
uv.lock
|
|
31
|
+
|
|
32
|
+
# PyInstaller
|
|
33
|
+
# Usually these files are written by a python script from a template
|
|
34
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
35
|
+
*.manifest
|
|
36
|
+
*.spec
|
|
37
|
+
|
|
38
|
+
# Installer logs
|
|
39
|
+
pip-log.txt
|
|
40
|
+
pip-delete-this-directory.txt
|
|
41
|
+
|
|
42
|
+
# Unit test / coverage reports
|
|
43
|
+
htmlcov/
|
|
44
|
+
.tox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*,cover
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
|
|
55
|
+
# Django stuff:
|
|
56
|
+
*.log
|
|
57
|
+
|
|
58
|
+
# Sphinx documentation
|
|
59
|
+
docs/_build/
|
|
60
|
+
|
|
61
|
+
# PyBuilder
|
|
62
|
+
target/
|
|
63
|
+
|
|
64
|
+
# Vim swapfiles
|
|
65
|
+
.*.sw?
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
..
|
|
2
|
+
Copyright (C) 2025 University of Münster.
|
|
3
|
+
|
|
4
|
+
invenio-pidstore-extra is free software; you can redistribute it and/or
|
|
5
|
+
modify it under the terms of the MIT License; see LICENSE file for more
|
|
6
|
+
details.
|
|
7
|
+
|
|
8
|
+
Authors
|
|
9
|
+
=======
|
|
10
|
+
|
|
11
|
+
Module that adds URN minting by DNB epicur service
|
|
12
|
+
|
|
13
|
+
- University of Münster <forschungsdaten@uni-muenster.de>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
..
|
|
2
|
+
Copyright (C) 2024-2025 University of Münster.
|
|
3
|
+
|
|
4
|
+
invenio-urn-provider is free software; you can redistribute it and/or
|
|
5
|
+
modify it under the terms of the MIT License; see LICENSE file for more
|
|
6
|
+
details.
|
|
7
|
+
|
|
8
|
+
Changes
|
|
9
|
+
=======
|
|
10
|
+
|
|
11
|
+
Version 0.2.0
|
|
12
|
+
|
|
13
|
+
- fully integrated the rest wrapper to DNB urn service
|
|
14
|
+
- adapted to InvenioRDM v13
|
|
15
|
+
- added a new component to set a successor of an URN if a new version has been published
|
|
16
|
+
|
|
17
|
+
Version 0.1.0 (released TBD)
|
|
18
|
+
|
|
19
|
+
- Initial public release.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (C) 2024 University of Münster.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
7
|
+
the Software without restriction, including without limitation the rights to
|
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
9
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
10
|
+
so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2024-2025 University of Münster.
|
|
4
|
+
#
|
|
5
|
+
# invenio-urn-provider is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
# TODO: Generate this manifest file by running the following commands:
|
|
10
|
+
# (please sort the lines in this file after running below commands)
|
|
11
|
+
#
|
|
12
|
+
# git init
|
|
13
|
+
# git add -A
|
|
14
|
+
# pip install -e .[all]
|
|
15
|
+
# check-manifest -u
|
|
16
|
+
|
|
17
|
+
# added by check-manifest
|
|
18
|
+
include *.in
|
|
19
|
+
include *.rst
|
|
20
|
+
include *.sh
|
|
21
|
+
include *.txt
|
|
22
|
+
include *.yml
|
|
23
|
+
include babel.ini
|
|
24
|
+
recursive-include tests *.ini
|
|
25
|
+
recursive-include tests *.py
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: invenio_pidstore_extra
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Dynamic: Description
|
|
5
|
+
Dynamic: Description-Content-Type
|
|
6
|
+
Summary: Module that adds URN minting by DNB epicur service.
|
|
7
|
+
Project-URL: Homepage, https://github.com/ulbmuenster/invenio-pidstore-extra
|
|
8
|
+
Author-email: University of Münster <forschungsdaten@uni-muenster.de>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: dnb,invenio,rdm,urn
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Requires-Dist: arrow>=1.3.0
|
|
15
|
+
Requires-Dist: flask>=3.1.0
|
|
16
|
+
Requires-Dist: idutils>=1.4.2
|
|
17
|
+
Requires-Dist: invenio-pidstore>=2.0.0
|
|
18
|
+
Requires-Dist: invenio-rdm-records>=17.0.2
|
|
19
|
+
Requires-Dist: invenio-search>=3.0.0
|
|
20
|
+
Requires-Dist: opensearch-dsl>=2.1.0
|
|
21
|
+
Provides-Extra: tests
|
|
22
|
+
Requires-Dist: check-manifest; extra == 'tests'
|
|
23
|
+
Requires-Dist: invenio-app>=2.1.0; extra == 'tests'
|
|
24
|
+
Requires-Dist: pytest-black-ng>=0.4.0; extra == 'tests'
|
|
25
|
+
Requires-Dist: pytest-cov==6.1.1; extra == 'tests'
|
|
26
|
+
Requires-Dist: pytest-docstyle==2.0.1; extra == 'tests'
|
|
27
|
+
Requires-Dist: pytest-env==1.1.5; extra == 'tests'
|
|
28
|
+
Requires-Dist: pytest-invenio>=3.3.0; extra == 'tests'
|
|
29
|
+
Requires-Dist: pytest-isort==4.0.0; extra == 'tests'
|
|
30
|
+
Requires-Dist: pytest-mock>=3.12.0; extra == 'tests'
|
|
31
|
+
Requires-Dist: pytest==8.3.5; extra == 'tests'
|
|
32
|
+
Requires-Dist: sphinx>=4.5.0; extra == 'tests'
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
..
|
|
2
|
+
Copyright (C) 2024-2025 University of Münster.
|
|
3
|
+
|
|
4
|
+
invenio-pidstore-extra is free software; you can redistribute it and/or
|
|
5
|
+
modify it under the terms of the MIT License; see LICENSE file for more
|
|
6
|
+
details.
|
|
7
|
+
|
|
8
|
+
=======================
|
|
9
|
+
invenio-pidstore-extra
|
|
10
|
+
=======================
|
|
11
|
+
|
|
12
|
+
Module that adds URN minting by DNB epicur service.
|
|
13
|
+
|
|
14
|
+
InvenioRDM supports DOI minting with Datacite out of the box. This module adds support for URN minting by using the
|
|
15
|
+
URN API published by German National Library (DNB).
|
|
16
|
+
|
|
17
|
+
Configuration
|
|
18
|
+
=============
|
|
19
|
+
|
|
20
|
+
After adding the module to your InvenioRDM instance you need to add the following snippet to your `invenio.cfg`.
|
|
21
|
+
Make sure you have registered at the DNB and set the config variables below to the correct values!
|
|
22
|
+
|
|
23
|
+
When putting this to production, set `PIDSTORE_EXTRA_TEST_MODE = False`!
|
|
24
|
+
|
|
25
|
+
.. code-block:: python
|
|
26
|
+
|
|
27
|
+
PIDSTORE_EXTRA_DNB_SANDBOX_URI = "http://127.0.0.1:8000/"
|
|
28
|
+
|
|
29
|
+
PIDSTORE_EXTRA_DNB_ENABLED = True
|
|
30
|
+
PIDSTORE_EXTRA_DNB_USERNAME = "username"
|
|
31
|
+
PIDSTORE_EXTRA_DNB_PASSWORD = "password"
|
|
32
|
+
PIDSTORE_EXTRA_DNB_ID_PREFIX = "urn:nbn:de:hbz:6"
|
|
33
|
+
PIDSTORE_EXTRA_FORMAT = "{prefix}-{id}"
|
|
34
|
+
PIDSTORE_EXTRA_TEST_MODE = True
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# Persistent identifiers configuration
|
|
38
|
+
#
|
|
39
|
+
from invenio_rdm_records.config import RDM_PERSISTENT_IDENTIFIER_PROVIDERS as DEFAULT_PERSISTENT_IDENTIFIER_PROVIDERS
|
|
40
|
+
from invenio_pidstore_extra import providers
|
|
41
|
+
|
|
42
|
+
RDM_PERSISTENT_IDENTIFIER_PROVIDERS = DEFAULT_PERSISTENT_IDENTIFIER_PROVIDERS + [
|
|
43
|
+
providers.DnbUrnProvider(
|
|
44
|
+
"urn",
|
|
45
|
+
client=providers.DNBUrnClient("dnb", PIDSTORE_EXTRA_DNB_ID_PREFIX, PIDSTORE_EXTRA_DNB_USERNAME, PIDSTORE_EXTRA_DNB_PASSWORD, PIDSTORE_EXTRA_FORMAT),
|
|
46
|
+
label=_("URN"),
|
|
47
|
+
),
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
from invenio_rdm_records.config import RDM_PERSISTENT_IDENTIFIERS as DEFAULT_PERSISTENT_IDENTIFIERS
|
|
51
|
+
|
|
52
|
+
RDM_PERSISTENT_IDENTIFIERS = {
|
|
53
|
+
**DEFAULT_PERSISTENT_IDENTIFIERS,
|
|
54
|
+
"urn": {
|
|
55
|
+
"providers": ["urn"],
|
|
56
|
+
"required": True,
|
|
57
|
+
"label": _("URN"),
|
|
58
|
+
"is_enabled": providers.DnbUrnProvider.is_enabled,
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
from invenio_pidstore_extra.services.components import URNRelationsComponent
|
|
63
|
+
from invenio_rdm_records.services.components import DefaultRecordsComponents
|
|
64
|
+
|
|
65
|
+
RDM_RECORDS_SERVICE_COMPONENTS = DefaultRecordsComponents + [URNRelationsComponent]
|
|
66
|
+
|
|
67
|
+
Development
|
|
68
|
+
===========
|
|
69
|
+
|
|
70
|
+
The flask app `invenio_pidstore_extra.dnb-sandbox.py` contains a very simple implementation of the DNB api to allow testing the URN support when the DNB sandbox is not available or just no user has been provided. You can start it with calling
|
|
71
|
+
|
|
72
|
+
.. code-block:: console
|
|
73
|
+
|
|
74
|
+
flask --app invenio_pidstore_extra.dnb-sandbox run --port=8000
|
|
75
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 University of Münster.
|
|
4
|
+
#
|
|
5
|
+
# invenio-pidstore-extra is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
# Extraction from Python source files
|
|
10
|
+
|
|
11
|
+
[python: **.py]
|
|
12
|
+
encoding = utf-8
|
|
13
|
+
|
|
14
|
+
# Extraction from Jinja2 templates
|
|
15
|
+
|
|
16
|
+
[jinja2: **/templates/**.html]
|
|
17
|
+
encoding = utf-8
|
|
18
|
+
extensions = jinja2.ext.autoescape, jinja2.ext.with_
|
|
19
|
+
|
|
20
|
+
# Extraction from JavaScript files
|
|
21
|
+
|
|
22
|
+
[javascript: **.js]
|
|
23
|
+
encoding = utf-8
|
|
24
|
+
extract_messages = $._, jQuery._
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 University of Münster.
|
|
4
|
+
#
|
|
5
|
+
# invenio-pidstore-extra is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
"""Module that adds URN minting by DNB epicur service."""
|
|
10
|
+
|
|
11
|
+
from .ext import InvenioUrnProvider
|
|
12
|
+
|
|
13
|
+
__version__ = "0.2.0"
|
|
14
|
+
|
|
15
|
+
__all__ = ("__version__", "InvenioUrnProvider")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 University of Münster.
|
|
4
|
+
#
|
|
5
|
+
# invenio-pidstore-extra is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
"""Module that adds URN minting by DNB epicur service."""
|
|
10
|
+
|
|
11
|
+
PIDSTORE_EXTRA_DNB_ENABLED = True
|
|
12
|
+
"""The URN provider is by default enabled (or why would you have installed the module?)."""
|
|
13
|
+
|
|
14
|
+
PIDSTORE_EXTRA_TEST_MODE = True
|
|
15
|
+
"""Set to 'False' if you want to mint real URN's."""
|
|
16
|
+
|
|
17
|
+
PIDSTORE_EXTRA_DNB_USERNAME = "username"
|
|
18
|
+
"""A username provided for you by DNB if you have a legal contract."""
|
|
19
|
+
|
|
20
|
+
PIDSTORE_EXTRA_DNB_PASSWORD = "password"
|
|
21
|
+
"""The corresponding password."""
|
|
22
|
+
|
|
23
|
+
PIDSTORE_EXTRA_DNB_ID_PREFIX = "urn:nbn:dnb:provider:"
|
|
24
|
+
"""Just an example! Please replace by prefix provided by DNB."""
|
|
25
|
+
|
|
26
|
+
PIDSTORE_EXTRA_DNB_SANDBOX_URI = "https://api.nbn-resolving.org/sandbox/v2/"
|
|
27
|
+
"""In case the sandbox is not available this setting allows configuration of a different URI."""
|
|
28
|
+
|
|
29
|
+
PIDSTORE_EXTRA_FORMAT = "{prefix}-{id}"
|
|
30
|
+
"""The format of the URN."""
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 University of Münster.
|
|
4
|
+
#
|
|
5
|
+
# invenio-pidstore-extra is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
"""Simple implementation of DNB URN API."""
|
|
10
|
+
|
|
11
|
+
import base64
|
|
12
|
+
import random
|
|
13
|
+
|
|
14
|
+
import arrow
|
|
15
|
+
from flask import Flask, jsonify, request
|
|
16
|
+
|
|
17
|
+
app = Flask(__name__)
|
|
18
|
+
namespace = "urn:nbn:de:hbz:6-"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@app.route("/namespaces/name/<name>", methods=["GET"])
|
|
22
|
+
def namespace_info(name: str):
|
|
23
|
+
"""Implementation of namespaces API."""
|
|
24
|
+
now = arrow.utcnow().isoformat()
|
|
25
|
+
return jsonify(
|
|
26
|
+
{
|
|
27
|
+
"name": name,
|
|
28
|
+
"created": now,
|
|
29
|
+
"lastModified": now,
|
|
30
|
+
"allowsRegistration": True,
|
|
31
|
+
"owner": "http://localhost:8000/organisations/id/1",
|
|
32
|
+
"urnNamingPolicy": "http://localhost:8000/policies/urn-naming/id/no-check",
|
|
33
|
+
"urlPolicy": "http://localhost:8000/policies/url/id/no-check",
|
|
34
|
+
"resolverUrl": "",
|
|
35
|
+
"urns": request.url + "/urns",
|
|
36
|
+
"urnSuggestion": request.url + "/urn-suggestion",
|
|
37
|
+
"self": request.url,
|
|
38
|
+
}
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@app.route("/namespaces/name/<name>/urn-suggestion", methods=["GET"])
|
|
43
|
+
def suggest(name: str):
|
|
44
|
+
"""Implementation of suggest API."""
|
|
45
|
+
return jsonify(
|
|
46
|
+
{
|
|
47
|
+
"suggestedUrn": name + str(random.randrange(1000000000, 9999999999, 1)),
|
|
48
|
+
"namespace": request.url[: request.url.find("/urn-suggestion")],
|
|
49
|
+
"self": request.url,
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@app.route("/urns", methods=["POST"])
|
|
55
|
+
def register():
|
|
56
|
+
"""Implementation of URN registration API."""
|
|
57
|
+
now = arrow.utcnow().isoformat()
|
|
58
|
+
content = request.json
|
|
59
|
+
return (
|
|
60
|
+
jsonify(
|
|
61
|
+
{
|
|
62
|
+
"urn": content["urn"],
|
|
63
|
+
"created": now,
|
|
64
|
+
"lastModified": now,
|
|
65
|
+
"namespace": "http://localhost:8000/namespaces/name/" + namespace,
|
|
66
|
+
"successor": None,
|
|
67
|
+
"urls": request.url + "/urn/" + content["urn"] + "/urls",
|
|
68
|
+
"myUrls": request.url + "/urn/" + content["urn"] + "/my-urls",
|
|
69
|
+
"self": request.url + "/urn/" + content["urn"],
|
|
70
|
+
}
|
|
71
|
+
),
|
|
72
|
+
201,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@app.route("/urns/urn/<urn>", methods=["HEAD"])
|
|
77
|
+
def check_existence(urn: str):
|
|
78
|
+
"""Implementation of check for existence API."""
|
|
79
|
+
if urn.startswith(namespace):
|
|
80
|
+
suffix = urn[len(namespace) :]
|
|
81
|
+
if int(suffix) < 5000000000:
|
|
82
|
+
return "", 200
|
|
83
|
+
return "", 404
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@app.route("/urns/urn/<urn>", methods=["GET"])
|
|
87
|
+
def get_urn(urn: str):
|
|
88
|
+
"""Implementation of get URN API."""
|
|
89
|
+
if urn.startswith(namespace):
|
|
90
|
+
suffix = urn[len(namespace) :]
|
|
91
|
+
if int(suffix) < 5000000000:
|
|
92
|
+
now = arrow.utcnow().isoformat()
|
|
93
|
+
return jsonify(
|
|
94
|
+
{
|
|
95
|
+
"urn": urn,
|
|
96
|
+
"created": now,
|
|
97
|
+
"lastModified": now,
|
|
98
|
+
"namespace": "http://localhost:8000/namespaces/name/" + namespace,
|
|
99
|
+
"successor": None,
|
|
100
|
+
"urls": request.url + "/urls",
|
|
101
|
+
"myUrls": request.url + "/my-urls",
|
|
102
|
+
"self": request.url,
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
return "", 404
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@app.route("/urns/urn/<urn>/urls", methods=["GET"])
|
|
109
|
+
def get_url(urn: str):
|
|
110
|
+
"""Implementation of get URL API."""
|
|
111
|
+
return get_urls(urn, "/urls")
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@app.route("/urns/urn/<urn>/my-urls", methods=["GET"])
|
|
115
|
+
def get_my_url(urn: str):
|
|
116
|
+
"""Implementation of get my URL API."""
|
|
117
|
+
return get_urls(urn, "/my-urls")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@app.route("/urns/urn/<urn>/urls/base64/<encoded>", methods=["GET"])
|
|
121
|
+
def get_single_url(urn: str, encoded: str):
|
|
122
|
+
"""Implementation of get single URL API."""
|
|
123
|
+
now = arrow.utcnow().isoformat()
|
|
124
|
+
return jsonify(
|
|
125
|
+
{
|
|
126
|
+
"url": base64.b64decode(bytes(encoded, "utf-8")).decode("utf-8"),
|
|
127
|
+
"created": now,
|
|
128
|
+
"lastModified": now,
|
|
129
|
+
"urn": request.url[: request.url.find("/urls")],
|
|
130
|
+
"owner": "http://localhost:8000/organisations/id/1",
|
|
131
|
+
"priority": 10,
|
|
132
|
+
"self": request.url,
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@app.route("/urns/urn/<urn>/urls", methods=["POST"])
|
|
138
|
+
def add_url(urn: str):
|
|
139
|
+
"""Implementation of add URL API."""
|
|
140
|
+
now = arrow.utcnow().isoformat()
|
|
141
|
+
content = request.json
|
|
142
|
+
return jsonify(
|
|
143
|
+
{
|
|
144
|
+
"url": content["url"],
|
|
145
|
+
"created": now,
|
|
146
|
+
"lastModified": now,
|
|
147
|
+
"urn": request.url[: request.url.find("/urls")],
|
|
148
|
+
"owner": "http://localhost:8000/organisations/id/1",
|
|
149
|
+
"priority": 10,
|
|
150
|
+
"self": request.url
|
|
151
|
+
+ "/urls/base64/"
|
|
152
|
+
+ base64.b64encode(bytes(content["url"], "utf-8")).decode("utf-8"),
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@app.route("/urns/urn/<urn>/urls/base64/<encoded>", methods=["DELETE"])
|
|
158
|
+
def remove_url(urn: str, encoded: str):
|
|
159
|
+
"""Implementation of remove URL API."""
|
|
160
|
+
return "", 204
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
@app.route("/urns/urn/<urn>/my-urls", methods=["PATCH"])
|
|
164
|
+
def add_my_url(urn: str):
|
|
165
|
+
"""Implementation of add my URL API."""
|
|
166
|
+
return "", 204
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
@app.route("/urns/urn/<urn>", methods=["PATCH"])
|
|
170
|
+
def set_successor(urn: str):
|
|
171
|
+
"""Implementation of set successor API."""
|
|
172
|
+
return "", 204
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def get_urls(urn: str, query: str):
|
|
176
|
+
"""Helper method."""
|
|
177
|
+
if urn.startswith(namespace):
|
|
178
|
+
suffix = urn[len(namespace) :]
|
|
179
|
+
if int(suffix) < 5000000000:
|
|
180
|
+
now = arrow.utcnow().isoformat()
|
|
181
|
+
find_urls = request.url.rfind(query)
|
|
182
|
+
return jsonify(
|
|
183
|
+
{
|
|
184
|
+
"totalItems": 1,
|
|
185
|
+
"items": [
|
|
186
|
+
{
|
|
187
|
+
"url": "http://example.org/document-url",
|
|
188
|
+
"created": now,
|
|
189
|
+
"lastModified": now,
|
|
190
|
+
"urn": request.url[:find_urls],
|
|
191
|
+
"owner": "http://localhost:8000/organisations/id/1",
|
|
192
|
+
"priority": 10,
|
|
193
|
+
"self": request.url[:find_urls]
|
|
194
|
+
+ "/urls/base64/aHR0cDovL2V4YW1wbGUub3JnL2RvY3VtZW50LXVybA==",
|
|
195
|
+
}
|
|
196
|
+
],
|
|
197
|
+
"self": request.url,
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
return "", 404
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
if __name__ == "__main__":
|
|
204
|
+
app.run()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 University of Münster.
|
|
4
|
+
#
|
|
5
|
+
# invenio-pidstore-extra is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
"""Module that adds URN minting by DNB epicur service."""
|
|
10
|
+
|
|
11
|
+
from . import config
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class InvenioUrnProvider(object):
|
|
15
|
+
"""invenio-pidstore-extra extension."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, app=None):
|
|
18
|
+
"""Extension initialization."""
|
|
19
|
+
if app:
|
|
20
|
+
self.init_app(app)
|
|
21
|
+
|
|
22
|
+
def init_app(self, app):
|
|
23
|
+
"""Flask application initialization."""
|
|
24
|
+
self.init_config(app)
|
|
25
|
+
app.extensions["invenio-pidstore-extra"] = self
|
|
26
|
+
|
|
27
|
+
def init_config(self, app):
|
|
28
|
+
"""Initialize configuration."""
|
|
29
|
+
# Use theme's base template if theme is installed
|
|
30
|
+
for k in dir(config):
|
|
31
|
+
if k.startswith("PIDSTORE_EXTRA_"):
|
|
32
|
+
app.config.setdefault(k, getattr(config, k))
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 University of Münster.
|
|
4
|
+
#
|
|
5
|
+
# invenio-pidstore-extra is free software; you can redistribute it and/or
|
|
6
|
+
# modify it under the terms of the MIT License; see LICENSE file for more
|
|
7
|
+
# details.
|
|
8
|
+
|
|
9
|
+
"""URN providers."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
from .dnb import DNBUrnClient, DnbUrnProvider
|
|
13
|
+
|
|
14
|
+
__all__ = (DNBUrnClient, DnbUrnProvider)
|