digitalhub 0.11.0b7__py3-none-any.whl → 0.13.0b0__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 +4 -0
- digitalhub/context/builder.py +4 -0
- digitalhub/context/context.py +4 -0
- 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 +11 -0
- digitalhub/entities/_base/material/__init__.py +3 -0
- digitalhub/entities/_base/material/entity.py +12 -15
- 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 +4 -0
- digitalhub/entities/_commons/types.py +4 -0
- digitalhub/entities/_commons/utils.py +4 -0
- digitalhub/entities/_processors/__init__.py +3 -0
- digitalhub/entities/_processors/base.py +4 -0
- digitalhub/entities/_processors/context.py +5 -1
- digitalhub/entities/_processors/utils.py +4 -0
- 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 +4 -0
- digitalhub/entities/artifact/utils.py +4 -0
- 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 +4 -0
- 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 +4 -0
- 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 +4 -0
- 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 +4 -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 +4 -0
- 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 -0
- 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 +4 -0
- 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 +4 -0
- 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 +4 -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 +4 -0
- digitalhub/factory/utils.py +4 -0
- digitalhub/runtimes/__init__.py +3 -0
- digitalhub/runtimes/_base.py +4 -0
- digitalhub/runtimes/builder.py +4 -0
- digitalhub/runtimes/enums.py +4 -0
- digitalhub/stores/__init__.py +3 -0
- digitalhub/stores/client/__init__.py +3 -0
- digitalhub/stores/client/_base/__init__.py +3 -0
- digitalhub/stores/client/_base/api_builder.py +4 -0
- digitalhub/stores/client/_base/client.py +4 -0
- digitalhub/stores/client/_base/key_builder.py +4 -0
- digitalhub/stores/client/_base/params_builder.py +4 -0
- digitalhub/stores/client/api.py +4 -0
- digitalhub/stores/client/builder.py +4 -0
- digitalhub/stores/client/dhcore/__init__.py +3 -0
- digitalhub/stores/client/dhcore/api_builder.py +4 -0
- digitalhub/stores/client/dhcore/client.py +60 -19
- digitalhub/stores/client/dhcore/configurator.py +282 -183
- digitalhub/stores/client/dhcore/enums.py +6 -0
- digitalhub/stores/client/dhcore/error_parser.py +4 -0
- digitalhub/stores/client/dhcore/key_builder.py +4 -0
- digitalhub/stores/client/dhcore/models.py +4 -0
- digitalhub/stores/client/dhcore/params_builder.py +4 -0
- digitalhub/stores/client/dhcore/utils.py +12 -8
- digitalhub/stores/client/local/__init__.py +3 -0
- digitalhub/stores/client/local/api_builder.py +4 -0
- digitalhub/stores/client/local/client.py +4 -0
- 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/{configurator → credentials}/api.py +7 -3
- digitalhub/stores/credentials/configurator.py +37 -0
- digitalhub/stores/credentials/enums.py +54 -0
- digitalhub/stores/credentials/handler.py +148 -0
- digitalhub/stores/{configurator → credentials}/ini_module.py +5 -1
- digitalhub/stores/credentials/store.py +49 -0
- digitalhub/stores/data/__init__.py +3 -0
- digitalhub/stores/data/_base/__init__.py +3 -0
- digitalhub/stores/data/_base/store.py +23 -6
- digitalhub/stores/data/api.py +41 -1
- digitalhub/stores/data/builder.py +50 -53
- 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 +40 -92
- digitalhub/stores/data/s3/store.py +46 -57
- digitalhub/stores/data/s3/utils.py +5 -1
- digitalhub/stores/data/sql/__init__.py +3 -0
- digitalhub/stores/data/sql/configurator.py +39 -83
- digitalhub/stores/data/sql/store.py +19 -15
- 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 +4 -0
- digitalhub/utils/file_utils.py +4 -0
- digitalhub/utils/generic_utils.py +4 -0
- digitalhub/utils/git_utils.py +4 -0
- digitalhub/utils/io_utils.py +4 -0
- digitalhub/utils/logger.py +4 -0
- digitalhub/utils/types.py +4 -0
- digitalhub/utils/uri_utils.py +4 -0
- digitalhub-0.13.0b0.dist-info/METADATA +301 -0
- digitalhub-0.13.0b0.dist-info/RECORD +260 -0
- digitalhub-0.13.0b0.dist-info/licenses/AUTHORS +5 -0
- digitalhub-0.13.0b0.dist-info/licenses/LICENSE +201 -0
- digitalhub/stores/configurator/__init__.py +0 -0
- digitalhub/stores/configurator/configurator.py +0 -198
- digitalhub/stores/configurator/credentials_store.py +0 -65
- digitalhub/stores/configurator/enums.py +0 -21
- 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.0b0.dist-info}/WHEEL +0 -0
|
@@ -1,14 +1,17 @@
|
|
|
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
|
-
from warnings import warn
|
|
5
8
|
|
|
6
9
|
from requests import request
|
|
7
10
|
|
|
8
|
-
from digitalhub.stores.client.dhcore.enums import AuthType
|
|
9
|
-
from digitalhub.stores.
|
|
10
|
-
from digitalhub.stores.
|
|
11
|
-
from digitalhub.stores.
|
|
11
|
+
from digitalhub.stores.client.dhcore.enums import AuthType
|
|
12
|
+
from digitalhub.stores.credentials.configurator import Configurator
|
|
13
|
+
from digitalhub.stores.credentials.enums import CredsEnvVar, CredsOrigin
|
|
14
|
+
from digitalhub.stores.credentials.handler import creds_handler
|
|
12
15
|
from digitalhub.utils.exceptions import ClientError
|
|
13
16
|
from digitalhub.utils.generic_utils import list_enum
|
|
14
17
|
from digitalhub.utils.uri_utils import has_remote_scheme
|
|
@@ -17,191 +20,282 @@ if typing.TYPE_CHECKING:
|
|
|
17
20
|
from requests import Response
|
|
18
21
|
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
AUTH_KEY = "_auth"
|
|
22
|
-
|
|
23
|
-
# API levels that are supported
|
|
24
|
-
MAX_API_LEVEL = 20
|
|
25
|
-
MIN_API_LEVEL = 11
|
|
26
|
-
LIB_VERSION = 11
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class ClientDHCoreConfigurator:
|
|
23
|
+
class ClientDHCoreConfigurator(Configurator):
|
|
30
24
|
"""
|
|
31
25
|
Configurator object used to configure the client.
|
|
26
|
+
|
|
27
|
+
The configurator starts reading the credentials from the
|
|
28
|
+
environment and from the ini file and stores them into the
|
|
29
|
+
creds_handler object.
|
|
30
|
+
|
|
31
|
+
While reading the credentials from the two sources (environment and file),
|
|
32
|
+
the configurator evaluate if the required keys are present in both sources.
|
|
33
|
+
If the required keys are not present in both sources, the configurator
|
|
34
|
+
will rise an error, otherwise decide which source to use.
|
|
35
|
+
|
|
36
|
+
Once the credentials are read, the configurator check the current profile
|
|
37
|
+
name from the ini file, and set it. The default one is __default. The
|
|
38
|
+
profile is used to discriminate a set of credentials inside the ini file.
|
|
39
|
+
|
|
40
|
+
The configurator finally set the authentication type based on the credentials.
|
|
41
|
+
The logic is the following:
|
|
42
|
+
|
|
43
|
+
1. Check for a personal access token. Use it immediately to
|
|
44
|
+
require a timed access token in an exchange endpoint.
|
|
45
|
+
Switche then the origin to file and .
|
|
46
|
+
Set the auth type to EXCHANGE.
|
|
47
|
+
2. Check for an access token and a refresh token.
|
|
48
|
+
Set the auth type to OAUTH2.
|
|
49
|
+
3. Check for username and password.
|
|
50
|
+
Set the auth type to BASIC.
|
|
51
|
+
4. If none of the above is true, leave the auth type to None.
|
|
32
52
|
"""
|
|
33
53
|
|
|
54
|
+
keys = [*list_enum(CredsEnvVar)]
|
|
55
|
+
required_keys = [CredsEnvVar.DHCORE_ENDPOINT.value]
|
|
56
|
+
keys_to_unprefix = [
|
|
57
|
+
CredsEnvVar.DHCORE_REFRESH_TOKEN.value,
|
|
58
|
+
CredsEnvVar.DHCORE_ACCESS_TOKEN.value,
|
|
59
|
+
CredsEnvVar.DHCORE_ISSUER.value,
|
|
60
|
+
CredsEnvVar.DHCORE_CLIENT_ID.value,
|
|
61
|
+
]
|
|
62
|
+
|
|
34
63
|
def __init__(self) -> None:
|
|
35
|
-
|
|
64
|
+
super().__init__()
|
|
65
|
+
self.load_configs()
|
|
66
|
+
self._origin = self.set_origin()
|
|
67
|
+
self._current_profile = creds_handler.get_current_env()
|
|
68
|
+
self._auth_type: str | None = None
|
|
69
|
+
self.set_auth_type()
|
|
36
70
|
|
|
37
71
|
##############################
|
|
38
|
-
#
|
|
72
|
+
# Credentials methods
|
|
39
73
|
##############################
|
|
40
74
|
|
|
41
|
-
def
|
|
75
|
+
def load_configs(self) -> str:
|
|
42
76
|
"""
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
config : dict
|
|
48
|
-
Configuration dictionary.
|
|
77
|
+
Load the configuration from the environment and from the file.
|
|
78
|
+
"""
|
|
79
|
+
self.load_env_vars()
|
|
80
|
+
self.load_file_vars()
|
|
49
81
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
82
|
+
def load_env_vars(self) -> None:
|
|
83
|
+
"""
|
|
84
|
+
Load the credentials from the environment.
|
|
53
85
|
"""
|
|
54
|
-
|
|
55
|
-
|
|
86
|
+
env_creds = {var: self._creds_handler.load_from_env(var) for var in self.keys}
|
|
87
|
+
env_creds = self._sanitize_env_vars(env_creds)
|
|
88
|
+
self._creds_handler.set_credentials(self._env, env_creds)
|
|
56
89
|
|
|
57
|
-
def
|
|
90
|
+
def _sanitize_env_vars(self, creds: dict) -> dict:
|
|
58
91
|
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
Regarding authentication parameters, the config parameter
|
|
62
|
-
takes precedence over the env variables, and the token
|
|
63
|
-
over the basic auth. Furthermore, the config parameter is
|
|
64
|
-
validated against the proper pydantic model.
|
|
92
|
+
Sanitize the env vars. We expect issuer to have the
|
|
93
|
+
form "DHCORE_ISSUER" in env.
|
|
65
94
|
|
|
66
95
|
Parameters
|
|
67
96
|
----------
|
|
68
|
-
|
|
69
|
-
|
|
97
|
+
creds : dict
|
|
98
|
+
Credentials dictionary.
|
|
70
99
|
|
|
71
100
|
Returns
|
|
72
101
|
-------
|
|
73
|
-
|
|
102
|
+
dict
|
|
74
103
|
"""
|
|
75
|
-
self.
|
|
76
|
-
self.
|
|
104
|
+
creds[CredsEnvVar.DHCORE_ENDPOINT.value] = self._sanitize_endpoint(creds[CredsEnvVar.DHCORE_ENDPOINT.value])
|
|
105
|
+
creds[CredsEnvVar.DHCORE_ISSUER.value] = self._sanitize_endpoint(creds[CredsEnvVar.DHCORE_ISSUER.value])
|
|
106
|
+
return creds
|
|
77
107
|
|
|
78
|
-
def
|
|
108
|
+
def load_file_vars(self) -> None:
|
|
79
109
|
"""
|
|
80
|
-
|
|
110
|
+
Load the credentials from the file.
|
|
111
|
+
"""
|
|
112
|
+
keys = [*self._remove_prefix_dhcore()]
|
|
113
|
+
file_creds = {var: self._creds_handler.load_from_file(var) for var in keys}
|
|
81
114
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
115
|
+
# Because in the response there is no endpoint
|
|
116
|
+
if file_creds[CredsEnvVar.DHCORE_ENDPOINT.value] is None:
|
|
117
|
+
file_creds[CredsEnvVar.DHCORE_ENDPOINT.value] = self._creds_handler.load_from_env(
|
|
118
|
+
CredsEnvVar.DHCORE_ENDPOINT.value
|
|
119
|
+
)
|
|
86
120
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
core_api_level = int(response.headers["X-Api-Level"])
|
|
93
|
-
if not (MIN_API_LEVEL <= core_api_level <= MAX_API_LEVEL):
|
|
94
|
-
raise ClientError("Backend API level not supported.")
|
|
95
|
-
if LIB_VERSION < core_api_level:
|
|
96
|
-
warn("Backend API level is higher than library version. You should consider updating the library.")
|
|
121
|
+
# Because in the response there is no personal access token
|
|
122
|
+
if file_creds[CredsEnvVar.DHCORE_PERSONAL_ACCESS_TOKEN.value] is None:
|
|
123
|
+
file_creds[CredsEnvVar.DHCORE_PERSONAL_ACCESS_TOKEN.value] = self._creds_handler.load_from_env(
|
|
124
|
+
CredsEnvVar.DHCORE_PERSONAL_ACCESS_TOKEN.value
|
|
125
|
+
)
|
|
97
126
|
|
|
98
|
-
|
|
127
|
+
file_creds = self._sanitize_file_vars(file_creds)
|
|
128
|
+
self._creds_handler.set_credentials(self._file, file_creds)
|
|
129
|
+
|
|
130
|
+
def _sanitize_file_vars(self, creds: dict) -> dict:
|
|
99
131
|
"""
|
|
100
|
-
|
|
132
|
+
Sanitize the file vars. We expect issuer, client_id and access_token and
|
|
133
|
+
refresh_token to not have the form "DHCORE_" in the file.
|
|
101
134
|
|
|
102
135
|
Parameters
|
|
103
136
|
----------
|
|
104
|
-
|
|
105
|
-
|
|
137
|
+
creds : dict
|
|
138
|
+
Credentials dictionary.
|
|
106
139
|
|
|
107
140
|
Returns
|
|
108
141
|
-------
|
|
109
|
-
|
|
110
|
-
The url.
|
|
142
|
+
dict
|
|
111
143
|
"""
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
144
|
+
creds[CredsEnvVar.DHCORE_ENDPOINT.value] = self._sanitize_endpoint(creds[CredsEnvVar.DHCORE_ENDPOINT.value])
|
|
145
|
+
creds[CredsEnvVar.DHCORE_ISSUER.value] = self._sanitize_endpoint(
|
|
146
|
+
creds[CredsEnvVar.DHCORE_ISSUER.value.removeprefix("DHCORE_")]
|
|
147
|
+
)
|
|
148
|
+
creds[CredsEnvVar.DHCORE_REFRESH_TOKEN.value] = creds[
|
|
149
|
+
CredsEnvVar.DHCORE_REFRESH_TOKEN.value.removeprefix("DHCORE_")
|
|
150
|
+
]
|
|
151
|
+
creds[CredsEnvVar.DHCORE_ACCESS_TOKEN.value] = creds[
|
|
152
|
+
CredsEnvVar.DHCORE_ACCESS_TOKEN.value.removeprefix("DHCORE_")
|
|
153
|
+
]
|
|
154
|
+
creds[CredsEnvVar.DHCORE_CLIENT_ID.value] = creds[CredsEnvVar.DHCORE_CLIENT_ID.value.removeprefix("DHCORE_")]
|
|
155
|
+
return {k: v for k, v in creds.items() if k in self.keys}
|
|
118
156
|
|
|
119
157
|
@staticmethod
|
|
120
|
-
def _sanitize_endpoint(endpoint: str) -> str:
|
|
158
|
+
def _sanitize_endpoint(endpoint: str | None = None) -> str | None:
|
|
121
159
|
"""
|
|
122
160
|
Sanitize the endpoint.
|
|
123
161
|
|
|
124
162
|
Returns
|
|
125
163
|
-------
|
|
126
|
-
None
|
|
164
|
+
str | None
|
|
165
|
+
The sanitized endpoint.
|
|
127
166
|
"""
|
|
167
|
+
if endpoint is None:
|
|
168
|
+
return
|
|
128
169
|
if not has_remote_scheme(endpoint):
|
|
129
170
|
raise ClientError("Invalid endpoint scheme. Must start with http:// or https://.")
|
|
130
171
|
|
|
131
172
|
endpoint = endpoint.strip()
|
|
132
173
|
return endpoint.removesuffix("/")
|
|
133
174
|
|
|
134
|
-
def
|
|
175
|
+
def check_config(self) -> None:
|
|
135
176
|
"""
|
|
136
|
-
|
|
177
|
+
Check if the config is valid.
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
config : dict
|
|
182
|
+
Configuration dictionary.
|
|
137
183
|
|
|
138
184
|
Returns
|
|
139
185
|
-------
|
|
140
186
|
None
|
|
187
|
+
"""
|
|
188
|
+
if (current := creds_handler.get_current_env()) != self._current_profile:
|
|
189
|
+
self.load_file_vars()
|
|
190
|
+
self._current_profile = current
|
|
141
191
|
|
|
142
|
-
|
|
143
|
-
------
|
|
144
|
-
Exception
|
|
145
|
-
If the endpoint of DHCore is not set in the env variables.
|
|
192
|
+
def get_endpoint(self) -> str:
|
|
146
193
|
"""
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
194
|
+
Get the DHCore endpoint.
|
|
195
|
+
|
|
196
|
+
Returns
|
|
197
|
+
-------
|
|
198
|
+
str
|
|
199
|
+
The endpoint.
|
|
200
|
+
"""
|
|
201
|
+
creds = self._creds_handler.get_credentials(self._origin)
|
|
202
|
+
return creds[CredsEnvVar.DHCORE_ENDPOINT.value]
|
|
152
203
|
|
|
153
|
-
|
|
204
|
+
##############################
|
|
205
|
+
# Origin methods
|
|
206
|
+
##############################
|
|
207
|
+
|
|
208
|
+
def set_origin(self) -> str:
|
|
154
209
|
"""
|
|
155
|
-
|
|
210
|
+
Evaluate the default origin from the credentials.
|
|
156
211
|
|
|
157
212
|
Returns
|
|
158
213
|
-------
|
|
159
|
-
|
|
214
|
+
str
|
|
215
|
+
The origin.
|
|
160
216
|
"""
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
217
|
+
origin = CredsOrigin.ENV.value
|
|
218
|
+
|
|
219
|
+
env_creds = self._creds_handler.get_credentials(self._env)
|
|
220
|
+
missing_env = self._check_credentials(env_creds)
|
|
221
|
+
|
|
222
|
+
file_creds = self._creds_handler.get_credentials(self._file)
|
|
223
|
+
missing_file = self._check_credentials(file_creds)
|
|
224
|
+
|
|
225
|
+
msg = ""
|
|
226
|
+
if missing_env:
|
|
227
|
+
msg = f"Missing required vars in env: {', '.join(missing_env)}"
|
|
228
|
+
origin = CredsOrigin.FILE.value
|
|
229
|
+
elif missing_file:
|
|
230
|
+
msg += f"Missing required vars in .dhcore.ini file: {', '.join(missing_file)}"
|
|
231
|
+
|
|
232
|
+
if missing_env and missing_file:
|
|
233
|
+
raise ClientError(msg)
|
|
234
|
+
|
|
235
|
+
return origin
|
|
166
236
|
|
|
167
|
-
|
|
237
|
+
def change_origin(self) -> None:
|
|
238
|
+
"""
|
|
239
|
+
Change the origin of the credentials.
|
|
240
|
+
"""
|
|
241
|
+
if self._origin == CredsOrigin.ENV.value:
|
|
242
|
+
self.change_to_file()
|
|
168
243
|
else:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
244
|
+
self.change_to_env()
|
|
245
|
+
|
|
246
|
+
# Re-evaluate the auth type
|
|
247
|
+
self.set_auth_type()
|
|
248
|
+
|
|
249
|
+
def change_to_file(self) -> None:
|
|
250
|
+
"""
|
|
251
|
+
Change the origin to file. Re-evaluate the auth type.
|
|
252
|
+
"""
|
|
253
|
+
self._origin = CredsOrigin.FILE.value
|
|
254
|
+
|
|
255
|
+
def change_to_env(self) -> None:
|
|
256
|
+
"""
|
|
257
|
+
Change the origin to env. Re-evaluate the auth type.
|
|
258
|
+
"""
|
|
259
|
+
self._origin = CredsOrigin.ENV.value
|
|
175
260
|
|
|
176
261
|
##############################
|
|
177
262
|
# Auth methods
|
|
178
263
|
##############################
|
|
179
264
|
|
|
180
|
-
def
|
|
265
|
+
def set_auth_type(self) -> None:
|
|
181
266
|
"""
|
|
182
|
-
|
|
267
|
+
Evaluate the auth type from the credentials.
|
|
183
268
|
|
|
184
269
|
Returns
|
|
185
270
|
-------
|
|
186
|
-
|
|
271
|
+
None
|
|
187
272
|
"""
|
|
188
|
-
|
|
189
|
-
|
|
273
|
+
creds = creds_handler.get_credentials(self._origin)
|
|
274
|
+
self._auth_type = self._eval_auth_type(creds)
|
|
275
|
+
# If we have an exchange token, we need to get a new access token.
|
|
276
|
+
# Therefore, we change the origin to file, where the refresh token is written.
|
|
277
|
+
# We also try to fetch the PAT from both env and file
|
|
278
|
+
if self._auth_type == AuthType.EXCHANGE.value:
|
|
279
|
+
self.get_new_access_token(change_origin=True)
|
|
280
|
+
# Just to ensure we get the right source from file
|
|
281
|
+
self.change_to_file()
|
|
190
282
|
|
|
191
|
-
def
|
|
283
|
+
def refreshable_auth_types(self) -> bool:
|
|
192
284
|
"""
|
|
193
|
-
|
|
285
|
+
Check if the auth type is refreshable.
|
|
194
286
|
|
|
195
287
|
Returns
|
|
196
288
|
-------
|
|
197
289
|
bool
|
|
290
|
+
True if the auth type is refreshable, False otherwise.
|
|
198
291
|
"""
|
|
199
|
-
|
|
200
|
-
return auth_type == AuthType.OAUTH2.value
|
|
292
|
+
return self._auth_type in [AuthType.OAUTH2.value, AuthType.EXCHANGE.value]
|
|
201
293
|
|
|
202
|
-
def
|
|
294
|
+
def get_auth_parameters(self, kwargs: dict) -> dict:
|
|
203
295
|
"""
|
|
204
|
-
Get the authentication header.
|
|
296
|
+
Get the authentication header for the request.
|
|
297
|
+
It is given for granted that the auth type is set and that,
|
|
298
|
+
if the auth type is EXCHANGE, the refresh token is set.
|
|
205
299
|
|
|
206
300
|
Parameters
|
|
207
301
|
----------
|
|
@@ -211,50 +305,78 @@ class ClientDHCoreConfigurator:
|
|
|
211
305
|
Returns
|
|
212
306
|
-------
|
|
213
307
|
dict
|
|
214
|
-
Authentication
|
|
215
|
-
"""
|
|
216
|
-
creds =
|
|
217
|
-
if
|
|
218
|
-
|
|
219
|
-
if self.basic_auth():
|
|
220
|
-
user = creds[DhcoreEnvVar.USER.value]
|
|
221
|
-
password = creds[DhcoreEnvVar.PASSWORD.value]
|
|
222
|
-
kwargs["auth"] = (user, password)
|
|
223
|
-
elif self.oauth2_auth():
|
|
308
|
+
Authentication parameters.
|
|
309
|
+
"""
|
|
310
|
+
creds = creds_handler.get_credentials(self._origin)
|
|
311
|
+
if self._auth_type in (AuthType.EXCHANGE.value, AuthType.OAUTH2.value):
|
|
312
|
+
access_token = creds[CredsEnvVar.DHCORE_ACCESS_TOKEN.value]
|
|
224
313
|
if "headers" not in kwargs:
|
|
225
314
|
kwargs["headers"] = {}
|
|
226
|
-
access_token = creds[DhcoreEnvVar.ACCESS_TOKEN.value.removeprefix("DHCORE_")]
|
|
227
315
|
kwargs["headers"]["Authorization"] = f"Bearer {access_token}"
|
|
316
|
+
elif self._auth_type == AuthType.BASIC.value:
|
|
317
|
+
user = creds[CredsEnvVar.DHCORE_USER.value]
|
|
318
|
+
password = creds[CredsEnvVar.DHCORE_PASSWORD.value]
|
|
319
|
+
kwargs["auth"] = (user, password)
|
|
228
320
|
return kwargs
|
|
229
321
|
|
|
230
|
-
def get_new_access_token(self) -> None:
|
|
322
|
+
def get_new_access_token(self, change_origin: bool = False) -> None:
|
|
231
323
|
"""
|
|
232
324
|
Get a new access token.
|
|
233
325
|
|
|
326
|
+
Parameters
|
|
327
|
+
----------
|
|
328
|
+
change_origin : bool, optional
|
|
329
|
+
Whether to change the origin of the credentials, by default False
|
|
330
|
+
|
|
234
331
|
Returns
|
|
235
332
|
-------
|
|
236
333
|
None
|
|
237
334
|
"""
|
|
238
|
-
|
|
239
|
-
|
|
335
|
+
if not self.refreshable_auth_types():
|
|
336
|
+
raise ClientError(f"Auth type {self._auth_type} does not support refresh.")
|
|
337
|
+
|
|
338
|
+
# Get refresh endpoint
|
|
240
339
|
url = self._get_refresh_endpoint()
|
|
241
340
|
|
|
242
|
-
#
|
|
243
|
-
|
|
244
|
-
refresh_token = configurator.load_from_env(DhcoreEnvVar.REFRESH_TOKEN.value)
|
|
245
|
-
response = self._call_refresh_token_endpoint(url, refresh_token)
|
|
341
|
+
# Get credentials
|
|
342
|
+
creds = self._creds_handler.get_credentials(self._origin)
|
|
246
343
|
|
|
247
|
-
#
|
|
344
|
+
# Get client id
|
|
345
|
+
if (client_id := creds.get(CredsEnvVar.DHCORE_CLIENT_ID.value)) is None:
|
|
346
|
+
raise ClientError("Client id not set.")
|
|
347
|
+
|
|
348
|
+
# Handling of token exchange or refresh
|
|
349
|
+
if self._auth_type == AuthType.OAUTH2.value:
|
|
350
|
+
response = self._call_refresh_token_endpoint(
|
|
351
|
+
url,
|
|
352
|
+
client_id=client_id,
|
|
353
|
+
refresh_token=creds.get(CredsEnvVar.DHCORE_REFRESH_TOKEN.value),
|
|
354
|
+
grant_type="refresh_token",
|
|
355
|
+
scope="credentials",
|
|
356
|
+
)
|
|
357
|
+
elif self._auth_type == AuthType.EXCHANGE.value:
|
|
358
|
+
response = self._call_refresh_token_endpoint(
|
|
359
|
+
url,
|
|
360
|
+
client_id=client_id,
|
|
361
|
+
subject_token=creds.get(CredsEnvVar.DHCORE_PERSONAL_ACCESS_TOKEN.value),
|
|
362
|
+
subject_token_type="urn:ietf:params:oauth:token-type:pat",
|
|
363
|
+
grant_type="urn:ietf:params:oauth:grant-type:token-exchange",
|
|
364
|
+
scope="credentials",
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
# Change origin of creds if needed
|
|
248
368
|
if response.status_code in (400, 401, 403):
|
|
249
|
-
|
|
250
|
-
|
|
369
|
+
if not change_origin:
|
|
370
|
+
raise ClientError("Unable to refresh token. Please check your credentials.")
|
|
371
|
+
self.change_origin()
|
|
372
|
+
self.get_new_access_token(change_origin=False)
|
|
251
373
|
|
|
252
374
|
response.raise_for_status()
|
|
253
375
|
|
|
254
376
|
# Read new credentials and propagate to config file
|
|
255
|
-
self.
|
|
377
|
+
self._export_new_creds(response.json())
|
|
256
378
|
|
|
257
|
-
def
|
|
379
|
+
def _export_new_creds(self, response: dict) -> None:
|
|
258
380
|
"""
|
|
259
381
|
Set new credentials.
|
|
260
382
|
|
|
@@ -267,17 +389,13 @@ class ClientDHCoreConfigurator:
|
|
|
267
389
|
-------
|
|
268
390
|
None
|
|
269
391
|
"""
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
*list_enum(S3StoreEnv),
|
|
273
|
-
*list_enum(SqlStoreEnv),
|
|
274
|
-
]
|
|
275
|
-
for key in keys:
|
|
276
|
-
if (value := response.get(key.lower())) is not None:
|
|
277
|
-
configurator.set_credential(key, value)
|
|
278
|
-
configurator.write_env(keys)
|
|
392
|
+
creds_handler.write_env(response)
|
|
393
|
+
self.load_file_vars()
|
|
279
394
|
|
|
280
|
-
|
|
395
|
+
# Change current origin to file because of refresh
|
|
396
|
+
self._origin = CredsOrigin.FILE.value
|
|
397
|
+
|
|
398
|
+
def _remove_prefix_dhcore(self) -> list[str]:
|
|
281
399
|
"""
|
|
282
400
|
Remove prefix from selected keys. (Compatibility with CLI)
|
|
283
401
|
|
|
@@ -292,13 +410,8 @@ class ClientDHCoreConfigurator:
|
|
|
292
410
|
List of keys without prefix.
|
|
293
411
|
"""
|
|
294
412
|
new_list = []
|
|
295
|
-
for key in keys:
|
|
296
|
-
if key in
|
|
297
|
-
DhcoreEnvVar.REFRESH_TOKEN.value,
|
|
298
|
-
DhcoreEnvVar.ACCESS_TOKEN.value,
|
|
299
|
-
DhcoreEnvVar.ISSUER.value,
|
|
300
|
-
DhcoreEnvVar.CLIENT_ID.value,
|
|
301
|
-
):
|
|
413
|
+
for key in self.keys:
|
|
414
|
+
if key in self.keys_to_unprefix:
|
|
302
415
|
new_list.append(key.removeprefix("DHCORE_"))
|
|
303
416
|
else:
|
|
304
417
|
new_list.append(key)
|
|
@@ -314,11 +427,10 @@ class ClientDHCoreConfigurator:
|
|
|
314
427
|
Refresh endpoint.
|
|
315
428
|
"""
|
|
316
429
|
# Get issuer endpoint
|
|
317
|
-
|
|
430
|
+
creds = self._creds_handler.get_credentials(self._origin)
|
|
431
|
+
endpoint_issuer = creds.get(CredsEnvVar.DHCORE_ISSUER.value)
|
|
318
432
|
if endpoint_issuer is None:
|
|
319
433
|
raise ClientError("Issuer endpoint not set.")
|
|
320
|
-
endpoint_issuer = self._sanitize_endpoint(endpoint_issuer)
|
|
321
|
-
configurator.set_credential(DhcoreEnvVar.ISSUER.value.removeprefix("DHCORE_"), endpoint_issuer)
|
|
322
434
|
|
|
323
435
|
# Standard issuer endpoint path
|
|
324
436
|
url = endpoint_issuer + "/.well-known/openid-configuration"
|
|
@@ -328,7 +440,11 @@ class ClientDHCoreConfigurator:
|
|
|
328
440
|
r.raise_for_status()
|
|
329
441
|
return r.json().get("token_endpoint")
|
|
330
442
|
|
|
331
|
-
def _call_refresh_token_endpoint(
|
|
443
|
+
def _call_refresh_token_endpoint(
|
|
444
|
+
self,
|
|
445
|
+
url: str,
|
|
446
|
+
**kwargs,
|
|
447
|
+
) -> Response:
|
|
332
448
|
"""
|
|
333
449
|
Call the refresh token endpoint.
|
|
334
450
|
|
|
@@ -336,44 +452,27 @@ class ClientDHCoreConfigurator:
|
|
|
336
452
|
----------
|
|
337
453
|
url : str
|
|
338
454
|
Refresh token endpoint.
|
|
339
|
-
|
|
340
|
-
|
|
455
|
+
kwargs : dict
|
|
456
|
+
Keyword arguments to pass to the request.
|
|
341
457
|
|
|
342
458
|
Returns
|
|
343
459
|
-------
|
|
344
460
|
Response
|
|
345
461
|
Response object.
|
|
346
462
|
"""
|
|
347
|
-
# Get client id
|
|
348
|
-
client_id = self._load_dhcore_oauth_vars(DhcoreEnvVar.CLIENT_ID.value)
|
|
349
|
-
if client_id is None:
|
|
350
|
-
raise ClientError("Client id not set.")
|
|
351
|
-
|
|
352
463
|
# Send request to get new access token
|
|
353
|
-
payload = {
|
|
354
|
-
"grant_type": "refresh_token",
|
|
355
|
-
"client_id": client_id,
|
|
356
|
-
"refresh_token": refresh_token,
|
|
357
|
-
"scope": "openid credentials offline_access",
|
|
358
|
-
}
|
|
464
|
+
payload = {**kwargs}
|
|
359
465
|
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
|
360
466
|
return request("POST", url, data=payload, headers=headers, timeout=60)
|
|
361
467
|
|
|
362
|
-
def
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
str
|
|
374
|
-
The oauth variable.
|
|
375
|
-
"""
|
|
376
|
-
read_var = configurator.load_from_env(oauth_var)
|
|
377
|
-
if read_var is None:
|
|
378
|
-
read_var = configurator.load_from_file(oauth_var.removeprefix("DHCORE_"))
|
|
379
|
-
return read_var
|
|
468
|
+
def _eval_auth_type(self, creds: dict) -> str | None:
|
|
469
|
+
if creds[CredsEnvVar.DHCORE_PERSONAL_ACCESS_TOKEN.value] is not None:
|
|
470
|
+
return AuthType.EXCHANGE.value
|
|
471
|
+
if (
|
|
472
|
+
creds[CredsEnvVar.DHCORE_ACCESS_TOKEN.value] is not None
|
|
473
|
+
and creds[CredsEnvVar.DHCORE_REFRESH_TOKEN.value] is not None
|
|
474
|
+
):
|
|
475
|
+
return AuthType.OAUTH2.value
|
|
476
|
+
if creds[CredsEnvVar.DHCORE_USER.value] is not None and creds[CredsEnvVar.DHCORE_PASSWORD.value] is not None:
|
|
477
|
+
return AuthType.BASIC.value
|
|
478
|
+
return None
|
|
@@ -1,3 +1,7 @@
|
|
|
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
|
from enum import Enum
|
|
@@ -15,6 +19,7 @@ class DhcoreEnvVar(Enum):
|
|
|
15
19
|
CLIENT_ID = "DHCORE_CLIENT_ID"
|
|
16
20
|
ACCESS_TOKEN = "DHCORE_ACCESS_TOKEN"
|
|
17
21
|
REFRESH_TOKEN = "DHCORE_REFRESH_TOKEN"
|
|
22
|
+
PERSONAL_ACCESS_TOKEN = "DHCORE_PERSONAL_ACCESS_TOKEN"
|
|
18
23
|
WORKFLOW_IMAGE = "DHCORE_WORKFLOW_IMAGE"
|
|
19
24
|
|
|
20
25
|
|
|
@@ -25,3 +30,4 @@ class AuthType(Enum):
|
|
|
25
30
|
|
|
26
31
|
BASIC = "basic"
|
|
27
32
|
OAUTH2 = "oauth2"
|
|
33
|
+
EXCHANGE = "exchange"
|