digitalhub 0.11.0b7__py3-none-any.whl → 0.13.0__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.
Potentially problematic release.
This version of digitalhub might be problematic. Click here for more details.
- digitalhub/__init__.py +4 -1
- digitalhub/context/api.py +9 -5
- digitalhub/context/builder.py +7 -5
- digitalhub/context/context.py +13 -1
- digitalhub/entities/__init__.py +3 -0
- digitalhub/entities/_base/__init__.py +3 -0
- digitalhub/entities/_base/_base/__init__.py +3 -0
- digitalhub/entities/_base/_base/entity.py +4 -0
- digitalhub/entities/_base/context/__init__.py +3 -0
- digitalhub/entities/_base/context/entity.py +4 -0
- digitalhub/entities/_base/entity/__init__.py +3 -0
- digitalhub/entities/_base/entity/_constructors/__init__.py +3 -0
- digitalhub/entities/_base/entity/_constructors/metadata.py +4 -0
- digitalhub/entities/_base/entity/_constructors/name.py +4 -0
- digitalhub/entities/_base/entity/_constructors/spec.py +4 -0
- digitalhub/entities/_base/entity/_constructors/status.py +4 -0
- digitalhub/entities/_base/entity/_constructors/uuid.py +4 -0
- digitalhub/entities/_base/entity/builder.py +4 -0
- digitalhub/entities/_base/entity/entity.py +4 -0
- digitalhub/entities/_base/entity/metadata.py +4 -0
- digitalhub/entities/_base/entity/spec.py +4 -0
- digitalhub/entities/_base/entity/status.py +4 -0
- digitalhub/entities/_base/executable/__init__.py +3 -0
- digitalhub/entities/_base/executable/entity.py +109 -57
- digitalhub/entities/_base/material/__init__.py +3 -0
- digitalhub/entities/_base/material/entity.py +15 -18
- digitalhub/entities/_base/material/spec.py +4 -0
- digitalhub/entities/_base/material/status.py +4 -0
- digitalhub/entities/_base/material/utils.py +5 -1
- digitalhub/entities/_base/runtime_entity/__init__.py +3 -0
- digitalhub/entities/_base/runtime_entity/builder.py +4 -0
- digitalhub/entities/_base/unversioned/__init__.py +3 -0
- digitalhub/entities/_base/unversioned/builder.py +4 -0
- digitalhub/entities/_base/unversioned/entity.py +4 -0
- digitalhub/entities/_base/versioned/__init__.py +3 -0
- digitalhub/entities/_base/versioned/builder.py +4 -0
- digitalhub/entities/_base/versioned/entity.py +4 -0
- digitalhub/entities/_commons/__init__.py +3 -0
- digitalhub/entities/_commons/enums.py +4 -0
- digitalhub/entities/_commons/metrics.py +68 -30
- digitalhub/entities/_commons/utils.py +40 -9
- digitalhub/entities/_processors/__init__.py +3 -0
- digitalhub/entities/_processors/base.py +154 -79
- digitalhub/entities/_processors/context.py +370 -215
- digitalhub/entities/_processors/utils.py +78 -30
- digitalhub/entities/artifact/__init__.py +3 -0
- digitalhub/entities/artifact/_base/__init__.py +3 -0
- digitalhub/entities/artifact/_base/builder.py +4 -0
- digitalhub/entities/artifact/_base/entity.py +4 -0
- digitalhub/entities/artifact/_base/spec.py +4 -0
- digitalhub/entities/artifact/_base/status.py +4 -0
- digitalhub/entities/artifact/artifact/__init__.py +3 -0
- digitalhub/entities/artifact/artifact/builder.py +4 -0
- digitalhub/entities/artifact/artifact/entity.py +4 -0
- digitalhub/entities/artifact/artifact/spec.py +4 -0
- digitalhub/entities/artifact/artifact/status.py +4 -0
- digitalhub/entities/artifact/crud.py +8 -0
- digitalhub/entities/artifact/utils.py +32 -13
- digitalhub/entities/builders.py +4 -0
- digitalhub/entities/dataitem/__init__.py +3 -0
- digitalhub/entities/dataitem/_base/__init__.py +3 -0
- digitalhub/entities/dataitem/_base/builder.py +4 -0
- digitalhub/entities/dataitem/_base/entity.py +4 -0
- digitalhub/entities/dataitem/_base/spec.py +4 -0
- digitalhub/entities/dataitem/_base/status.py +4 -0
- digitalhub/entities/dataitem/crud.py +18 -2
- digitalhub/entities/dataitem/dataitem/__init__.py +3 -0
- digitalhub/entities/dataitem/dataitem/builder.py +4 -0
- digitalhub/entities/dataitem/dataitem/entity.py +4 -0
- digitalhub/entities/dataitem/dataitem/spec.py +4 -0
- digitalhub/entities/dataitem/dataitem/status.py +4 -0
- digitalhub/entities/dataitem/iceberg/__init__.py +3 -0
- digitalhub/entities/dataitem/iceberg/builder.py +4 -0
- digitalhub/entities/dataitem/iceberg/entity.py +4 -0
- digitalhub/entities/dataitem/iceberg/spec.py +4 -0
- digitalhub/entities/dataitem/iceberg/status.py +4 -0
- digitalhub/entities/dataitem/table/__init__.py +3 -0
- digitalhub/entities/dataitem/table/builder.py +4 -0
- digitalhub/entities/dataitem/table/entity.py +7 -3
- digitalhub/entities/dataitem/table/models.py +4 -0
- digitalhub/entities/dataitem/table/spec.py +4 -0
- digitalhub/entities/dataitem/table/status.py +4 -0
- digitalhub/entities/dataitem/table/utils.py +4 -0
- digitalhub/entities/dataitem/utils.py +88 -35
- digitalhub/entities/function/__init__.py +3 -0
- digitalhub/entities/function/_base/__init__.py +3 -0
- digitalhub/entities/function/_base/builder.py +4 -0
- digitalhub/entities/function/_base/entity.py +4 -0
- digitalhub/entities/function/_base/spec.py +4 -0
- digitalhub/entities/function/_base/status.py +4 -0
- digitalhub/entities/function/crud.py +4 -0
- digitalhub/entities/model/__init__.py +3 -0
- digitalhub/entities/model/_base/__init__.py +3 -0
- digitalhub/entities/model/_base/builder.py +4 -0
- digitalhub/entities/model/_base/entity.py +4 -0
- digitalhub/entities/model/_base/spec.py +4 -0
- digitalhub/entities/model/_base/status.py +4 -0
- digitalhub/entities/model/crud.py +8 -0
- digitalhub/entities/model/huggingface/__init__.py +3 -0
- digitalhub/entities/model/huggingface/builder.py +4 -0
- digitalhub/entities/model/huggingface/entity.py +4 -0
- digitalhub/entities/model/huggingface/spec.py +4 -0
- digitalhub/entities/model/huggingface/status.py +4 -0
- digitalhub/entities/model/mlflow/__init__.py +3 -0
- digitalhub/entities/model/mlflow/builder.py +4 -0
- digitalhub/entities/model/mlflow/entity.py +4 -0
- digitalhub/entities/model/mlflow/models.py +4 -0
- digitalhub/entities/model/mlflow/spec.py +4 -0
- digitalhub/entities/model/mlflow/status.py +4 -0
- digitalhub/entities/model/mlflow/utils.py +4 -0
- digitalhub/entities/model/model/__init__.py +3 -0
- digitalhub/entities/model/model/builder.py +4 -0
- digitalhub/entities/model/model/entity.py +4 -0
- digitalhub/entities/model/model/spec.py +4 -0
- digitalhub/entities/model/model/status.py +4 -0
- digitalhub/entities/model/sklearn/__init__.py +3 -0
- digitalhub/entities/model/sklearn/builder.py +4 -0
- digitalhub/entities/model/sklearn/entity.py +4 -0
- digitalhub/entities/model/sklearn/spec.py +4 -0
- digitalhub/entities/model/sklearn/status.py +4 -0
- digitalhub/entities/model/utils.py +32 -13
- digitalhub/entities/project/__init__.py +3 -0
- digitalhub/entities/project/_base/__init__.py +3 -0
- digitalhub/entities/project/_base/builder.py +4 -0
- digitalhub/entities/project/_base/entity.py +4 -2
- digitalhub/entities/project/_base/models.py +4 -0
- digitalhub/entities/project/_base/spec.py +4 -0
- digitalhub/entities/project/_base/status.py +4 -0
- digitalhub/entities/project/crud.py +4 -0
- digitalhub/entities/project/utils.py +4 -0
- digitalhub/entities/run/__init__.py +3 -0
- digitalhub/entities/run/_base/__init__.py +3 -0
- digitalhub/entities/run/_base/builder.py +4 -0
- digitalhub/entities/run/_base/entity.py +6 -2
- digitalhub/entities/run/_base/spec.py +4 -0
- digitalhub/entities/run/_base/status.py +4 -0
- digitalhub/entities/run/crud.py +4 -0
- digitalhub/entities/secret/__init__.py +3 -0
- digitalhub/entities/secret/_base/__init__.py +3 -0
- digitalhub/entities/secret/_base/builder.py +4 -0
- digitalhub/entities/secret/_base/entity.py +4 -0
- digitalhub/entities/secret/_base/spec.py +4 -0
- digitalhub/entities/secret/_base/status.py +4 -0
- digitalhub/entities/secret/crud.py +4 -0
- digitalhub/entities/task/__init__.py +3 -0
- digitalhub/entities/task/_base/__init__.py +3 -0
- digitalhub/entities/task/_base/builder.py +4 -0
- digitalhub/entities/task/_base/entity.py +4 -0
- digitalhub/entities/task/_base/models.py +16 -3
- digitalhub/entities/task/_base/spec.py +4 -0
- digitalhub/entities/task/_base/status.py +4 -0
- digitalhub/entities/task/_base/utils.py +4 -0
- digitalhub/entities/task/crud.py +4 -0
- digitalhub/entities/trigger/__init__.py +3 -0
- digitalhub/entities/trigger/_base/__init__.py +3 -0
- digitalhub/entities/trigger/_base/builder.py +4 -0
- digitalhub/entities/trigger/_base/entity.py +15 -0
- digitalhub/entities/trigger/_base/spec.py +4 -0
- digitalhub/entities/trigger/_base/status.py +4 -0
- digitalhub/entities/trigger/crud.py +4 -0
- digitalhub/entities/trigger/lifecycle/__init__.py +3 -0
- digitalhub/entities/trigger/lifecycle/builder.py +4 -0
- digitalhub/entities/trigger/lifecycle/entity.py +4 -0
- digitalhub/entities/trigger/lifecycle/spec.py +4 -0
- digitalhub/entities/trigger/lifecycle/status.py +4 -0
- digitalhub/entities/trigger/scheduler/__init__.py +3 -0
- digitalhub/entities/trigger/scheduler/builder.py +4 -0
- digitalhub/entities/trigger/scheduler/entity.py +4 -0
- digitalhub/entities/trigger/scheduler/spec.py +4 -0
- digitalhub/entities/trigger/scheduler/status.py +4 -0
- digitalhub/entities/workflow/__init__.py +3 -0
- digitalhub/entities/workflow/_base/__init__.py +3 -0
- digitalhub/entities/workflow/_base/builder.py +4 -0
- digitalhub/entities/workflow/_base/entity.py +4 -0
- digitalhub/entities/workflow/_base/spec.py +4 -0
- digitalhub/entities/workflow/_base/status.py +4 -0
- digitalhub/entities/workflow/crud.py +4 -0
- digitalhub/factory/__init__.py +3 -0
- digitalhub/factory/factory.py +29 -3
- digitalhub/factory/utils.py +15 -3
- digitalhub/runtimes/__init__.py +3 -0
- digitalhub/runtimes/_base.py +5 -1
- digitalhub/runtimes/builder.py +22 -1
- digitalhub/runtimes/enums.py +4 -0
- digitalhub/stores/__init__.py +3 -0
- digitalhub/stores/client/__init__.py +15 -0
- digitalhub/stores/client/_base/__init__.py +3 -0
- digitalhub/stores/client/_base/api_builder.py +18 -0
- digitalhub/stores/client/_base/client.py +97 -0
- digitalhub/stores/client/_base/key_builder.py +32 -0
- digitalhub/stores/client/_base/params_builder.py +18 -0
- digitalhub/stores/client/api.py +14 -5
- digitalhub/stores/client/builder.py +7 -1
- digitalhub/stores/client/dhcore/__init__.py +3 -0
- digitalhub/stores/client/dhcore/api_builder.py +21 -0
- digitalhub/stores/client/dhcore/client.py +329 -70
- digitalhub/stores/client/dhcore/configurator.py +489 -193
- digitalhub/stores/client/dhcore/enums.py +7 -0
- digitalhub/stores/client/dhcore/error_parser.py +39 -1
- digitalhub/stores/client/dhcore/key_builder.py +4 -0
- digitalhub/stores/client/dhcore/models.py +4 -0
- digitalhub/stores/client/dhcore/params_builder.py +117 -17
- digitalhub/stores/client/dhcore/utils.py +44 -22
- digitalhub/stores/client/local/__init__.py +3 -0
- digitalhub/stores/client/local/api_builder.py +21 -0
- digitalhub/stores/client/local/client.py +10 -8
- digitalhub/stores/client/local/enums.py +4 -0
- digitalhub/stores/client/local/key_builder.py +4 -0
- digitalhub/stores/client/local/params_builder.py +4 -0
- digitalhub/stores/credentials/__init__.py +3 -0
- digitalhub/stores/credentials/api.py +35 -0
- digitalhub/stores/credentials/configurator.py +210 -0
- digitalhub/stores/credentials/enums.py +68 -0
- digitalhub/stores/credentials/handler.py +176 -0
- digitalhub/stores/credentials/ini_module.py +164 -0
- digitalhub/stores/credentials/store.py +81 -0
- digitalhub/stores/data/__init__.py +3 -0
- digitalhub/stores/data/_base/__init__.py +3 -0
- digitalhub/stores/data/_base/store.py +31 -9
- digitalhub/stores/data/api.py +53 -9
- digitalhub/stores/data/builder.py +94 -41
- digitalhub/stores/data/enums.py +4 -0
- digitalhub/stores/data/local/__init__.py +3 -0
- digitalhub/stores/data/local/store.py +8 -7
- digitalhub/stores/data/remote/__init__.py +3 -0
- digitalhub/stores/data/remote/store.py +8 -7
- digitalhub/stores/data/s3/__init__.py +3 -0
- digitalhub/stores/data/s3/configurator.py +69 -80
- digitalhub/stores/data/s3/store.py +73 -81
- digitalhub/stores/data/s3/utils.py +14 -10
- digitalhub/stores/data/sql/__init__.py +3 -0
- digitalhub/stores/data/sql/configurator.py +80 -73
- digitalhub/stores/data/sql/store.py +195 -102
- digitalhub/stores/readers/__init__.py +3 -0
- digitalhub/stores/readers/data/__init__.py +3 -0
- digitalhub/stores/readers/data/_base/__init__.py +3 -0
- digitalhub/stores/readers/data/_base/builder.py +4 -0
- digitalhub/stores/readers/data/_base/reader.py +4 -0
- digitalhub/stores/readers/data/api.py +4 -0
- digitalhub/stores/readers/data/factory.py +4 -0
- digitalhub/stores/readers/data/pandas/__init__.py +3 -0
- digitalhub/stores/readers/data/pandas/builder.py +4 -0
- digitalhub/stores/readers/data/pandas/reader.py +4 -0
- digitalhub/stores/readers/query/__init__.py +3 -0
- digitalhub/utils/__init__.py +3 -0
- digitalhub/utils/enums.py +4 -0
- digitalhub/utils/exceptions.py +10 -0
- digitalhub/utils/file_utils.py +57 -30
- digitalhub/utils/generic_utils.py +45 -33
- digitalhub/utils/git_utils.py +28 -14
- digitalhub/utils/io_utils.py +23 -18
- digitalhub/utils/logger.py +4 -0
- digitalhub/utils/types.py +4 -0
- digitalhub/utils/uri_utils.py +35 -31
- digitalhub-0.13.0.dist-info/METADATA +301 -0
- digitalhub-0.13.0.dist-info/RECORD +259 -0
- digitalhub-0.13.0.dist-info/licenses/AUTHORS +5 -0
- digitalhub-0.13.0.dist-info/licenses/LICENSE +201 -0
- digitalhub/entities/_commons/types.py +0 -5
- digitalhub/stores/configurator/__init__.py +0 -0
- digitalhub/stores/configurator/api.py +0 -31
- digitalhub/stores/configurator/configurator.py +0 -198
- digitalhub/stores/configurator/credentials_store.py +0 -65
- digitalhub/stores/configurator/enums.py +0 -21
- digitalhub/stores/configurator/ini_module.py +0 -128
- digitalhub/stores/data/s3/enums.py +0 -16
- digitalhub/stores/data/sql/enums.py +0 -16
- digitalhub/stores/data/utils.py +0 -34
- digitalhub-0.11.0b7.dist-info/METADATA +0 -259
- digitalhub-0.11.0b7.dist-info/RECORD +0 -261
- digitalhub-0.11.0b7.dist-info/licenses/LICENSE.txt +0 -216
- {digitalhub-0.11.0b7.dist-info → digitalhub-0.13.0.dist-info}/WHEEL +0 -0
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: © 2025 DSLab - Fondazione Bruno Kessler
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
1
5
|
from __future__ import annotations
|
|
2
6
|
|
|
3
7
|
import typing
|
|
4
8
|
from typing import Any
|
|
9
|
+
from warnings import warn
|
|
5
10
|
|
|
6
11
|
from requests import request
|
|
7
12
|
from requests.exceptions import JSONDecodeError
|
|
@@ -12,30 +17,91 @@ from digitalhub.stores.client.dhcore.configurator import ClientDHCoreConfigurato
|
|
|
12
17
|
from digitalhub.stores.client.dhcore.error_parser import ErrorParser
|
|
13
18
|
from digitalhub.stores.client.dhcore.key_builder import ClientDHCoreKeyBuilder
|
|
14
19
|
from digitalhub.stores.client.dhcore.params_builder import ClientDHCoreParametersBuilder
|
|
15
|
-
from digitalhub.utils.exceptions import BackendError
|
|
20
|
+
from digitalhub.utils.exceptions import BackendError, ClientError
|
|
16
21
|
from digitalhub.utils.generic_utils import dump_json
|
|
17
22
|
|
|
18
23
|
if typing.TYPE_CHECKING:
|
|
19
24
|
from requests import Response
|
|
20
25
|
|
|
21
26
|
|
|
27
|
+
# API levels that are supported
|
|
28
|
+
MAX_API_LEVEL = 20
|
|
29
|
+
MIN_API_LEVEL = 13
|
|
30
|
+
LIB_VERSION = 13
|
|
31
|
+
|
|
32
|
+
|
|
22
33
|
class ClientDHCore(Client):
|
|
23
34
|
"""
|
|
24
|
-
DHCore client.
|
|
25
|
-
|
|
26
|
-
The DHCore client is used to communicate with the
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
DHCore client for remote DigitalHub Core backend communication.
|
|
36
|
+
|
|
37
|
+
The DHCore client is used to communicate with the DigitalHub Core
|
|
38
|
+
backend API via REST. The client supports multiple authentication methods:
|
|
39
|
+
- Basic authentication (username/password)
|
|
40
|
+
- OAuth2 token authentication with automatic token refresh
|
|
41
|
+
- Personal access token exchange
|
|
42
|
+
|
|
43
|
+
At initialization, the client attempts to load endpoint and authentication
|
|
44
|
+
parameters from environment variables and the .dhcore configuration file.
|
|
45
|
+
If authentication or endpoint errors occur during client creation, users
|
|
46
|
+
can update the configuration using the `set_dhcore_env` function from
|
|
47
|
+
the utils module.
|
|
48
|
+
|
|
49
|
+
The client automatically handles:
|
|
50
|
+
- API version compatibility checking
|
|
51
|
+
- Pagination for list operations
|
|
52
|
+
- Token refresh on authentication errors
|
|
53
|
+
- Error parsing and exception mapping
|
|
54
|
+
- JSON serialization/deserialization
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
config : dict, optional
|
|
59
|
+
DHCore environment configuration. If None, configuration will
|
|
60
|
+
be loaded from environment variables and configuration files.
|
|
61
|
+
|
|
62
|
+
Attributes
|
|
63
|
+
----------
|
|
64
|
+
_api_builder : ClientDHCoreApiBuilder
|
|
65
|
+
Builds API endpoint URLs for different operations.
|
|
66
|
+
_key_builder : ClientDHCoreKeyBuilder
|
|
67
|
+
Builds storage keys for entities.
|
|
68
|
+
_params_builder : ClientDHCoreParametersBuilder
|
|
69
|
+
Builds request parameters for API calls.
|
|
70
|
+
_error_parser : ErrorParser
|
|
71
|
+
Parses backend responses and raises appropriate exceptions.
|
|
72
|
+
_configurator : ClientDHCoreConfigurator
|
|
73
|
+
Manages client configuration and authentication.
|
|
74
|
+
|
|
75
|
+
Notes
|
|
76
|
+
-----
|
|
77
|
+
Supported DHCore API versions: {MIN_API_LEVEL} to {MAX_API_LEVEL}
|
|
78
|
+
Current library API version: {LIB_VERSION}
|
|
79
|
+
|
|
80
|
+
Examples
|
|
81
|
+
--------
|
|
82
|
+
>>> from digitalhub.stores.client.api import get_client
|
|
83
|
+
>>> client = get_client(local=False)
|
|
84
|
+
>>> # Client is now ready for API operations
|
|
36
85
|
"""
|
|
37
86
|
|
|
38
87
|
def __init__(self, config: dict | None = None) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Initialize DHCore client.
|
|
90
|
+
|
|
91
|
+
Creates a new DHCore client instance with all necessary components
|
|
92
|
+
for communicating with the DigitalHub Core backend. Sets up API
|
|
93
|
+
builders, configurators, and error handling.
|
|
94
|
+
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
config : dict, optional
|
|
98
|
+
DHCore environment configuration. If None, configuration will
|
|
99
|
+
be loaded from environment variables and configuration files.
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
None
|
|
104
|
+
"""
|
|
39
105
|
super().__init__()
|
|
40
106
|
|
|
41
107
|
# API builder
|
|
@@ -52,7 +118,6 @@ class ClientDHCore(Client):
|
|
|
52
118
|
|
|
53
119
|
# Client Configurator
|
|
54
120
|
self._configurator = ClientDHCoreConfigurator()
|
|
55
|
-
self._configurator.configure(config)
|
|
56
121
|
|
|
57
122
|
##############################
|
|
58
123
|
# CRUD methods
|
|
@@ -62,19 +127,31 @@ class ClientDHCore(Client):
|
|
|
62
127
|
"""
|
|
63
128
|
Create an object in DHCore.
|
|
64
129
|
|
|
130
|
+
Sends a POST request to the DHCore backend to create a new object.
|
|
131
|
+
Automatically sets the appropriate Content-Type header and serializes
|
|
132
|
+
the object to JSON format.
|
|
133
|
+
|
|
65
134
|
Parameters
|
|
66
135
|
----------
|
|
67
136
|
api : str
|
|
68
|
-
|
|
137
|
+
The API endpoint path for creating the object.
|
|
69
138
|
obj : Any
|
|
70
|
-
|
|
139
|
+
The object to create. Will be serialized to JSON.
|
|
71
140
|
**kwargs : dict
|
|
72
|
-
|
|
141
|
+
Additional keyword arguments to pass to the HTTP request,
|
|
142
|
+
such as headers, params, etc.
|
|
73
143
|
|
|
74
144
|
Returns
|
|
75
145
|
-------
|
|
76
146
|
dict
|
|
77
|
-
|
|
147
|
+
The created object as returned by the backend.
|
|
148
|
+
|
|
149
|
+
Raises
|
|
150
|
+
------
|
|
151
|
+
BackendError
|
|
152
|
+
If the backend returns an error response.
|
|
153
|
+
ClientError
|
|
154
|
+
If there are client-side configuration issues.
|
|
78
155
|
"""
|
|
79
156
|
if "headers" not in kwargs:
|
|
80
157
|
kwargs["headers"] = {}
|
|
@@ -86,17 +163,27 @@ class ClientDHCore(Client):
|
|
|
86
163
|
"""
|
|
87
164
|
Get an object from DHCore.
|
|
88
165
|
|
|
166
|
+
Sends a GET request to the DHCore backend to retrieve an existing object.
|
|
167
|
+
|
|
89
168
|
Parameters
|
|
90
169
|
----------
|
|
91
170
|
api : str
|
|
92
|
-
|
|
171
|
+
The API endpoint path for reading the object.
|
|
93
172
|
**kwargs : dict
|
|
94
|
-
|
|
173
|
+
Additional keyword arguments to pass to the HTTP request,
|
|
174
|
+
such as headers, params, etc.
|
|
95
175
|
|
|
96
176
|
Returns
|
|
97
177
|
-------
|
|
98
178
|
dict
|
|
99
|
-
|
|
179
|
+
The retrieved object as returned by the backend.
|
|
180
|
+
|
|
181
|
+
Raises
|
|
182
|
+
------
|
|
183
|
+
BackendError
|
|
184
|
+
If the backend returns an error response.
|
|
185
|
+
EntityNotExistsError
|
|
186
|
+
If the requested object does not exist.
|
|
100
187
|
"""
|
|
101
188
|
return self._prepare_call("GET", api, **kwargs)
|
|
102
189
|
|
|
@@ -104,19 +191,31 @@ class ClientDHCore(Client):
|
|
|
104
191
|
"""
|
|
105
192
|
Update an object in DHCore.
|
|
106
193
|
|
|
194
|
+
Sends a PUT request to the DHCore backend to update an existing object.
|
|
195
|
+
Automatically sets the appropriate Content-Type header and serializes
|
|
196
|
+
the object to JSON format.
|
|
197
|
+
|
|
107
198
|
Parameters
|
|
108
199
|
----------
|
|
109
200
|
api : str
|
|
110
|
-
|
|
111
|
-
obj :
|
|
112
|
-
|
|
201
|
+
The API endpoint path for updating the object.
|
|
202
|
+
obj : Any
|
|
203
|
+
The updated object data. Will be serialized to JSON.
|
|
113
204
|
**kwargs : dict
|
|
114
|
-
|
|
205
|
+
Additional keyword arguments to pass to the HTTP request,
|
|
206
|
+
such as headers, params, etc.
|
|
115
207
|
|
|
116
208
|
Returns
|
|
117
209
|
-------
|
|
118
210
|
dict
|
|
119
|
-
|
|
211
|
+
The updated object as returned by the backend.
|
|
212
|
+
|
|
213
|
+
Raises
|
|
214
|
+
------
|
|
215
|
+
BackendError
|
|
216
|
+
If the backend returns an error response.
|
|
217
|
+
EntityNotExistsError
|
|
218
|
+
If the object to update does not exist.
|
|
120
219
|
"""
|
|
121
220
|
if "headers" not in kwargs:
|
|
122
221
|
kwargs["headers"] = {}
|
|
@@ -128,17 +227,30 @@ class ClientDHCore(Client):
|
|
|
128
227
|
"""
|
|
129
228
|
Delete an object from DHCore.
|
|
130
229
|
|
|
230
|
+
Sends a DELETE request to the DHCore backend to remove an object.
|
|
231
|
+
If the backend returns a boolean response, it will be wrapped in
|
|
232
|
+
a dictionary with a "deleted" key.
|
|
233
|
+
|
|
131
234
|
Parameters
|
|
132
235
|
----------
|
|
133
236
|
api : str
|
|
134
|
-
|
|
237
|
+
The API endpoint path for deleting the object.
|
|
135
238
|
**kwargs : dict
|
|
136
|
-
|
|
239
|
+
Additional keyword arguments to pass to the HTTP request,
|
|
240
|
+
such as headers, params, cascade options, etc.
|
|
137
241
|
|
|
138
242
|
Returns
|
|
139
243
|
-------
|
|
140
244
|
dict
|
|
141
|
-
|
|
245
|
+
The deletion result. Either the backend response or
|
|
246
|
+
{"deleted": True/False} if backend returns a boolean.
|
|
247
|
+
|
|
248
|
+
Raises
|
|
249
|
+
------
|
|
250
|
+
BackendError
|
|
251
|
+
If the backend returns an error response.
|
|
252
|
+
EntityNotExistsError
|
|
253
|
+
If the object to delete does not exist.
|
|
142
254
|
"""
|
|
143
255
|
resp = self._prepare_call("DELETE", api, **kwargs)
|
|
144
256
|
if isinstance(resp, bool):
|
|
@@ -149,21 +261,33 @@ class ClientDHCore(Client):
|
|
|
149
261
|
"""
|
|
150
262
|
List objects from DHCore.
|
|
151
263
|
|
|
264
|
+
Sends GET requests to the DHCore backend to retrieve a paginated list
|
|
265
|
+
of objects. Automatically handles pagination by making multiple requests
|
|
266
|
+
until all objects are retrieved.
|
|
267
|
+
|
|
152
268
|
Parameters
|
|
153
269
|
----------
|
|
154
270
|
api : str
|
|
155
|
-
|
|
271
|
+
The API endpoint path for listing objects.
|
|
156
272
|
**kwargs : dict
|
|
157
|
-
|
|
273
|
+
Additional keyword arguments to pass to the HTTP request.
|
|
274
|
+
Can include 'params' dict with pagination parameters.
|
|
158
275
|
|
|
159
276
|
Returns
|
|
160
277
|
-------
|
|
161
278
|
list[dict]
|
|
162
|
-
|
|
163
|
-
"""
|
|
164
|
-
if kwargs is None:
|
|
165
|
-
kwargs = {}
|
|
279
|
+
A list containing all objects from all pages.
|
|
166
280
|
|
|
281
|
+
Raises
|
|
282
|
+
------
|
|
283
|
+
BackendError
|
|
284
|
+
If the backend returns an error response.
|
|
285
|
+
|
|
286
|
+
Notes
|
|
287
|
+
-----
|
|
288
|
+
This method automatically handles pagination starting from page 0
|
|
289
|
+
and continues until all pages are retrieved.
|
|
290
|
+
"""
|
|
167
291
|
if "params" not in kwargs:
|
|
168
292
|
kwargs["params"] = {}
|
|
169
293
|
|
|
@@ -185,19 +309,27 @@ class ClientDHCore(Client):
|
|
|
185
309
|
|
|
186
310
|
def list_first_object(self, api: str, **kwargs) -> dict:
|
|
187
311
|
"""
|
|
188
|
-
|
|
312
|
+
Get the first object from a list in DHCore.
|
|
313
|
+
|
|
314
|
+
Retrieves the first object from a paginated list by calling
|
|
315
|
+
list_objects and returning the first item.
|
|
189
316
|
|
|
190
317
|
Parameters
|
|
191
318
|
----------
|
|
192
319
|
api : str
|
|
193
|
-
The
|
|
320
|
+
The API endpoint path for listing objects.
|
|
194
321
|
**kwargs : dict
|
|
195
|
-
|
|
322
|
+
Additional keyword arguments to pass to the HTTP request.
|
|
196
323
|
|
|
197
324
|
Returns
|
|
198
325
|
-------
|
|
199
326
|
dict
|
|
200
|
-
The
|
|
327
|
+
The first object from the list.
|
|
328
|
+
|
|
329
|
+
Raises
|
|
330
|
+
------
|
|
331
|
+
BackendError
|
|
332
|
+
If no objects are found or if the backend returns an error.
|
|
201
333
|
"""
|
|
202
334
|
try:
|
|
203
335
|
return self.list_objects(api, **kwargs)[0]
|
|
@@ -208,21 +340,35 @@ class ClientDHCore(Client):
|
|
|
208
340
|
"""
|
|
209
341
|
Search objects from DHCore.
|
|
210
342
|
|
|
343
|
+
Performs a search query against the DHCore backend using Solr search
|
|
344
|
+
capabilities. Handles pagination and removes search highlights from
|
|
345
|
+
the returned objects.
|
|
346
|
+
|
|
211
347
|
Parameters
|
|
212
348
|
----------
|
|
213
349
|
api : str
|
|
214
|
-
|
|
350
|
+
The API endpoint path for searching objects (usually Solr search).
|
|
215
351
|
**kwargs : dict
|
|
216
|
-
|
|
352
|
+
Additional keyword arguments to pass to the HTTP request.
|
|
353
|
+
Can include search parameters, filters, pagination options, etc.
|
|
217
354
|
|
|
218
355
|
Returns
|
|
219
356
|
-------
|
|
220
357
|
list[dict]
|
|
221
|
-
|
|
358
|
+
A list of objects matching the search criteria, with search
|
|
359
|
+
highlights removed.
|
|
360
|
+
|
|
361
|
+
Raises
|
|
362
|
+
------
|
|
363
|
+
BackendError
|
|
364
|
+
If the backend returns an error response.
|
|
365
|
+
|
|
366
|
+
Notes
|
|
367
|
+
-----
|
|
368
|
+
This method sets default values for pagination (page=0, size=10)
|
|
369
|
+
and sorting (by metadata.updated descending) if not provided.
|
|
370
|
+
Search highlights are automatically removed from results.
|
|
222
371
|
"""
|
|
223
|
-
if kwargs is None:
|
|
224
|
-
kwargs = {}
|
|
225
|
-
|
|
226
372
|
if "params" not in kwargs:
|
|
227
373
|
kwargs["params"] = {}
|
|
228
374
|
|
|
@@ -262,73 +408,177 @@ class ClientDHCore(Client):
|
|
|
262
408
|
"""
|
|
263
409
|
Prepare a call to the DHCore API.
|
|
264
410
|
|
|
411
|
+
Handles the preparation of an API call by checking configuration,
|
|
412
|
+
building the URL, and adding authentication parameters.
|
|
413
|
+
|
|
265
414
|
Parameters
|
|
266
415
|
----------
|
|
267
416
|
call_type : str
|
|
268
|
-
The type
|
|
417
|
+
The HTTP method type (GET, POST, PUT, DELETE, etc.).
|
|
269
418
|
api : str
|
|
270
|
-
The
|
|
419
|
+
The API endpoint path to call.
|
|
271
420
|
**kwargs : dict
|
|
272
|
-
|
|
421
|
+
Additional keyword arguments to pass to the HTTP request.
|
|
273
422
|
|
|
274
423
|
Returns
|
|
275
424
|
-------
|
|
276
425
|
dict
|
|
277
|
-
|
|
426
|
+
The response from the API call.
|
|
427
|
+
|
|
428
|
+
Raises
|
|
429
|
+
------
|
|
430
|
+
ClientError
|
|
431
|
+
If the client configuration is invalid.
|
|
432
|
+
BackendError
|
|
433
|
+
If the backend returns an error response.
|
|
278
434
|
"""
|
|
279
435
|
self._configurator.check_config()
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
kwargs = self._configurator.set_request_auth(kwargs)
|
|
284
|
-
return self._make_call(call_type, url, **kwargs)
|
|
436
|
+
url = self._build_url(api)
|
|
437
|
+
full_kwargs = self._configurator.get_auth_parameters(kwargs)
|
|
438
|
+
return self._make_call(call_type, url, **full_kwargs)
|
|
285
439
|
|
|
286
|
-
def
|
|
440
|
+
def _build_url(self, api: str) -> str:
|
|
441
|
+
"""
|
|
442
|
+
Build the complete URL for an API call.
|
|
443
|
+
|
|
444
|
+
Combines the configured endpoint with the API path to create
|
|
445
|
+
the full URL for the HTTP request.
|
|
446
|
+
|
|
447
|
+
Parameters
|
|
448
|
+
----------
|
|
449
|
+
api : str
|
|
450
|
+
The API endpoint path. Leading slashes are automatically handled.
|
|
451
|
+
|
|
452
|
+
Returns
|
|
453
|
+
-------
|
|
454
|
+
str
|
|
455
|
+
The complete URL for the API call.
|
|
456
|
+
|
|
457
|
+
Notes
|
|
458
|
+
-----
|
|
459
|
+
This method automatically removes leading slashes from the API path
|
|
460
|
+
to ensure proper URL construction.
|
|
461
|
+
"""
|
|
462
|
+
endpoint = self._configurator.get_endpoint()
|
|
463
|
+
return f"{endpoint}/{api.removeprefix('/')}"
|
|
464
|
+
|
|
465
|
+
def _make_call(self, call_type: str, url: str, refresh: bool = True, **kwargs) -> dict:
|
|
287
466
|
"""
|
|
288
467
|
Make a call to the DHCore API.
|
|
289
468
|
|
|
469
|
+
Executes the actual HTTP request to the DHCore backend, handles
|
|
470
|
+
API version checking, automatic token refresh on 401 errors,
|
|
471
|
+
and error parsing.
|
|
472
|
+
|
|
290
473
|
Parameters
|
|
291
474
|
----------
|
|
292
475
|
call_type : str
|
|
293
|
-
The type
|
|
476
|
+
The HTTP method type (GET, POST, PUT, DELETE, etc.).
|
|
294
477
|
url : str
|
|
295
|
-
The URL to call.
|
|
478
|
+
The complete URL to call.
|
|
479
|
+
refresh : bool, default True
|
|
480
|
+
Whether to attempt token refresh on authentication errors.
|
|
481
|
+
Set to False to prevent infinite recursion during refresh.
|
|
296
482
|
**kwargs : dict
|
|
297
|
-
|
|
483
|
+
Additional keyword arguments to pass to the HTTP request.
|
|
298
484
|
|
|
299
485
|
Returns
|
|
300
486
|
-------
|
|
301
487
|
dict
|
|
302
|
-
|
|
488
|
+
The parsed response from the backend as a dictionary.
|
|
489
|
+
|
|
490
|
+
Raises
|
|
491
|
+
------
|
|
492
|
+
ClientError
|
|
493
|
+
If the backend API version is not supported.
|
|
494
|
+
BackendError
|
|
495
|
+
If the backend returns an error response or response parsing fails.
|
|
496
|
+
UnauthorizedError
|
|
497
|
+
If authentication fails and token refresh is not possible.
|
|
498
|
+
|
|
499
|
+
Notes
|
|
500
|
+
-----
|
|
501
|
+
This method automatically handles:
|
|
502
|
+
- API version compatibility checking
|
|
503
|
+
- OAuth2 token refresh on 401 errors
|
|
504
|
+
- Response parsing and error handling
|
|
505
|
+
- 60-second timeout for all requests
|
|
303
506
|
"""
|
|
304
507
|
# Call the API
|
|
305
508
|
response = request(call_type, url, timeout=60, **kwargs)
|
|
306
509
|
|
|
307
510
|
# Evaluate DHCore API version
|
|
308
|
-
self.
|
|
511
|
+
self._check_core_version(response)
|
|
309
512
|
|
|
310
|
-
# Handle token refresh
|
|
311
|
-
if response.status_code in [401] and
|
|
312
|
-
self._configurator.
|
|
313
|
-
kwargs = self._configurator.
|
|
314
|
-
return self._make_call(call_type, url,
|
|
513
|
+
# Handle token refresh (redo call)
|
|
514
|
+
if (response.status_code in [401]) and (refresh) and self._configurator.refreshable_auth_types():
|
|
515
|
+
self._configurator.refresh_credentials(change_origin=True)
|
|
516
|
+
kwargs = self._configurator.get_auth_parameters(kwargs)
|
|
517
|
+
return self._make_call(call_type, url, refresh=False, **kwargs)
|
|
315
518
|
|
|
316
519
|
self._error_parser.parse(response)
|
|
317
520
|
return self._dictify_response(response)
|
|
318
521
|
|
|
522
|
+
def _check_core_version(self, response: Response) -> None:
|
|
523
|
+
"""
|
|
524
|
+
Check DHCore API version compatibility.
|
|
525
|
+
|
|
526
|
+
Validates that the DHCore backend API version is compatible with
|
|
527
|
+
this client library. Issues warnings if the backend version is
|
|
528
|
+
newer than the library version.
|
|
529
|
+
|
|
530
|
+
Parameters
|
|
531
|
+
----------
|
|
532
|
+
response : Response
|
|
533
|
+
The HTTP response object containing the X-Api-Level header.
|
|
534
|
+
|
|
535
|
+
Returns
|
|
536
|
+
-------
|
|
537
|
+
None
|
|
538
|
+
|
|
539
|
+
Raises
|
|
540
|
+
------
|
|
541
|
+
ClientError
|
|
542
|
+
If the backend API level is not supported by this client.
|
|
543
|
+
|
|
544
|
+
Notes
|
|
545
|
+
-----
|
|
546
|
+
Supported API levels: {MIN_API_LEVEL} to {MAX_API_LEVEL}
|
|
547
|
+
Current library version: {LIB_VERSION}
|
|
548
|
+
"""
|
|
549
|
+
if "X-Api-Level" in response.headers:
|
|
550
|
+
core_api_level = int(response.headers["X-Api-Level"])
|
|
551
|
+
if not (MIN_API_LEVEL <= core_api_level <= MAX_API_LEVEL):
|
|
552
|
+
raise ClientError("Backend API level not supported.")
|
|
553
|
+
if LIB_VERSION < core_api_level:
|
|
554
|
+
warn("Backend API level is higher than library version. You should consider updating the library.")
|
|
555
|
+
|
|
319
556
|
def _dictify_response(self, response: Response) -> dict:
|
|
320
557
|
"""
|
|
321
|
-
|
|
558
|
+
Parse HTTP response to dictionary.
|
|
559
|
+
|
|
560
|
+
Converts the HTTP response body from JSON to a Python dictionary.
|
|
561
|
+
Handles empty responses gracefully.
|
|
322
562
|
|
|
323
563
|
Parameters
|
|
324
564
|
----------
|
|
325
565
|
response : Response
|
|
326
|
-
The response object.
|
|
566
|
+
The HTTP response object to parse.
|
|
327
567
|
|
|
328
568
|
Returns
|
|
329
569
|
-------
|
|
330
570
|
dict
|
|
331
|
-
The parsed response
|
|
571
|
+
The parsed response body as a dictionary. Returns empty dict
|
|
572
|
+
if response body is empty.
|
|
573
|
+
|
|
574
|
+
Raises
|
|
575
|
+
------
|
|
576
|
+
BackendError
|
|
577
|
+
If the response cannot be parsed as JSON.
|
|
578
|
+
|
|
579
|
+
Notes
|
|
580
|
+
-----
|
|
581
|
+
Empty response bodies are treated as valid and return an empty dict.
|
|
332
582
|
"""
|
|
333
583
|
try:
|
|
334
584
|
return response.json()
|
|
@@ -344,11 +594,20 @@ class ClientDHCore(Client):
|
|
|
344
594
|
@staticmethod
|
|
345
595
|
def is_local() -> bool:
|
|
346
596
|
"""
|
|
347
|
-
|
|
597
|
+
Check if this client operates locally.
|
|
598
|
+
|
|
599
|
+
Returns a flag indicating whether this client instance operates
|
|
600
|
+
on local data or communicates with a remote backend.
|
|
348
601
|
|
|
349
602
|
Returns
|
|
350
603
|
-------
|
|
351
604
|
bool
|
|
352
|
-
False
|
|
605
|
+
False, indicating this client communicates with a remote
|
|
606
|
+
DHCore backend, not local storage.
|
|
607
|
+
|
|
608
|
+
Notes
|
|
609
|
+
-----
|
|
610
|
+
This method is used to distinguish between ClientDHCore (returns False)
|
|
611
|
+
and ClientLocal (returns True) implementations.
|
|
353
612
|
"""
|
|
354
613
|
return False
|