cmem-client 0.5.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.
- cmem_client/__init__.py +13 -0
- cmem_client/auth_provider/__init__.py +14 -0
- cmem_client/auth_provider/abc.py +124 -0
- cmem_client/auth_provider/client_credentials.py +207 -0
- cmem_client/auth_provider/password.py +252 -0
- cmem_client/auth_provider/prefetched_token.py +153 -0
- cmem_client/client.py +485 -0
- cmem_client/components/__init__.py +10 -0
- cmem_client/components/graph_store.py +316 -0
- cmem_client/components/marketplace.py +179 -0
- cmem_client/components/sparql_wrapper.py +53 -0
- cmem_client/components/workspace.py +194 -0
- cmem_client/config.py +364 -0
- cmem_client/exceptions.py +82 -0
- cmem_client/logging_utils.py +49 -0
- cmem_client/models/__init__.py +16 -0
- cmem_client/models/access_condition.py +147 -0
- cmem_client/models/base.py +30 -0
- cmem_client/models/dataset.py +32 -0
- cmem_client/models/error.py +67 -0
- cmem_client/models/graph.py +26 -0
- cmem_client/models/item.py +143 -0
- cmem_client/models/logging_config.py +51 -0
- cmem_client/models/package.py +35 -0
- cmem_client/models/project.py +46 -0
- cmem_client/models/python_package.py +26 -0
- cmem_client/models/token.py +40 -0
- cmem_client/models/url.py +34 -0
- cmem_client/models/workflow.py +80 -0
- cmem_client/repositories/__init__.py +15 -0
- cmem_client/repositories/access_conditions.py +62 -0
- cmem_client/repositories/base/__init__.py +12 -0
- cmem_client/repositories/base/abc.py +138 -0
- cmem_client/repositories/base/paged_list.py +63 -0
- cmem_client/repositories/base/plain_list.py +39 -0
- cmem_client/repositories/base/task_search.py +70 -0
- cmem_client/repositories/datasets.py +36 -0
- cmem_client/repositories/graph_imports.py +93 -0
- cmem_client/repositories/graphs.py +458 -0
- cmem_client/repositories/marketplace_packages.py +486 -0
- cmem_client/repositories/projects.py +214 -0
- cmem_client/repositories/protocols/__init__.py +15 -0
- cmem_client/repositories/protocols/create_item.py +125 -0
- cmem_client/repositories/protocols/delete_item.py +95 -0
- cmem_client/repositories/protocols/export_item.py +114 -0
- cmem_client/repositories/protocols/import_item.py +141 -0
- cmem_client/repositories/python_packages.py +58 -0
- cmem_client/repositories/workflows.py +143 -0
- cmem_client-0.5.0.dist-info/METADATA +64 -0
- cmem_client-0.5.0.dist-info/RECORD +52 -0
- cmem_client-0.5.0.dist-info/WHEEL +4 -0
- cmem_client-0.5.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""Prefetched token authentication provider.
|
|
2
|
+
|
|
3
|
+
This module provides an authentication provider for scenarios where access tokens
|
|
4
|
+
are obtained through external means rather than through OAuth flows. This is useful
|
|
5
|
+
for environments where tokens are managed by external systems, CI/CD pipelines,
|
|
6
|
+
or when integrating with existing authentication infrastructure.
|
|
7
|
+
|
|
8
|
+
The PrefetchedToken provider simply stores and returns a pre-obtained access token
|
|
9
|
+
without performing any token refresh or validation. It's the responsibility of the
|
|
10
|
+
external system to ensure the token is valid and renewed when necessary.
|
|
11
|
+
|
|
12
|
+
This approach is often used in containerized environments, serverless functions,
|
|
13
|
+
or when tokens are managed by orchestration platforms.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import logging
|
|
17
|
+
from os import getenv
|
|
18
|
+
|
|
19
|
+
from cmem_client.auth_provider.abc import AuthProvider
|
|
20
|
+
from cmem_client.config import Config
|
|
21
|
+
from cmem_client.exceptions import ClientEnvConfigError
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class PrefetchedToken(AuthProvider):
|
|
25
|
+
"""Authentication provider for externally managed access tokens.
|
|
26
|
+
|
|
27
|
+
PrefetchedToken is designed for scenarios where access tokens are obtained
|
|
28
|
+
and managed by external systems rather than through standard OAuth 2.0 flows.
|
|
29
|
+
This provider simply stores and returns a pre-obtained token without performing
|
|
30
|
+
any validation, refresh, or expiration checking.
|
|
31
|
+
|
|
32
|
+
This approach is commonly used in:
|
|
33
|
+
- Containerized environments where tokens are injected at runtime
|
|
34
|
+
- CI/CD pipelines with token management systems
|
|
35
|
+
- Serverless functions with external authentication services
|
|
36
|
+
- Integration with existing authentication infrastructure
|
|
37
|
+
- Short-lived execution contexts where token refresh isn't needed
|
|
38
|
+
|
|
39
|
+
Attributes:
|
|
40
|
+
prefetched_token: The pre-obtained access token to be used for authentication.
|
|
41
|
+
|
|
42
|
+
Important Notes:
|
|
43
|
+
- No token validation or expiration checking is performed
|
|
44
|
+
- Token refresh is not supported; external systems must handle renewal
|
|
45
|
+
- The token is assumed to be valid and properly formatted
|
|
46
|
+
- Suitable for short-lived processes or external token management scenarios
|
|
47
|
+
|
|
48
|
+
See Also:
|
|
49
|
+
For automatic token management with refresh capabilities, consider using
|
|
50
|
+
ClientCredentialsFlow or PasswordFlow instead.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
prefetched_token: str
|
|
54
|
+
"""The pre-obtained access token used for authentication requests."""
|
|
55
|
+
|
|
56
|
+
logger: logging.Logger
|
|
57
|
+
"""Logger object for logging."""
|
|
58
|
+
|
|
59
|
+
def __init__(self, prefetched_token: str) -> None:
|
|
60
|
+
"""Initialize a new Prefetched Token authentication provider.
|
|
61
|
+
|
|
62
|
+
Creates a provider instance that stores the given access token for use
|
|
63
|
+
in authentication requests. No validation or processing is performed
|
|
64
|
+
on the token; it is stored as-is.
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
prefetched_token: A pre-obtained access token string. The token
|
|
68
|
+
should be valid, properly formatted (typically JWT), and
|
|
69
|
+
have appropriate permissions for Corporate Memory operations.
|
|
70
|
+
|
|
71
|
+
Note:
|
|
72
|
+
Unlike other authentication providers, this constructor does not
|
|
73
|
+
make any network requests or perform token validation. The token
|
|
74
|
+
is assumed to be valid and ready for immediate use.
|
|
75
|
+
"""
|
|
76
|
+
self.prefetched_token = prefetched_token
|
|
77
|
+
self.logger: logging.Logger = logging.getLogger(__name__)
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_env(cls, config: Config) -> "PrefetchedToken": # noqa: ARG003
|
|
81
|
+
"""Create a Prefetched Token provider from environment variables.
|
|
82
|
+
|
|
83
|
+
This factory method creates a provider instance by reading a pre-obtained
|
|
84
|
+
access token from the OAUTH_ACCESS_TOKEN environment variable.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
config: Corporate Memory configuration object. Note that this parameter
|
|
88
|
+
is not used by PrefetchedToken but is required to maintain
|
|
89
|
+
consistency with other AuthProvider implementations.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
A configured PrefetchedToken instance ready for use.
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
ClientEnvConfigError: If the required OAUTH_ACCESS_TOKEN environment
|
|
96
|
+
variable is not set or is empty.
|
|
97
|
+
|
|
98
|
+
Environment Variables:
|
|
99
|
+
OAUTH_ACCESS_TOKEN (required): The pre-obtained access token.
|
|
100
|
+
Should be a valid JWT or other token format accepted by
|
|
101
|
+
Corporate Memory. The token must have appropriate permissions
|
|
102
|
+
for the intended operations.
|
|
103
|
+
|
|
104
|
+
Use Cases:
|
|
105
|
+
- Docker containers with token injection
|
|
106
|
+
- Kubernetes pods with secret mounting
|
|
107
|
+
- CI/CD pipelines with secure token storage
|
|
108
|
+
- Serverless functions with environment-based configuration
|
|
109
|
+
- Integration with external token management systems
|
|
110
|
+
"""
|
|
111
|
+
oauth_access_token = getenv("OAUTH_ACCESS_TOKEN")
|
|
112
|
+
if not oauth_access_token:
|
|
113
|
+
raise ClientEnvConfigError("Need OAUTH_ACCESS_TOKEN environment variable.")
|
|
114
|
+
return cls(prefetched_token=oauth_access_token)
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
def from_cmempy(cls, config: Config) -> "PrefetchedToken": # noqa: ARG003
|
|
118
|
+
"""Create a Prefetched Token provider from a cmempy environment."""
|
|
119
|
+
try:
|
|
120
|
+
import cmem.cmempy.config as cmempy_config # noqa: PLC0415
|
|
121
|
+
except ImportError as error:
|
|
122
|
+
raise OSError("cmempy is not installed.") from error
|
|
123
|
+
oauth_access_token = cmempy_config.get_oauth_access_token()
|
|
124
|
+
if not oauth_access_token:
|
|
125
|
+
raise ClientEnvConfigError("Need OAUTH_ACCESS_TOKEN environment variable.")
|
|
126
|
+
return cls(prefetched_token=oauth_access_token)
|
|
127
|
+
|
|
128
|
+
def get_access_token(self) -> str:
|
|
129
|
+
"""Get the prefetched access token for Bearer Authorization header.
|
|
130
|
+
|
|
131
|
+
Returns the stored access token without any validation, refresh, or
|
|
132
|
+
expiration checking. The token is returned as-is, exactly as it was
|
|
133
|
+
provided during initialization.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
The prefetched access token string ready for use in HTTP
|
|
137
|
+
Authorization headers.
|
|
138
|
+
|
|
139
|
+
Important Notes:
|
|
140
|
+
- No validation is performed on the token
|
|
141
|
+
- No expiration checking is done
|
|
142
|
+
- No automatic refresh capability
|
|
143
|
+
- The token is assumed to be valid and current
|
|
144
|
+
- External systems are responsible for token lifecycle management
|
|
145
|
+
|
|
146
|
+
Limitations:
|
|
147
|
+
Unlike other AuthProvider implementations, this method does not:
|
|
148
|
+
- Check token expiration
|
|
149
|
+
- Refresh expired tokens
|
|
150
|
+
- Validate token format
|
|
151
|
+
- Handle token renewal
|
|
152
|
+
"""
|
|
153
|
+
return self.prefetched_token
|
cmem_client/client.py
ADDED
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
"""Main API client for eccenca Corporate Memory.
|
|
2
|
+
|
|
3
|
+
This module provides the primary Client class that serves as the central interface
|
|
4
|
+
for interacting with eccenca Corporate Memory instances. The Client orchestrates
|
|
5
|
+
authentication, HTTP communication, and provides access to various service components
|
|
6
|
+
like workspaces and graph stores.
|
|
7
|
+
|
|
8
|
+
The Client uses lazy loading for its components and can be configured either manually
|
|
9
|
+
or automatically from environment variables, making it flexible for different
|
|
10
|
+
deployment scenarios.
|
|
11
|
+
|
|
12
|
+
Examples:
|
|
13
|
+
>>> from os import environ
|
|
14
|
+
>>> from cmem_client.models.url import HttpUrl
|
|
15
|
+
>>> from cmem_client.auth_provider.client_credentials import ClientCredentialsFlow
|
|
16
|
+
>>> config = Config(url_base=HttpUrl(environ.get("TESTING_BASE_URL")))
|
|
17
|
+
>>> client = Client(config=config)
|
|
18
|
+
>>> client_id = environ.get("TESTING_CCF_CLIENT_ID")
|
|
19
|
+
>>> client_secret = environ.get("TESTING_CCF_CLIENT_SECRET")
|
|
20
|
+
>>> client.auth = ClientCredentialsFlow(config=config, client_id=client_id, client_secret=client_secret)
|
|
21
|
+
>>> # Client is now configured with oauth provider from environment
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import json
|
|
27
|
+
import logging
|
|
28
|
+
from logging.config import dictConfig
|
|
29
|
+
from logging.handlers import RotatingFileHandler
|
|
30
|
+
from pathlib import Path
|
|
31
|
+
from typing import Any, ClassVar
|
|
32
|
+
|
|
33
|
+
import httpx
|
|
34
|
+
|
|
35
|
+
from cmem_client.auth_provider.abc import AuthProvider
|
|
36
|
+
from cmem_client.components.graph_store import GraphStore
|
|
37
|
+
from cmem_client.components.marketplace import Marketplace
|
|
38
|
+
from cmem_client.components.workspace import BuildWorkspace
|
|
39
|
+
from cmem_client.config import Config
|
|
40
|
+
from cmem_client.exceptions import ClientNoAuthProviderError
|
|
41
|
+
from cmem_client.logging_utils import install_trace_logger
|
|
42
|
+
from cmem_client.models.logging_config import LoggingConfig
|
|
43
|
+
from cmem_client.repositories.graph_imports import GraphImportsRepository
|
|
44
|
+
from cmem_client.repositories.graphs import GraphsRepository
|
|
45
|
+
from cmem_client.repositories.marketplace_packages import MarketplacePackagesRepository
|
|
46
|
+
from cmem_client.repositories.projects import ProjectsRepository
|
|
47
|
+
from cmem_client.repositories.python_packages import PythonPackagesRepository
|
|
48
|
+
from cmem_client.repositories.workflows import WorkflowsRepository
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class Client:
|
|
52
|
+
"""API Client for eccenca Corporate Memory.
|
|
53
|
+
|
|
54
|
+
The Client class provides the main interface for interacting with eccenca
|
|
55
|
+
Corporate Memory instances. It manages authentication, HTTP communication,
|
|
56
|
+
and provides access to various service components through lazy-loaded properties.
|
|
57
|
+
|
|
58
|
+
The client follows a lazy initialization pattern where components are only
|
|
59
|
+
created when first accessed, improving performance and reducing unnecessary
|
|
60
|
+
resource allocation.
|
|
61
|
+
|
|
62
|
+
Attributes:
|
|
63
|
+
config: Configuration object containing URLs and connection settings.
|
|
64
|
+
_headers: Class-level dictionary of HTTP headers shared across instances.
|
|
65
|
+
_auth: Authentication provider for obtaining access tokens.
|
|
66
|
+
_http: HTTP client instance for making API requests.
|
|
67
|
+
_workspace: DataIntegration workspace component for build operations.
|
|
68
|
+
_store: DataPlatform graph store component for explore operations.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
config: Config
|
|
72
|
+
"""Configuration object containing URLs, timeouts, and SSL settings."""
|
|
73
|
+
|
|
74
|
+
_logger: logging.Logger
|
|
75
|
+
"""Logger object for configuring logging."""
|
|
76
|
+
|
|
77
|
+
_headers: ClassVar[dict] = {}
|
|
78
|
+
"""Class-level HTTP headers dictionary shared across all client instances."""
|
|
79
|
+
|
|
80
|
+
_auth: AuthProvider
|
|
81
|
+
"""Authentication provider responsible for token management and refresh."""
|
|
82
|
+
|
|
83
|
+
_http: httpx.Client
|
|
84
|
+
"""HTTP client instance configured with headers, SSL settings, and timeouts."""
|
|
85
|
+
|
|
86
|
+
_workspace: BuildWorkspace
|
|
87
|
+
"""DataIntegration workspace component for project and dataset operations."""
|
|
88
|
+
|
|
89
|
+
_store: GraphStore
|
|
90
|
+
"""DataPlatform graph store component for RDF graph operations."""
|
|
91
|
+
|
|
92
|
+
_graphs: GraphsRepository
|
|
93
|
+
"""Graph repository for graphs."""
|
|
94
|
+
|
|
95
|
+
_graph_imports: GraphImportsRepository
|
|
96
|
+
"""Graph Imports repository"""
|
|
97
|
+
|
|
98
|
+
_vocabularies: GraphsRepository
|
|
99
|
+
"""Graph repository configured for vocabulary import and export operations."""
|
|
100
|
+
|
|
101
|
+
_marketplace_packages: MarketplacePackagesRepository
|
|
102
|
+
"""MarketplacePackagesRepository object for marketplace package operations."""
|
|
103
|
+
|
|
104
|
+
_python_packages: PythonPackagesRepository
|
|
105
|
+
"""PythonPackageRepository object for python package operations."""
|
|
106
|
+
|
|
107
|
+
_projects: ProjectsRepository
|
|
108
|
+
"""ProjectsRepository object for project operations."""
|
|
109
|
+
|
|
110
|
+
_marketplace: Marketplace
|
|
111
|
+
"""Marketplace repository object for marketplace server operations."""
|
|
112
|
+
|
|
113
|
+
_workflows: WorkflowsRepository
|
|
114
|
+
"""WorkflowsRepository object for workflow operations."""
|
|
115
|
+
|
|
116
|
+
def __init__(
|
|
117
|
+
self,
|
|
118
|
+
config: Config,
|
|
119
|
+
logger: logging.Logger | None = None,
|
|
120
|
+
) -> None:
|
|
121
|
+
"""Initialize a new Client instance.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
config: Configuration object containing base URLs, SSL settings,
|
|
125
|
+
and other connection parameters.
|
|
126
|
+
logger: Optional Logger object for configuring logging.
|
|
127
|
+
|
|
128
|
+
Note:
|
|
129
|
+
The client requires an authentication provider to be set after
|
|
130
|
+
initialization before it can make authenticated requests.
|
|
131
|
+
"""
|
|
132
|
+
self.config = config
|
|
133
|
+
self._logger = logger or logging.getLogger(__name__)
|
|
134
|
+
install_trace_logger()
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def logger(self) -> logging.Logger:
|
|
138
|
+
"""Return the configured logger."""
|
|
139
|
+
return self._logger
|
|
140
|
+
|
|
141
|
+
@classmethod
|
|
142
|
+
def from_env(cls, logger: logging.Logger | None = None) -> Client:
|
|
143
|
+
"""Create a client instance configured from environment variables.
|
|
144
|
+
|
|
145
|
+
This factory method creates a fully configured client by reading
|
|
146
|
+
configuration and authentication settings from environment variables.
|
|
147
|
+
It's the recommended way to create clients in most applications.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
logger: Optional Logger object for configuring logging.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
A fully configured Client instance with authentication provider
|
|
154
|
+
automatically set based on environment variables.
|
|
155
|
+
|
|
156
|
+
Raises:
|
|
157
|
+
ClientEnvConfigError: If required environment variables are missing.
|
|
158
|
+
|
|
159
|
+
Examples:
|
|
160
|
+
>>> my_client = Client.from_env() # Uses CMEM_BASE_URI, OAUTH_* vars
|
|
161
|
+
>>> store_info = my_client.store.self_information
|
|
162
|
+
"""
|
|
163
|
+
logger_instance = logger or logging.getLogger(__name__)
|
|
164
|
+
config = Config.from_env()
|
|
165
|
+
client = cls(config=config, logger=logger_instance)
|
|
166
|
+
client.auth = AuthProvider.from_env(config=config)
|
|
167
|
+
logger_instance.info("Initialized Client from environment")
|
|
168
|
+
return client
|
|
169
|
+
|
|
170
|
+
@classmethod
|
|
171
|
+
def from_cmempy(cls, logger: logging.Logger | None = None) -> Client:
|
|
172
|
+
"""Create a client instance configured from a cmempy environment."""
|
|
173
|
+
logger_instance = logger or logging.getLogger(__name__)
|
|
174
|
+
config = Config.from_cmempy()
|
|
175
|
+
client = Client(config=config, logger=logger_instance)
|
|
176
|
+
client.auth = AuthProvider.from_cmempy(config=config)
|
|
177
|
+
logger_instance.info("Initialized Client from cmempy")
|
|
178
|
+
return client
|
|
179
|
+
|
|
180
|
+
def configure_client_logger(
|
|
181
|
+
self,
|
|
182
|
+
level: str | int = "INFO",
|
|
183
|
+
format_string: str | None = None,
|
|
184
|
+
handlers: list[logging.Handler] | None = None,
|
|
185
|
+
filename: str | Path | None = None,
|
|
186
|
+
) -> None:
|
|
187
|
+
"""Configure logging for the client's loggger and its decendants.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
level: Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) or int
|
|
191
|
+
format_string: Custom log format string
|
|
192
|
+
handlers: List of custom handlers (if provided, overrides filename)
|
|
193
|
+
filename: Path to log file (creates FileHandler if provided)
|
|
194
|
+
|
|
195
|
+
Examples:
|
|
196
|
+
>>> Client.configure_client_logger(level="DEBUG")
|
|
197
|
+
>>> Client.configure_client_logger(level="INFO", filename="cmem.log")
|
|
198
|
+
"""
|
|
199
|
+
self.logger.setLevel(level)
|
|
200
|
+
self.logger.handlers.clear()
|
|
201
|
+
|
|
202
|
+
if format_string is None:
|
|
203
|
+
# Default logging format
|
|
204
|
+
format_string = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
205
|
+
formatter = logging.Formatter(format_string)
|
|
206
|
+
|
|
207
|
+
if handlers is not None:
|
|
208
|
+
for handler in handlers:
|
|
209
|
+
if handler.formatter is None:
|
|
210
|
+
handler.setFormatter(formatter)
|
|
211
|
+
self.logger.addHandler(handler)
|
|
212
|
+
elif filename is not None:
|
|
213
|
+
# Use RotatingFileHandler for production (https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/)
|
|
214
|
+
file_handler = RotatingFileHandler(str(filename))
|
|
215
|
+
file_handler.setFormatter(formatter)
|
|
216
|
+
self.logger.addHandler(file_handler)
|
|
217
|
+
else:
|
|
218
|
+
# Default use console logging
|
|
219
|
+
console_handler = logging.StreamHandler()
|
|
220
|
+
console_handler.setFormatter(formatter)
|
|
221
|
+
self.logger.addHandler(console_handler)
|
|
222
|
+
|
|
223
|
+
def configure_logging_from_dict(self, config: dict[str, Any]) -> None:
|
|
224
|
+
"""Configure logging for the client.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
config: Dictionary of logging configuration
|
|
228
|
+
"""
|
|
229
|
+
validated_config = LoggingConfig(**config)
|
|
230
|
+
dictConfig(validated_config.model_dump(by_alias=True, exclude_none=True))
|
|
231
|
+
|
|
232
|
+
def configure_logging_from_json(self, json_config: Path) -> None:
|
|
233
|
+
"""Configure logging for the client via a json file.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
json_config: Path to json configuration file
|
|
237
|
+
"""
|
|
238
|
+
with Path.open(json_config, "r") as json_file:
|
|
239
|
+
config_dict = json.load(json_file)
|
|
240
|
+
self.configure_logging_from_dict(config_dict)
|
|
241
|
+
|
|
242
|
+
def get_new_httpx_client(self) -> httpx.Client:
|
|
243
|
+
"""Create a new HTTP client instance with current configuration.
|
|
244
|
+
|
|
245
|
+
Creates a fresh httpx.Client instance configured with the current
|
|
246
|
+
headers, SSL verification settings, and timeout values from the
|
|
247
|
+
client configuration.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
A new httpx.Client instance ready for making HTTP requests.
|
|
251
|
+
|
|
252
|
+
Note:
|
|
253
|
+
This method is called internally when the auth provider changes
|
|
254
|
+
or when the HTTP client needs to be refreshed with new headers.
|
|
255
|
+
"""
|
|
256
|
+
return httpx.Client(headers=self._headers, verify=self.config.verify, timeout=self.config.timeout)
|
|
257
|
+
|
|
258
|
+
@property
|
|
259
|
+
def http(self) -> httpx.Client:
|
|
260
|
+
"""Get the HTTP client instance for making API requests.
|
|
261
|
+
|
|
262
|
+
Returns the configured HTTP client, creating it lazily on first access.
|
|
263
|
+
The client is pre-configured with authentication headers, SSL settings,
|
|
264
|
+
and timeout values.
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
The httpx.Client instance configured for this client.
|
|
268
|
+
|
|
269
|
+
Note:
|
|
270
|
+
The HTTP client is automatically recreated when the authentication
|
|
271
|
+
provider is changed to ensure headers are updated.
|
|
272
|
+
"""
|
|
273
|
+
try:
|
|
274
|
+
return self._http
|
|
275
|
+
except AttributeError:
|
|
276
|
+
self._http = self.get_new_httpx_client()
|
|
277
|
+
return self._http
|
|
278
|
+
|
|
279
|
+
@property
|
|
280
|
+
def auth(self) -> AuthProvider:
|
|
281
|
+
"""Get the current authentication provider.
|
|
282
|
+
|
|
283
|
+
Returns the authentication provider responsible for obtaining and
|
|
284
|
+
refreshing access tokens for API requests.
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
The currently configured AuthProvider instance.
|
|
288
|
+
|
|
289
|
+
Raises:
|
|
290
|
+
ClientNoAuthProviderError: If no authentication provider has been
|
|
291
|
+
set on this client instance.
|
|
292
|
+
|
|
293
|
+
Note:
|
|
294
|
+
An authentication provider must be set before the client can make
|
|
295
|
+
authenticated API requests. Use Client.from_env() for automatic
|
|
296
|
+
configuration or set the auth property manually.
|
|
297
|
+
"""
|
|
298
|
+
try:
|
|
299
|
+
return self._auth
|
|
300
|
+
except AttributeError as error:
|
|
301
|
+
raise ClientNoAuthProviderError from error
|
|
302
|
+
|
|
303
|
+
@auth.setter
|
|
304
|
+
def auth(self, value: AuthProvider) -> None:
|
|
305
|
+
"""Set the authentication provider for this client.
|
|
306
|
+
|
|
307
|
+
Setting a new authentication provider will immediately fetch an access
|
|
308
|
+
token and update the HTTP client with the new authorization header.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
value: The AuthProvider instance to use for authentication.
|
|
312
|
+
|
|
313
|
+
Note:
|
|
314
|
+
Setting a new auth provider will refresh the HTTP client to ensure
|
|
315
|
+
the new authorization headers are applied to all future requests.
|
|
316
|
+
"""
|
|
317
|
+
self.logger.debug("Setting a new auth provider for this client: '%s'", value.__class__.__name__)
|
|
318
|
+
self._auth = value
|
|
319
|
+
self._auth.logger = logging.getLogger(f"{self.logger.name}.{self._auth.__class__.__name__}")
|
|
320
|
+
self._headers["Authorization"] = f"Bearer {self.auth.get_access_token()}"
|
|
321
|
+
self._http = self.get_new_httpx_client()
|
|
322
|
+
|
|
323
|
+
@property
|
|
324
|
+
def workspace(self) -> BuildWorkspace:
|
|
325
|
+
"""Get the DataIntegration (build) workspace component.
|
|
326
|
+
|
|
327
|
+
Returns the BuildWorkspace component for managing Corporate Memory's
|
|
328
|
+
DataIntegration workspace, including projects, datasets, transformations,
|
|
329
|
+
and workspace-level import/export operations.
|
|
330
|
+
|
|
331
|
+
Returns:
|
|
332
|
+
The BuildWorkspace component instance, created lazily on first access.
|
|
333
|
+
|
|
334
|
+
Examples:
|
|
335
|
+
>>> from pathlib import Path
|
|
336
|
+
>>> client = Client.from_env()
|
|
337
|
+
>>> client.workspace.import_from_zip(Path("backup.zip"))
|
|
338
|
+
>>> client.workspace.export_to_zip(Path("new_backup.zip"))
|
|
339
|
+
"""
|
|
340
|
+
try:
|
|
341
|
+
return self._workspace
|
|
342
|
+
except AttributeError:
|
|
343
|
+
self._workspace = BuildWorkspace(client=self)
|
|
344
|
+
return self._workspace
|
|
345
|
+
|
|
346
|
+
@property
|
|
347
|
+
def store(self) -> GraphStore:
|
|
348
|
+
"""Get the DataPlatform (explore) graph store component.
|
|
349
|
+
|
|
350
|
+
Returns the GraphStore component for managing Corporate Memory's
|
|
351
|
+
DataPlatform graph store, including RDF graph operations, bootstrap
|
|
352
|
+
data management, and store-level backup/restore functionality.
|
|
353
|
+
|
|
354
|
+
Returns:
|
|
355
|
+
The GraphStore component instance, created lazily on first access.
|
|
356
|
+
|
|
357
|
+
Examples:
|
|
358
|
+
>>> client = Client.from_env()
|
|
359
|
+
>>> store_info = client.store.self_information
|
|
360
|
+
>>> print(f"Store type: {store_info.type}, version: {store_info.version}")
|
|
361
|
+
"""
|
|
362
|
+
try:
|
|
363
|
+
return self._store
|
|
364
|
+
except AttributeError:
|
|
365
|
+
self._store = GraphStore(client=self)
|
|
366
|
+
return self._store
|
|
367
|
+
|
|
368
|
+
@property
|
|
369
|
+
def marketplace(self) -> Marketplace:
|
|
370
|
+
"""Get the DataPlatform (explore) marketplace component.
|
|
371
|
+
|
|
372
|
+
Returns the Marketplace component.
|
|
373
|
+
|
|
374
|
+
Returns:
|
|
375
|
+
The Marketplace component instance, created lazily on first access.
|
|
376
|
+
"""
|
|
377
|
+
try:
|
|
378
|
+
return self._marketplace
|
|
379
|
+
except AttributeError:
|
|
380
|
+
self._marketplace = Marketplace(client=self)
|
|
381
|
+
return self._marketplace
|
|
382
|
+
|
|
383
|
+
@property
|
|
384
|
+
def graphs(self) -> GraphsRepository:
|
|
385
|
+
"""Get the DataPlatform (explore) graph repository component.
|
|
386
|
+
|
|
387
|
+
Returns the GraphsRepository component for managing Corporate Memory's
|
|
388
|
+
DataPlatform graph repository for importing and exporting graph
|
|
389
|
+
files and manages their integration with the graph store.
|
|
390
|
+
|
|
391
|
+
Returns:
|
|
392
|
+
The GraphRepository component instance, created lazily on first access.
|
|
393
|
+
|
|
394
|
+
Examples:
|
|
395
|
+
>>> from pathlib import Path
|
|
396
|
+
>>> client = Client.from_env()
|
|
397
|
+
>>> graphs = client.graphs
|
|
398
|
+
>>> graphs.import_item(Path("backup.ttl"))
|
|
399
|
+
"""
|
|
400
|
+
try:
|
|
401
|
+
return self._graphs
|
|
402
|
+
except AttributeError:
|
|
403
|
+
self._graphs = GraphsRepository(client=self)
|
|
404
|
+
return self._graphs
|
|
405
|
+
|
|
406
|
+
@property
|
|
407
|
+
def projects(self) -> ProjectsRepository:
|
|
408
|
+
"""Get the DataIntegration (build) project repository component.
|
|
409
|
+
|
|
410
|
+
Returns the ProjectsRepository component to manage
|
|
411
|
+
DataIntegration projects, such as importing and exporting project
|
|
412
|
+
files.
|
|
413
|
+
|
|
414
|
+
Returns:
|
|
415
|
+
The ProjectsRepository component instance, created lazily on first access.
|
|
416
|
+
|
|
417
|
+
Examples:
|
|
418
|
+
>>> from pathlib import Path
|
|
419
|
+
>>> client = Client.from_env()
|
|
420
|
+
>>> projects = client.projects
|
|
421
|
+
>>> projects.import_item(Path("project.zip"))
|
|
422
|
+
"""
|
|
423
|
+
try:
|
|
424
|
+
return self._projects
|
|
425
|
+
except AttributeError:
|
|
426
|
+
self._projects = ProjectsRepository(client=self)
|
|
427
|
+
return self._projects
|
|
428
|
+
|
|
429
|
+
@property
|
|
430
|
+
def marketplace_packages(self) -> MarketplacePackagesRepository:
|
|
431
|
+
"""Get the package repository for managing Corporate Memory's marketplace packages
|
|
432
|
+
|
|
433
|
+
Returns the package repository for managing Corporate Memory's
|
|
434
|
+
marketplace packages. This component handles marketplace packages
|
|
435
|
+
in a .zip format.
|
|
436
|
+
|
|
437
|
+
Returns: The marketplace package repository instance, created lazily on first access.
|
|
438
|
+
|
|
439
|
+
Examples:
|
|
440
|
+
>>> from pathlib import Path
|
|
441
|
+
>>> client = Client.from_env()
|
|
442
|
+
>>> packages = client.marketplace_packages
|
|
443
|
+
>>> packages.import_item(Path("marketplace_package.zip"))
|
|
444
|
+
"""
|
|
445
|
+
try:
|
|
446
|
+
return self._marketplace_packages
|
|
447
|
+
except AttributeError:
|
|
448
|
+
self._marketplace_packages = MarketplacePackagesRepository(client=self)
|
|
449
|
+
return self._marketplace_packages
|
|
450
|
+
|
|
451
|
+
@property
|
|
452
|
+
def python_packages(self) -> PythonPackagesRepository:
|
|
453
|
+
"""Get the package repository for managing python packages
|
|
454
|
+
|
|
455
|
+
Returns: The python package repository instance, created lazily on first access.
|
|
456
|
+
"""
|
|
457
|
+
try:
|
|
458
|
+
return self._python_packages
|
|
459
|
+
except AttributeError:
|
|
460
|
+
self._python_packages = PythonPackagesRepository(client=self)
|
|
461
|
+
return self._python_packages
|
|
462
|
+
|
|
463
|
+
@property
|
|
464
|
+
def graph_imports(self) -> GraphImportsRepository:
|
|
465
|
+
"""Get the graph imports repository for managing graph imports
|
|
466
|
+
|
|
467
|
+
Returns: The graph imports repository instance, created lazily on first access.
|
|
468
|
+
"""
|
|
469
|
+
try:
|
|
470
|
+
return self._graph_imports
|
|
471
|
+
except AttributeError:
|
|
472
|
+
self._graph_imports = GraphImportsRepository(client=self)
|
|
473
|
+
return self._graph_imports
|
|
474
|
+
|
|
475
|
+
@property
|
|
476
|
+
def workflows(self) -> WorkflowsRepository:
|
|
477
|
+
"""Get the workflows repository for managing workflows
|
|
478
|
+
|
|
479
|
+
Returns: The workflows repository instance, created lazily on first access.
|
|
480
|
+
"""
|
|
481
|
+
try:
|
|
482
|
+
return self._workflows
|
|
483
|
+
except AttributeError:
|
|
484
|
+
self._workflows = WorkflowsRepository(client=self)
|
|
485
|
+
return self._workflows
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""High-level service components for Corporate Memory operations.
|
|
2
|
+
|
|
3
|
+
This package provides high-level component classes that encapsulate complex
|
|
4
|
+
business operations and workflows for Corporate Memory. Components abstract
|
|
5
|
+
the details of repository interactions and provide convenient methods for
|
|
6
|
+
common administrative and operational tasks.
|
|
7
|
+
|
|
8
|
+
Components serve as the service layer between the client interface and the
|
|
9
|
+
repository data access layer.
|
|
10
|
+
"""
|