digitalhub 0.14.0b5__py3-none-any.whl → 0.14.0b7__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 +1 -1
- digitalhub/context/api.py +1 -5
- digitalhub/context/builder.py +1 -1
- digitalhub/entities/_base/material/utils.py +0 -4
- digitalhub/entities/_commons/enums.py +1 -0
- digitalhub/entities/_commons/utils.py +19 -0
- digitalhub/entities/_processors/base/crud.py +1 -1
- digitalhub/entities/_processors/base/import_export.py +3 -2
- digitalhub/entities/_processors/base/processor.py +3 -3
- digitalhub/entities/_processors/context/crud.py +22 -24
- digitalhub/entities/_processors/context/import_export.py +2 -2
- digitalhub/entities/_processors/context/special_ops.py +10 -10
- digitalhub/entities/_processors/utils.py +5 -5
- digitalhub/entities/artifact/utils.py +2 -2
- digitalhub/entities/dataitem/utils.py +10 -14
- digitalhub/entities/model/utils.py +2 -2
- digitalhub/entities/project/_base/entity.py +248 -102
- digitalhub/entities/task/_base/models.py +13 -16
- digitalhub/stores/client/_base/key_builder.py +1 -1
- digitalhub/stores/client/builder.py +1 -1
- digitalhub/stores/client/dhcore/client.py +19 -303
- digitalhub/stores/client/dhcore/configurator.py +1 -1
- digitalhub/stores/client/dhcore/header_manager.py +61 -0
- digitalhub/stores/client/dhcore/http_handler.py +133 -0
- digitalhub/stores/client/dhcore/response_processor.py +102 -0
- digitalhub/stores/client/dhcore/utils.py +2 -60
- digitalhub/stores/client/local/client.py +2 -2
- digitalhub/stores/credentials/api.py +0 -4
- digitalhub/stores/credentials/ini_module.py +0 -6
- digitalhub/stores/data/builder.py +1 -1
- digitalhub/stores/data/s3/store.py +1 -1
- digitalhub/stores/data/sql/store.py +6 -6
- digitalhub/utils/generic_utils.py +0 -12
- digitalhub/utils/git_utils.py +0 -8
- digitalhub/utils/io_utils.py +0 -8
- digitalhub/utils/store_utils.py +1 -1
- {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.0b7.dist-info}/METADATA +1 -1
- {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.0b7.dist-info}/RECORD +41 -38
- {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.0b7.dist-info}/WHEEL +0 -0
- {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.0b7.dist-info}/licenses/AUTHORS +0 -0
- {digitalhub-0.14.0b5.dist-info → digitalhub-0.14.0b7.dist-info}/licenses/LICENSE +0 -0
digitalhub/__init__.py
CHANGED
|
@@ -95,7 +95,7 @@ from digitalhub.entities.workflow.crud import (
|
|
|
95
95
|
new_workflow,
|
|
96
96
|
update_workflow,
|
|
97
97
|
)
|
|
98
|
-
from digitalhub.stores.client.dhcore.utils import refresh_token
|
|
98
|
+
from digitalhub.stores.client.dhcore.utils import refresh_token
|
|
99
99
|
from digitalhub.stores.credentials.api import get_current_profile, set_current_profile
|
|
100
100
|
from digitalhub.utils.store_utils import get_s3_client, get_sql_engine
|
|
101
101
|
|
digitalhub/context/api.py
CHANGED
|
@@ -24,7 +24,7 @@ def build_context(project: Project, overwrite: bool = False) -> Context:
|
|
|
24
24
|
----------
|
|
25
25
|
project : Project
|
|
26
26
|
The project object used to build the context.
|
|
27
|
-
overwrite : bool
|
|
27
|
+
overwrite : bool
|
|
28
28
|
If True, overwrites existing context if it exists. Default is False.
|
|
29
29
|
|
|
30
30
|
Returns
|
|
@@ -60,9 +60,5 @@ def delete_context(project: str) -> None:
|
|
|
60
60
|
----------
|
|
61
61
|
project : str
|
|
62
62
|
Project name.
|
|
63
|
-
|
|
64
|
-
Returns
|
|
65
|
-
-------
|
|
66
|
-
None
|
|
67
63
|
"""
|
|
68
64
|
context_builder.remove(project)
|
digitalhub/context/builder.py
CHANGED
|
@@ -33,6 +33,25 @@ def is_valid_key(key: str) -> bool:
|
|
|
33
33
|
return bool(re.fullmatch(KEY_PATTERN_WITH_ID, key) or re.fullmatch(KEY_PATTERN_NO_ID, key))
|
|
34
34
|
|
|
35
35
|
|
|
36
|
+
def sanitize_unversioned_key(key: str) -> str:
|
|
37
|
+
"""
|
|
38
|
+
Sanitize an unversioned entity key (from name:id to id).
|
|
39
|
+
|
|
40
|
+
Parameters
|
|
41
|
+
----------
|
|
42
|
+
key : str
|
|
43
|
+
The unversioned entity key.
|
|
44
|
+
|
|
45
|
+
Returns
|
|
46
|
+
-------
|
|
47
|
+
str
|
|
48
|
+
The sanitized entity key with version.
|
|
49
|
+
"""
|
|
50
|
+
splt = key.split("/")[2:]
|
|
51
|
+
ent_id = splt[-1].split(":")[0]
|
|
52
|
+
return "store://" + "/".join(splt[:-1] + [ent_id])
|
|
53
|
+
|
|
54
|
+
|
|
36
55
|
def parse_entity_key(key: str) -> tuple[str, str, str, str | None, str]:
|
|
37
56
|
"""
|
|
38
57
|
Parse an entity key into its constituent components.
|
|
@@ -13,6 +13,7 @@ from digitalhub.utils.exceptions import EntityAlreadyExistsError, EntityError, E
|
|
|
13
13
|
from digitalhub.utils.io_utils import read_yaml
|
|
14
14
|
|
|
15
15
|
if typing.TYPE_CHECKING:
|
|
16
|
+
from digitalhub.entities._processors.base.crud import BaseEntityCRUDProcessor
|
|
16
17
|
from digitalhub.entities.project._base.entity import Project
|
|
17
18
|
|
|
18
19
|
|
|
@@ -26,7 +27,7 @@ class BaseEntityImportExportProcessor:
|
|
|
26
27
|
|
|
27
28
|
def import_project_entity(
|
|
28
29
|
self,
|
|
29
|
-
crud_processor,
|
|
30
|
+
crud_processor: BaseEntityCRUDProcessor,
|
|
30
31
|
file: str,
|
|
31
32
|
**kwargs,
|
|
32
33
|
) -> Project:
|
|
@@ -81,7 +82,7 @@ class BaseEntityImportExportProcessor:
|
|
|
81
82
|
|
|
82
83
|
def load_project_entity(
|
|
83
84
|
self,
|
|
84
|
-
crud_processor,
|
|
85
|
+
crud_processor: BaseEntityCRUDProcessor,
|
|
85
86
|
file: str,
|
|
86
87
|
**kwargs,
|
|
87
88
|
) -> Project:
|
|
@@ -49,7 +49,7 @@ class BaseEntityOperationsProcessor:
|
|
|
49
49
|
|
|
50
50
|
Parameters
|
|
51
51
|
----------
|
|
52
|
-
_entity : Project
|
|
52
|
+
_entity : Project
|
|
53
53
|
An existing project entity object to create. If None,
|
|
54
54
|
a new entity will be built from kwargs.
|
|
55
55
|
**kwargs : dict
|
|
@@ -212,7 +212,7 @@ class BaseEntityOperationsProcessor:
|
|
|
212
212
|
EntityError
|
|
213
213
|
If the project already exists in the backend.
|
|
214
214
|
"""
|
|
215
|
-
return self.import_export_processor.import_project_entity(file, **kwargs)
|
|
215
|
+
return self.import_export_processor.import_project_entity(self.crud_processor, file, **kwargs)
|
|
216
216
|
|
|
217
217
|
def load_project_entity(
|
|
218
218
|
self,
|
|
@@ -238,7 +238,7 @@ class BaseEntityOperationsProcessor:
|
|
|
238
238
|
Project
|
|
239
239
|
The loaded and updated project entity.
|
|
240
240
|
"""
|
|
241
|
-
return self.import_export_processor.load_project_entity(file, **kwargs)
|
|
241
|
+
return self.import_export_processor.load_project_entity(self.crud_processor, file, **kwargs)
|
|
242
242
|
|
|
243
243
|
##############################
|
|
244
244
|
# Base entity operations
|
|
@@ -6,7 +6,7 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
import typing
|
|
8
8
|
|
|
9
|
-
from digitalhub.entities._commons.utils import is_valid_key
|
|
9
|
+
from digitalhub.entities._commons.utils import is_valid_key, sanitize_unversioned_key
|
|
10
10
|
from digitalhub.entities._processors.utils import (
|
|
11
11
|
get_context_from_identifier,
|
|
12
12
|
get_context_from_project,
|
|
@@ -77,7 +77,7 @@ class ContextEntityCRUDProcessor:
|
|
|
77
77
|
|
|
78
78
|
Parameters
|
|
79
79
|
----------
|
|
80
|
-
_entity : ContextEntity
|
|
80
|
+
_entity : ContextEntity
|
|
81
81
|
An existing context entity object to create. If None,
|
|
82
82
|
a new entity will be built from kwargs.
|
|
83
83
|
**kwargs : dict
|
|
@@ -120,11 +120,11 @@ class ContextEntityCRUDProcessor:
|
|
|
120
120
|
The project context instance.
|
|
121
121
|
identifier : str
|
|
122
122
|
Entity key (store://...) or entity name identifier.
|
|
123
|
-
entity_type : str
|
|
123
|
+
entity_type : str
|
|
124
124
|
The type of entity to read.
|
|
125
|
-
project : str
|
|
125
|
+
project : str
|
|
126
126
|
Project name (used for identifier parsing).
|
|
127
|
-
entity_id : str
|
|
127
|
+
entity_id : str
|
|
128
128
|
Specific entity ID to read.
|
|
129
129
|
**kwargs : dict
|
|
130
130
|
Additional parameters to pass to the API call.
|
|
@@ -185,11 +185,11 @@ class ContextEntityCRUDProcessor:
|
|
|
185
185
|
----------
|
|
186
186
|
identifier : str
|
|
187
187
|
Entity key (store://...) or entity name identifier.
|
|
188
|
-
entity_type : str
|
|
188
|
+
entity_type : str
|
|
189
189
|
The type of entity to read.
|
|
190
|
-
project : str
|
|
190
|
+
project : str
|
|
191
191
|
Project name for context resolution.
|
|
192
|
-
entity_id : str
|
|
192
|
+
entity_id : str
|
|
193
193
|
Specific entity ID to read.
|
|
194
194
|
**kwargs : dict
|
|
195
195
|
Additional parameters to pass to the API call.
|
|
@@ -230,11 +230,11 @@ class ContextEntityCRUDProcessor:
|
|
|
230
230
|
----------
|
|
231
231
|
identifier : str
|
|
232
232
|
Entity key (store://...) or entity ID.
|
|
233
|
-
entity_type : str
|
|
233
|
+
entity_type : str
|
|
234
234
|
The type of entity to read.
|
|
235
|
-
project : str
|
|
235
|
+
project : str
|
|
236
236
|
Project name for context resolution.
|
|
237
|
-
entity_id : str
|
|
237
|
+
entity_id : str
|
|
238
238
|
Specific entity ID to read.
|
|
239
239
|
**kwargs : dict
|
|
240
240
|
Additional parameters to pass to the API call.
|
|
@@ -247,9 +247,7 @@ class ContextEntityCRUDProcessor:
|
|
|
247
247
|
if not is_valid_key(identifier):
|
|
248
248
|
entity_id = identifier
|
|
249
249
|
else:
|
|
250
|
-
|
|
251
|
-
if len(splt) == 3:
|
|
252
|
-
identifier = f"{splt[0]}:{splt[1]}"
|
|
250
|
+
identifier = sanitize_unversioned_key(identifier)
|
|
253
251
|
return self.read_context_entity(
|
|
254
252
|
identifier,
|
|
255
253
|
entity_type=entity_type,
|
|
@@ -278,9 +276,9 @@ class ContextEntityCRUDProcessor:
|
|
|
278
276
|
The project context instance.
|
|
279
277
|
identifier : str
|
|
280
278
|
Entity key (store://...) or entity name identifier.
|
|
281
|
-
entity_type : str
|
|
279
|
+
entity_type : str
|
|
282
280
|
The type of entity to read versions for.
|
|
283
|
-
project : str
|
|
281
|
+
project : str
|
|
284
282
|
Project name (used for identifier parsing).
|
|
285
283
|
**kwargs : dict
|
|
286
284
|
Additional parameters to pass to the API call.
|
|
@@ -329,9 +327,9 @@ class ContextEntityCRUDProcessor:
|
|
|
329
327
|
----------
|
|
330
328
|
identifier : str
|
|
331
329
|
Entity key (store://...) or entity name identifier.
|
|
332
|
-
entity_type : str
|
|
330
|
+
entity_type : str
|
|
333
331
|
The type of entity to read versions for.
|
|
334
|
-
project : str
|
|
332
|
+
project : str
|
|
335
333
|
Project name for context resolution.
|
|
336
334
|
**kwargs : dict
|
|
337
335
|
Additional parameters to pass to the API call.
|
|
@@ -541,11 +539,11 @@ class ContextEntityCRUDProcessor:
|
|
|
541
539
|
The project context instance.
|
|
542
540
|
identifier : str
|
|
543
541
|
Entity key (store://...) or entity name identifier.
|
|
544
|
-
entity_type : str
|
|
542
|
+
entity_type : str
|
|
545
543
|
The type of entity to delete.
|
|
546
|
-
project : str
|
|
544
|
+
project : str
|
|
547
545
|
Project name (used for identifier parsing).
|
|
548
|
-
entity_id : str
|
|
546
|
+
entity_id : str
|
|
549
547
|
Specific entity ID to delete.
|
|
550
548
|
**kwargs : dict
|
|
551
549
|
Additional parameters including:
|
|
@@ -606,11 +604,11 @@ class ContextEntityCRUDProcessor:
|
|
|
606
604
|
----------
|
|
607
605
|
identifier : str
|
|
608
606
|
Entity key (store://...) or entity name identifier.
|
|
609
|
-
project : str
|
|
607
|
+
project : str
|
|
610
608
|
Project name for context resolution.
|
|
611
|
-
entity_type : str
|
|
609
|
+
entity_type : str
|
|
612
610
|
The type of entity to delete.
|
|
613
|
-
entity_id : str
|
|
611
|
+
entity_id : str
|
|
614
612
|
Specific entity ID to delete.
|
|
615
613
|
**kwargs : dict
|
|
616
614
|
Additional parameters including deletion options.
|
|
@@ -47,7 +47,7 @@ class ContextEntityImportExportProcessor:
|
|
|
47
47
|
Storage key (store://...) to read the entity from.
|
|
48
48
|
reset_id : bool
|
|
49
49
|
Flag to determine if the ID of context entities should be reset.
|
|
50
|
-
context : str
|
|
50
|
+
context : str
|
|
51
51
|
Project name to use for context resolution. If None, uses
|
|
52
52
|
the project specified in the YAML file.
|
|
53
53
|
|
|
@@ -110,7 +110,7 @@ class ContextEntityImportExportProcessor:
|
|
|
110
110
|
Storage key (store://...) to read the entity from.
|
|
111
111
|
reset_id : bool
|
|
112
112
|
Flag to determine if the ID of executable entities should be reset.
|
|
113
|
-
context : str
|
|
113
|
+
context : str
|
|
114
114
|
Project name to use for context resolution.
|
|
115
115
|
|
|
116
116
|
Returns
|
|
@@ -47,7 +47,7 @@ class ContextEntitySpecialOpsProcessor:
|
|
|
47
47
|
The kind/subtype of entity.
|
|
48
48
|
entity_name : str
|
|
49
49
|
The name of the entity.
|
|
50
|
-
entity_id : str
|
|
50
|
+
entity_id : str
|
|
51
51
|
The unique identifier of the entity version.
|
|
52
52
|
|
|
53
53
|
Returns
|
|
@@ -336,7 +336,7 @@ class ContextEntitySpecialOpsProcessor:
|
|
|
336
336
|
The type of entity to read metrics from.
|
|
337
337
|
entity_id : str
|
|
338
338
|
The unique identifier of the entity.
|
|
339
|
-
metric_name : str
|
|
339
|
+
metric_name : str
|
|
340
340
|
The name of a specific metric to retrieve.
|
|
341
341
|
If None, retrieves all available metrics.
|
|
342
342
|
**kwargs : dict
|
|
@@ -428,22 +428,22 @@ class ContextEntitySpecialOpsProcessor:
|
|
|
428
428
|
The CRUD processor instance for entity operations.
|
|
429
429
|
project : str
|
|
430
430
|
The project name to search within.
|
|
431
|
-
query : str
|
|
431
|
+
query : str
|
|
432
432
|
Free-text search query to match against entity content.
|
|
433
|
-
entity_types : list[str]
|
|
433
|
+
entity_types : list[str]
|
|
434
434
|
List of entity types to filter by.
|
|
435
435
|
If None, searches all entity types.
|
|
436
|
-
name : str
|
|
436
|
+
name : str
|
|
437
437
|
Entity name pattern to match.
|
|
438
|
-
kind : str
|
|
438
|
+
kind : str
|
|
439
439
|
Entity kind to filter by.
|
|
440
|
-
created : str
|
|
440
|
+
created : str
|
|
441
441
|
Creation date filter (ISO format).
|
|
442
|
-
updated : str
|
|
442
|
+
updated : str
|
|
443
443
|
Last update date filter (ISO format).
|
|
444
|
-
description : str
|
|
444
|
+
description : str
|
|
445
445
|
Description pattern to match.
|
|
446
|
-
labels : list[str]
|
|
446
|
+
labels : list[str]
|
|
447
447
|
List of label patterns to match.
|
|
448
448
|
**kwargs : dict
|
|
449
449
|
Additional search parameters to pass to the API call.
|
|
@@ -38,13 +38,13 @@ def parse_identifier(
|
|
|
38
38
|
identifier : str
|
|
39
39
|
The entity identifier to parse. Can be either a full entity key
|
|
40
40
|
(store://project/entity_type/kind/name:id) or a simple entity name.
|
|
41
|
-
project : str
|
|
41
|
+
project : str
|
|
42
42
|
The project name. Required when identifier is not a full key.
|
|
43
|
-
entity_type : str
|
|
43
|
+
entity_type : str
|
|
44
44
|
The entity type. Required when identifier is not a full key.
|
|
45
|
-
entity_kind : str
|
|
45
|
+
entity_kind : str
|
|
46
46
|
The entity kind specification.
|
|
47
|
-
entity_id : str
|
|
47
|
+
entity_id : str
|
|
48
48
|
The entity version identifier.
|
|
49
49
|
|
|
50
50
|
Returns
|
|
@@ -81,7 +81,7 @@ def get_context_from_identifier(
|
|
|
81
81
|
identifier : str
|
|
82
82
|
The entity identifier to extract context from. Can be either
|
|
83
83
|
a full entity key (store://...) or a simple entity name.
|
|
84
|
-
project : str
|
|
84
|
+
project : str
|
|
85
85
|
The project name. Required when identifier is not a full key.
|
|
86
86
|
|
|
87
87
|
Returns
|
|
@@ -23,7 +23,7 @@ def eval_source(
|
|
|
23
23
|
|
|
24
24
|
Parameters
|
|
25
25
|
----------
|
|
26
|
-
source : str, list[str], or None
|
|
26
|
+
source : str, list[str], or None
|
|
27
27
|
The source specification(s) to evaluate. Can be a single
|
|
28
28
|
source string, a list of source strings, or None.
|
|
29
29
|
|
|
@@ -59,7 +59,7 @@ def process_kwargs(
|
|
|
59
59
|
source : str or list[str]
|
|
60
60
|
The source specification(s) for the artifact content.
|
|
61
61
|
Can be a single source or multiple sources.
|
|
62
|
-
path : str
|
|
62
|
+
path : str
|
|
63
63
|
The destination path for the artifact entity.
|
|
64
64
|
If None, a path will be automatically generated.
|
|
65
65
|
**kwargs : dict
|
|
@@ -41,17 +41,17 @@ def eval_source(
|
|
|
41
41
|
|
|
42
42
|
Parameters
|
|
43
43
|
----------
|
|
44
|
-
source : SourcesOrListOfSources
|
|
44
|
+
source : SourcesOrListOfSources
|
|
45
45
|
The source specification(s) for the dataitem. Can be file paths,
|
|
46
46
|
URLs, or other source identifiers.
|
|
47
|
-
data : Any
|
|
47
|
+
data : Any
|
|
48
48
|
The data object to process (e.g., DataFrame). Alternative to source.
|
|
49
49
|
Exactly one of source or data must be provided.
|
|
50
|
-
kind : str
|
|
50
|
+
kind : str
|
|
51
51
|
The kind of dataitem being created (e.g., 'table').
|
|
52
|
-
name : str
|
|
52
|
+
name : str
|
|
53
53
|
The name of the dataitem, used for generating file paths.
|
|
54
|
-
project : str
|
|
54
|
+
project : str
|
|
55
55
|
The project name, used for context and path generation.
|
|
56
56
|
|
|
57
57
|
Returns
|
|
@@ -105,13 +105,13 @@ def eval_data(
|
|
|
105
105
|
how data should be processed.
|
|
106
106
|
source : SourcesOrListOfSources
|
|
107
107
|
The source specification(s) to load data from.
|
|
108
|
-
data : Any
|
|
108
|
+
data : Any
|
|
109
109
|
Pre-loaded data object. If provided, may be returned directly
|
|
110
110
|
depending on the dataitem kind.
|
|
111
|
-
file_format : str
|
|
111
|
+
file_format : str
|
|
112
112
|
The file format specification for reading the source
|
|
113
113
|
(e.g., 'parquet', 'csv').
|
|
114
|
-
engine : str
|
|
114
|
+
engine : str
|
|
115
115
|
The engine to use for reading the data (e.g., 'pandas', 'polars').
|
|
116
116
|
|
|
117
117
|
Returns
|
|
@@ -159,10 +159,10 @@ def process_kwargs(
|
|
|
159
159
|
The kind of dataitem being created (e.g., 'table').
|
|
160
160
|
source : SourcesOrListOfSources
|
|
161
161
|
The source specification(s) for the dataitem content.
|
|
162
|
-
data : Any
|
|
162
|
+
data : Any
|
|
163
163
|
The data object for schema extraction and processing.
|
|
164
164
|
Used as an alternative to source for table dataitems.
|
|
165
|
-
path : str
|
|
165
|
+
path : str
|
|
166
166
|
The destination path for the dataitem entity.
|
|
167
167
|
If None, a path will be automatically generated.
|
|
168
168
|
**kwargs : dict
|
|
@@ -201,10 +201,6 @@ def clean_tmp_path(pth: SourcesOrListOfSources) -> None:
|
|
|
201
201
|
pth : SourcesOrListOfSources
|
|
202
202
|
The path or list of paths to clean up. Can be file paths
|
|
203
203
|
or directory paths that need to be removed.
|
|
204
|
-
|
|
205
|
-
Returns
|
|
206
|
-
-------
|
|
207
|
-
None
|
|
208
204
|
"""
|
|
209
205
|
if isinstance(pth, list):
|
|
210
206
|
for p in pth:
|
|
@@ -23,7 +23,7 @@ def eval_source(
|
|
|
23
23
|
|
|
24
24
|
Parameters
|
|
25
25
|
----------
|
|
26
|
-
source : str, list[str], or None
|
|
26
|
+
source : str, list[str], or None
|
|
27
27
|
The source specification(s) to evaluate. Can be a single
|
|
28
28
|
source string, a list of source strings, or None.
|
|
29
29
|
|
|
@@ -59,7 +59,7 @@ def process_kwargs(
|
|
|
59
59
|
source : str or list[str]
|
|
60
60
|
The source specification(s) for the model content.
|
|
61
61
|
Can be a single source or multiple sources.
|
|
62
|
-
path : str
|
|
62
|
+
path : str
|
|
63
63
|
The destination path for the model entity.
|
|
64
64
|
If None, a path will be automatically generated.
|
|
65
65
|
**kwargs : dict
|