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.
Files changed (52) hide show
  1. cmem_client/__init__.py +13 -0
  2. cmem_client/auth_provider/__init__.py +14 -0
  3. cmem_client/auth_provider/abc.py +124 -0
  4. cmem_client/auth_provider/client_credentials.py +207 -0
  5. cmem_client/auth_provider/password.py +252 -0
  6. cmem_client/auth_provider/prefetched_token.py +153 -0
  7. cmem_client/client.py +485 -0
  8. cmem_client/components/__init__.py +10 -0
  9. cmem_client/components/graph_store.py +316 -0
  10. cmem_client/components/marketplace.py +179 -0
  11. cmem_client/components/sparql_wrapper.py +53 -0
  12. cmem_client/components/workspace.py +194 -0
  13. cmem_client/config.py +364 -0
  14. cmem_client/exceptions.py +82 -0
  15. cmem_client/logging_utils.py +49 -0
  16. cmem_client/models/__init__.py +16 -0
  17. cmem_client/models/access_condition.py +147 -0
  18. cmem_client/models/base.py +30 -0
  19. cmem_client/models/dataset.py +32 -0
  20. cmem_client/models/error.py +67 -0
  21. cmem_client/models/graph.py +26 -0
  22. cmem_client/models/item.py +143 -0
  23. cmem_client/models/logging_config.py +51 -0
  24. cmem_client/models/package.py +35 -0
  25. cmem_client/models/project.py +46 -0
  26. cmem_client/models/python_package.py +26 -0
  27. cmem_client/models/token.py +40 -0
  28. cmem_client/models/url.py +34 -0
  29. cmem_client/models/workflow.py +80 -0
  30. cmem_client/repositories/__init__.py +15 -0
  31. cmem_client/repositories/access_conditions.py +62 -0
  32. cmem_client/repositories/base/__init__.py +12 -0
  33. cmem_client/repositories/base/abc.py +138 -0
  34. cmem_client/repositories/base/paged_list.py +63 -0
  35. cmem_client/repositories/base/plain_list.py +39 -0
  36. cmem_client/repositories/base/task_search.py +70 -0
  37. cmem_client/repositories/datasets.py +36 -0
  38. cmem_client/repositories/graph_imports.py +93 -0
  39. cmem_client/repositories/graphs.py +458 -0
  40. cmem_client/repositories/marketplace_packages.py +486 -0
  41. cmem_client/repositories/projects.py +214 -0
  42. cmem_client/repositories/protocols/__init__.py +15 -0
  43. cmem_client/repositories/protocols/create_item.py +125 -0
  44. cmem_client/repositories/protocols/delete_item.py +95 -0
  45. cmem_client/repositories/protocols/export_item.py +114 -0
  46. cmem_client/repositories/protocols/import_item.py +141 -0
  47. cmem_client/repositories/python_packages.py +58 -0
  48. cmem_client/repositories/workflows.py +143 -0
  49. cmem_client-0.5.0.dist-info/METADATA +64 -0
  50. cmem_client-0.5.0.dist-info/RECORD +52 -0
  51. cmem_client-0.5.0.dist-info/WHEEL +4 -0
  52. 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
+ """