Skip to content

Commit

Permalink
refactor: re-organized kiara config mechanism to incl. creating empty…
Browse files Browse the repository at this point in the history
… archive
  • Loading branch information
makkus committed Mar 28, 2024
1 parent 3fe395f commit c5781d3
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 72 deletions.
22 changes: 10 additions & 12 deletions src/kiara/context/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ def create_default_store_config(
return data_store


DEFAULT_STORE_TYPE: Literal["auto"] = "auto"
DEFAULT_STORE_TYPE: Literal["sqlite"] = "sqlite"


class KiaraConfig(BaseSettings):
Expand Down Expand Up @@ -461,10 +461,10 @@ def load_from_file(cls, path: Union[Path, str, None] = None) -> "KiaraConfig":
description="The name of the default context to use if none is provided.",
default=DEFAULT_CONTEXT_NAME,
)
default_store_type: Literal["auto", "sqlite", "filesystem"] = Field(
description="The default store type to use when creating new stores.",
default=DEFAULT_STORE_TYPE,
)
# default_store_type: Literal["sqlite", "filesystem"] = Field(
# description="The default store type to use when creating new stores.",
# default=DEFAULT_STORE_TYPE,
# )
auto_generate_contexts: bool = Field(
description="Whether to auto-generate requested contexts if they don't exist yet.",
default=True,
Expand Down Expand Up @@ -639,8 +639,9 @@ def create_default_sqlite_archive_config(use_wal_mode: bool) -> Dict[str, Any]:
default_sqlite_config: Union[Dict[str, Any], None] = None

use_wal_mode: bool = True
default_store_type = "sqlite"

if self.default_store_type == "auto":
if default_store_type == "auto":

# if windows, we want sqlite as default, because although it's slower, it does not
# need the user to enable developer mode
Expand All @@ -653,20 +654,20 @@ def create_default_sqlite_archive_config(use_wal_mode: bool) -> Dict[str, Any]:
alias_store_type = "sqlite"
job_store_type = "sqlite"
workflow_store_type = "sqlite"
elif self.default_store_type == "filesystem":
elif default_store_type == "filesystem":
metadata_store_type = "filesystem"
data_store_type = "filesystem"
alias_store_type = "filesystem"
job_store_type = "filesystem"
workflow_store_type = "filesystem"
elif self.default_store_type == "sqlite":
elif default_store_type == "sqlite":
metadata_store_type = "sqlite"
data_store_type = "sqlite"
alias_store_type = "sqlite"
job_store_type = "sqlite"
workflow_store_type = "sqlite"
else:
raise Exception(f"Unknown store type: {self.default_store_type}")
raise Exception(f"Unknown store type: {default_store_type}")

if DEFAULT_METADATA_STORE_MARKER not in context_config.archives.keys():

Expand Down Expand Up @@ -920,9 +921,6 @@ def save(self, path: Union[Path, None] = None):
}
)

if data["default_store_type"] == DEFAULT_STORE_TYPE:
data.pop("default_store_type")

with path.open("wt") as f:
yaml.dump(
data,
Expand Down
54 changes: 13 additions & 41 deletions src/kiara/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import os
import sys
import uuid
from pathlib import Path
from typing import (
TYPE_CHECKING,
Any,
Expand All @@ -21,7 +20,6 @@
Union,
)

from kiara.defaults import KIARA_CONFIG_FILE_NAME, KIARA_MAIN_CONFIG_FILE
from kiara.exceptions import KiaraException
from kiara.utils.cli import terminal_print

Expand Down Expand Up @@ -221,6 +219,12 @@ def set_console_width(width: Union[int, None] = None, prefer_env: bool = True):


class KiaraAPIWrap(object):
"""A wrapper class to help with lazy loading.
This is mostly relevant in terms of Python imports and the cli, because that allows
to avoid importing lots of Python modules if only `--help` is called.
"""

def __init__(
self,
config: Union[str, None],
Expand Down Expand Up @@ -291,47 +295,15 @@ def kiara_config(self) -> "KiaraConfig":

if self._kiara_config is not None:
return self._kiara_config
from kiara.context.config import KiaraConfig

# kiara_config: Optional[KiaraConfig] = None
exists = False
create = False
if self._config:
config_path = Path(self._config)
if config_path.exists():
if config_path.is_file():
config_file_path = config_path
exists = True
else:
config_file_path = config_path / KIARA_CONFIG_FILE_NAME
if config_file_path.exists():
exists = True
else:
config_path.parent.mkdir(parents=True, exist_ok=True)
config_file_path = config_path

else:
config_file_path = Path(KIARA_MAIN_CONFIG_FILE)
if not config_file_path.exists():
create = True
exists = False
else:
exists = True

if not exists:
if not create:
from kiara.utils.cli import terminal_print

terminal_print()
terminal_print(
f"Can't create kiara context, specified config file does not exist: {self._config}."
)
sys.exit(1)
try:
from kiara.utils.config import assemble_kiara_config

kiara_config = KiaraConfig()
kiara_config.save(config_file_path)
else:
kiara_config = KiaraConfig.load_from_file(config_file_path)
kiara_config = assemble_kiara_config(config_file=self._config)
except Exception as e:
terminal_print()
terminal_print(f"Error loading kiara config: {e}")
sys.exit(1)

kiara_config.runtime_config.runtime_profile = "default"

Expand Down
36 changes: 21 additions & 15 deletions src/kiara/interfaces/python_api/kiara_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from pathlib import Path

# BEGIN AUTO-GENERATED-IMPORTS
from typing import TYPE_CHECKING, Any, ClassVar, Dict, Iterable, List, Mapping, Union
from typing import TYPE_CHECKING, Any, ClassVar, Iterable, List, Mapping, Union
from uuid import UUID

if TYPE_CHECKING:
Expand All @@ -30,7 +30,6 @@

if TYPE_CHECKING:
from kiara.context import KiaraConfig
from kiara.interfaces import BaseAPI
from kiara.interfaces.python_api.models.archive import KiArchive
from kiara.interfaces.python_api.models.doc import OperationsMap
from kiara.interfaces.python_api.models.info import (
Expand Down Expand Up @@ -72,25 +71,27 @@ class KiaraAPI(object):
"""

_default_instance: ClassVar[Union["KiaraAPI", None]] = None
_context_instances: ClassVar[Dict[str, "BaseAPI"]] = {}

@classmethod
def instance(cls, context_name: Union[str, None] = None) -> "KiaraAPI":
def instance(cls) -> "KiaraAPI":
"""Retrieve the default KiaraAPI instance.
if context_name is None:
This is a convenience method to get a singleton KiaraAPI instance. If this is the first time this method is called, it loads the default *kiara* context. If this is called subsequently, it will return
the same instance, so if you or some-one (or -thing) switched that context, this might not be the case.
if cls._default_instance is not None:
return cls._default_instance
So make sure you understand the implications, and if in doubt, it might be safer to create your own `KiaraAPI` instance manually.
"""

if cls._default_instance is not None:
return cls._default_instance

from kiara.context import KiaraConfig
from kiara.utils.config import assemble_kiara_config

config = KiaraConfig()
config = assemble_kiara_config()

api = KiaraAPI(kiara_config=config)
cls._default_instance = api
return api
else:
raise NotImplementedError()
api = KiaraAPI(kiara_config=config)
cls._default_instance = api
return api

def __init__(self, kiara_config: Union["KiaraConfig", None] = None):

Expand Down Expand Up @@ -127,7 +128,7 @@ def run_job(
"""

if not comment:
if not comment and comment != "":
from kiara.exceptions import KiaraException

raise KiaraException(msg="Can't submit job: no comment provided.")
Expand Down Expand Up @@ -164,6 +165,11 @@ def queue_job(
the queued job id
"""

if not comment and comment != "":
from kiara.exceptions import KiaraException

raise KiaraException(msg="Can't submit job: no comment provided.")

return self._api.queue_job(
operation=operation,
inputs=inputs,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-

from kiara.interfaces.python_api.base_api import BaseAPI
from kiara.api import KiaraAPI
from kiara.utils.cli import terminal_print

"""{{ pipeline.doc.full_doc }}
"""

kiara = BaseAPI.instance()
kiara = KiaraAPI.instance()

# ==============================================================================
# Specify all the pipeline inputs here
Expand Down Expand Up @@ -44,6 +44,7 @@ results_{{ step_id }} = kiara.run_job('{{ step.manifest_src.module_type }}', ope
{%- set pipeline_output_refs = pipeline.pipeline_output_refs -%}
{% for field_name, output_ref in pipeline_output_refs.items() %}
pipeline_result_{{ field_name }} = results_{{ output_ref.connected_output.step_id }}['{{ output_ref.connected_output.value_name }}']
terminal_rendered_result_{{ field_name }} = kiara.render_value(pipeline_result_{{ field_name }}, target_format="terminal_renderable", use_pretty_print=True)
terminal_print(terminal_rendered_result_{{ field_name }}, in_panel='Pipeline result: [b]{{ field_name }}[/b]')

terminal_print(pipeline_result_{{ field_name }}, in_panel='Pipeline result metadata: [b]{{ field_name }}[/b]')
terminal_print(pipeline_result_{{ field_name }}.data, in_panel='Pipeline result data: [b]{{ field_name }}[/b]')
{% endfor %}
63 changes: 63 additions & 0 deletions src/kiara/utils/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
from pathlib import Path
from typing import TYPE_CHECKING, Union

from kiara.defaults import KIARA_CONFIG_FILE_NAME, KIARA_MAIN_CONFIG_FILE
from kiara.exceptions import KiaraException

if TYPE_CHECKING:
from kiara.context import KiaraConfig


def assemble_kiara_config(
config_file: Union[str, None] = None, create_config_file: bool = False
) -> "KiaraConfig":
"""Assemble a KiaraConfig object from a config file path or create a new one.
Arguments:
config_file: The path to a Kiara config file or a folder containing one named 'kiara.config'.
create_config_file: If True, create a new config file if it does not exist.
"""

exists = False
if config_file:
config_path = Path(config_file)
if config_path.exists():
if config_path.is_file():
config_file_path = config_path
exists = True
else:
config_file_path = config_path / KIARA_CONFIG_FILE_NAME
if config_file_path.exists():
exists = True
else:
config_path.parent.mkdir(parents=True, exist_ok=True)
config_file_path = config_path

else:
config_file_path = Path(KIARA_MAIN_CONFIG_FILE)
if not config_file_path.exists():
exists = False
else:
exists = True

from kiara.context import KiaraConfig

if not exists:
kiara_config = KiaraConfig()

if config_file:
if not create_config_file:
raise KiaraException(
f"specified config file does not exist: {config_file}."
)
else:
if create_config_file:
kiara_config.save(config_file_path)
else:
kiara_config = KiaraConfig.load_from_file(config_file_path)

return kiara_config

0 comments on commit c5781d3

Please sign in to comment.