Skip to content

Commit

Permalink
feat: add 'import_values' API endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
makkus committed Feb 28, 2024
1 parent b6cad4e commit 97da58b
Show file tree
Hide file tree
Showing 10 changed files with 369 additions and 10 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ dev.py
store.sqlite
**.kiarchive
**.kontext
dev/
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- `kiara archive import`
- `kiara archive export`
- `kiara archive explain`
- api endpoints:
- api endpoints:
- `register_archive`
- `set_archive_metadata_value`
- `retrieve_archive_info`
Expand Down
2 changes: 2 additions & 0 deletions src/kiara/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def dbg(
):

for obj in objects:
if hasattr(obj, "create_renderable"):
obj = obj.create_renderable()
try:
rich_print(obj, sep=sep, end=end, file=file, flush=flush)
except Exception:
Expand Down
3 changes: 3 additions & 0 deletions src/kiara/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"KiaraModule",
"KiaraModuleConfig",
"JobDesc",
"Pipeline",
"PipelineStructure",
"RunSpec",
"Value",
"ValueMap",
Expand All @@ -17,6 +19,7 @@
from .context.config import KiaraConfig
from .interfaces.python_api import KiaraAPI
from .interfaces.python_api.models.job import JobDesc, RunSpec
from .models.module.pipeline.pipeline import Pipeline, PipelineStructure
from .models.values.value import Value, ValueMap
from .models.values.value_schema import ValueSchema
from .modules import KiaraModule, KiaraModuleConfig, ValueMapSchema
123 changes: 121 additions & 2 deletions src/kiara/interfaces/python_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1773,6 +1773,7 @@ def store_value(
def store_values(
self,
values: Union[
str,
Mapping[str, Union[str, uuid.UUID, Value]],
Iterable[Union[str, uuid.UUID, Value]],
],
Expand All @@ -1790,6 +1791,8 @@ def store_values(
You have several options to provide the values and aliases you want to store:
- as a string, in which case the item will be wrapped in a list (see non-mapping iterable below)
- as a (non-mapping) iterable of value items, those can either be:
- a value id (as string or uuid)
Expand Down Expand Up @@ -1840,6 +1843,9 @@ def store_values(
if not alias_store:
alias_store = store

if isinstance(values, str):
values = [values]

result = {}
if not isinstance(values, Mapping):
if not alias_map:
Expand Down Expand Up @@ -1933,10 +1939,123 @@ def store_values(
# ------------------------------------------------------------------------------------------------------------------
# archive-related methods

def import_values(
self,
source_archive: Union[str, Path],
values: Union[
str,
Mapping[str, Union[str, uuid.UUID, Value]],
Iterable[Union[str, uuid.UUID, Value]],
],
alias_map: Union[Mapping[str, Iterable[str]], bool, str] = False,
allow_alias_overwrite: bool = True,
source_registered_name: Union[str, None] = None,
) -> StoreValuesResult:
"""Import one or several values from an external kiara archive, along with their aliases (optional).
For the 'values' & 'alias_map' arguments, see the 'store_values' endpoint, as they will be forwarded to that endpoint as is,
and there are several ways to use them which is information I don't want to duplicate.
If you provide aliases in the 'values' parameter, the aliases must be available in the external archive.
Currently, this only works with an external archive file, not with an archive that is registered into the context.
This will probably be added later on, let me know if there is demand, then I'll prioritize.
This method does not raise an error if the storing of the value fails, so you have to investigate the
'StoreValuesResult' instance that is returned to see if the storing was successful.
# NOTE: this is a preliminary endpoint, and might be changed in the future. If you have a use-case for this, please let me know.
Arguments:
source_archive: the name of the archive to store the values into
values: an iterable/map of value keys/values
alias_map: a map of value keys aliases
allow_alias_overwrite: whether to allow overwriting existing aliases
source_registered_name: the name to register the archive under in the context
"""

if source_archive in [None, DEFAULT_STORE_MARKER]:
raise KiaraException(
"You cannot use the default store as source for this operation."
)

if alias_map is True:
pass
elif alias_map is False:
pass
elif isinstance(alias_map, str):
pass
elif isinstance(alias_map, Mapping):
pass
else:
raise KiaraException(
f"Invalid type for 'alias_map' argument: {type(alias_map)}."
)

source_archive_ref = self.register_archive(
archive=source_archive, # type: ignore
registered_name=source_registered_name,
create_if_not_exists=False,
allow_write_access=False,
existing_ok=True,
)

value_ids: Set[uuid.UUID] = set()
aliases: Set[str] = set()

if isinstance(values, str):
values = [values]

if not isinstance(values, Mapping):
# means we have a list of value ids/aliases
for value in values:
if isinstance(value, uuid.UUID):
value_ids.add(value)
elif isinstance(value, str):
try:
_value = uuid.UUID(value)
value_ids.add(_value)
except Exception:
aliases.add(value)
else:
raise NotImplementedError("Not implemented yet.")

new_values: Dict[str, Union[uuid.UUID, str]] = {}
idx = 0
for value_id in value_ids:
field = f"field_{idx}"
idx += 1
new_values[field] = value_id

new_alias_map = {}
for alias in aliases:
field = f"field_{idx}"
idx += 1
new_values[field] = f"{source_archive_ref}#{alias}"
if alias_map is False:
pass
elif alias_map is True:
new_alias_map[field] = [f"{alias}"]
elif isinstance(alias_map, str):
new_alias_map[field] = [f"{alias_map}{alias}"]
else:
# means its a dict
raise NotImplementedError(
"'alias_map' of type 'Mapping' not implemented yet."
)

result = self.store_values(
values=new_values,
alias_map=new_alias_map,
allow_alias_overwrite=allow_alias_overwrite,
)
return result

def export_values(
self,
target_archive: Union[str, Path],
values: Union[
str,
Mapping[str, Union[str, uuid.UUID, Value]],
Iterable[Union[str, uuid.UUID, Value]],
],
Expand All @@ -1962,13 +2081,13 @@ def export_values(
- LZ4: LZ4 compression -- very fast, but not as good compression as zstd
This method does not raise an error if the storing of the value fails, so you have to investigate the
'StoreValuesResult' instance that is returned to see if the storing was successful
'StoreValuesResult' instance that is returned to see if the storing was successful.
# NOTE: this is a preliminary endpoint, and might be changed in the future. If you have a use-case for this, please let me know.
Arguments:
target_store: the name of the archive to store the values into
value: an iterable/map of value keys/values
values: an iterable/map of value keys/values
alias_map: a map of value keys aliases
allow_alias_overwrite: whether to allow overwriting existing aliases
target_registered_name: the name to register the archive under in the context
Expand Down
Loading

0 comments on commit 97da58b

Please sign in to comment.