Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use qualibrate config package #118

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
427 changes: 232 additions & 195 deletions backend/poetry.lock

Large diffs are not rendered by default.

14 changes: 2 additions & 12 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,19 @@ tomli = { version = "^2.0.1", python = "<3.11" }
tomli-w = "^1.0.0"
requests = "^2.31.0"
jsonpatch = "^1.33"
qualibrate-runner = { version = "^0.2.2", optional = true }
qualibrate-config = {path = "../../qualibrate-config", develop = true}
# TODO: replace after publishing timeline-db
# json-timeline-database = { path = "../../json-timeline-database", optional = true, develop = true }

[tool.poetry.extras]
json-timeline-db = ["json-timeline-database"]
runner = ["qualibrate-runner"]

[tool.poetry.group.dev.dependencies]
mypy = "^1.8.0"
ruff = "^0.7.0"
types-requests = "^2.31.0.20240218"
poethepoet = "^0.25.0"

#[tool.poetry.group.qm-dev.dependencies]
#qualibrate-runner = {path = "../../qualibrate-runner", optional = true, develop = true, extras=["qualibrary"]}

[tool.poetry.group.test.dependencies]
pytest = "^8.0.0"
pytest-mock = "^3.12.0"
Expand All @@ -52,13 +48,7 @@ exclude = ['tests/']

[[tool.mypy.overrides]]
# TODO: add py.typed to json_timeline_database and remove from ignore imports
module = [
"jsonpatch",
"jsonpointer",
"json_timeline_database.*",
"qualibrate",
"qualibrate_runner.*",
]
module = ["jsonpatch", "jsonpointer", "json_timeline_database.*"]
ignore_missing_imports = true

[tool.ruff]
Expand Down
3 changes: 2 additions & 1 deletion backend/qualibrate_app/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import click
from qualibrate_config.cli.config import config_command

from qualibrate_app.cli import config_command, start_command
from qualibrate_app.cli import start_command


@click.group()
Expand Down
25 changes: 25 additions & 0 deletions backend/qualibrate_app/api/core/domain/bases/base_with_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from abc import ABC

from qualibrate_config.models import (
JsonTimelineDBRemoteServiceConfig,
QualibrateAppConfig,
QualibrateConfig,
)


class DomainWithConfigBase(ABC): # noqa: B024
def __init__(self, settings: QualibrateConfig):
self._settings = settings

@property
def app_config(self) -> QualibrateAppConfig:
if self._settings.app is None:
raise RuntimeError("Qualibrate app config not set")
return self._settings.app

@property
def timeline_db_config(self) -> JsonTimelineDBRemoteServiceConfig:
app = self.app_config
if app.timeline_db is None:
raise RuntimeError("Timeline DB of Qualibrate app config not set")
return app.timeline_db
12 changes: 8 additions & 4 deletions backend/qualibrate_app/api/core/domain/bases/branch.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
from enum import IntEnum
from typing import Optional

from qualibrate_config.models import QualibrateConfig

from qualibrate_app.api.core.domain.bases.base_with_settings import (
DomainWithConfigBase,
)
from qualibrate_app.api.core.domain.bases.i_dump import IDump
from qualibrate_app.api.core.domain.bases.node import NodeBase
from qualibrate_app.api.core.domain.bases.snapshot import SnapshotBase
from qualibrate_app.api.core.models.branch import Branch as BranchModel
from qualibrate_app.api.core.types import DocumentType, IdType
from qualibrate_app.config import QualibrateAppSettings

__all__ = ["BranchBase", "BranchLoadType"]

Expand All @@ -19,16 +23,16 @@ class BranchLoadType(IntEnum):
Full = 1


class BranchBase(IDump, ABC):
class BranchBase(DomainWithConfigBase, IDump, ABC):
def __init__(
self,
name: str,
content: Optional[DocumentType] = None,
*,
settings: QualibrateAppSettings,
settings: QualibrateConfig,
):
super().__init__(settings)
self._name = name
self._settings = settings
if content is None:
self.content = {}
self._load_type = BranchLoadType.Empty
Expand Down
22 changes: 14 additions & 8 deletions backend/qualibrate_app/api/core/domain/bases/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
from enum import IntEnum
from typing import Optional

from qualibrate_config.models import QualibrateConfig

from qualibrate_app.api.core.domain.bases.base_with_settings import (
DomainWithConfigBase,
)
from qualibrate_app.api.core.domain.bases.i_dump import IDump
from qualibrate_app.api.core.domain.bases.snapshot import (
SnapshotBase,
Expand All @@ -17,29 +22,30 @@
from qualibrate_app.api.exceptions.classes.storage import (
QNotADirectoryException,
)
from qualibrate_app.config import QualibrateAppSettings

__all__ = ["NodeBase", "NodeLoadType"]

from qualibrate_app.config.vars import METADATA_OUT_PATH


class NodeLoadType(IntEnum):
Empty = 0
Snapshot = 1
Full = 2


class NodeBase(IDump, ABC):
class NodeBase(DomainWithConfigBase, IDump, ABC):
def __init__(
self,
node_id: IdType,
snapshot: SnapshotBase,
settings: QualibrateAppSettings,
settings: QualibrateConfig,
) -> None:
super().__init__(settings)
self._node_id = node_id
self._load_type = NodeLoadType.Empty
self._snapshot = snapshot
self._storage: Optional[DataFileStorage] = None
self._settings = settings

@property
def load_type(self) -> NodeLoadType:
Expand All @@ -64,15 +70,15 @@ def storage(self) -> Optional[DataFileStorage]:
def _fill_storage(self) -> None:
metadata = self._snapshot.metadata
if metadata is None or not isinstance(
metadata.get(self._settings.metadata_out_path), str
metadata.get(METADATA_OUT_PATH), str
):
self._storage = None
self._load_type = NodeLoadType.Snapshot
return
rel_output_path = metadata[self._settings.metadata_out_path]
rel_output_path = metadata[METADATA_OUT_PATH]
abs_output_path = resolve_and_check_relative(
self._settings.qualibrate.storage.location,
metadata[self._settings.metadata_out_path],
self._settings.storage.location,
metadata[METADATA_OUT_PATH],
)
if not abs_output_path.is_dir():
raise QNotADirectoryException(
Expand Down
35 changes: 19 additions & 16 deletions backend/qualibrate_app/api/core/domain/bases/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@
from pathlib import Path
from typing import Any

from qualibrate_app.api.core.models.project import Project
from qualibrate_app.config import (
QUALIBRATE_CONFIG_KEY,
QualibrateAppSettings,
read_config_file,
from qualibrate_config.file import read_config_file
from qualibrate_config.models import QualibrateConfig
from qualibrate_config.references.resolvers import resolve_references
from qualibrate_config.vars import QUALIBRATE_CONFIG_KEY

from qualibrate_app.api.core.domain.bases.base_with_settings import (
DomainWithConfigBase,
)
from qualibrate_app.config.references.resolvers import resolve_references
from qualibrate_app.api.core.models.project import Project


class ProjectsManagerBase(ABC):
def __init__(self, settings: QualibrateAppSettings, config_path: Path):
self._settings = settings
class ProjectsManagerBase(DomainWithConfigBase, ABC):
def __init__(self, settings: QualibrateConfig, config_path: Path):
super().__init__(settings)
self._config_path = config_path

@property
def project(self) -> str:
return self._settings.qualibrate.project
return self._settings.project

@project.setter
def project(self, value: str) -> None:
Expand All @@ -30,9 +32,8 @@ def project(self, value: str) -> None:
def _active_project_setter(self, value: str) -> None:
pass

@abstractmethod
def _set_user_storage_project(self, project_name: str) -> None:
pass
self._settings.project = project_name

@abstractmethod
def create(self, project_name: str) -> str:
Expand All @@ -46,7 +47,7 @@ def _get_raw_and_resolved_ref_config(
self, project_name: str
) -> tuple[Mapping[str, Any], Mapping[str, Any]]:
raw_config = read_config_file(self._config_path, solve_references=False)
# TODO: over way to update project
# TODO: over way to update project;
old_project_name = raw_config[QUALIBRATE_CONFIG_KEY]["project"]
if old_project_name == project_name:
return raw_config, deepcopy(raw_config)
Expand All @@ -68,8 +69,9 @@ def _get_raw_and_resolved_ref_config(
)
return raw_config, new_config

@classmethod
def _resolve_base_projects_path(
self, project_name: str, user_storage: Path
cls, project_name: str, user_storage: Path
) -> Path:
if project_name not in user_storage.parts:
# project name isn't part of user storage path;
Expand All @@ -80,8 +82,9 @@ def _resolve_base_projects_path(
)
return user_storage.parents[project_name_index_from_end]

@classmethod
def _resolve_new_project_path(
self,
cls,
new_project_name: str,
current_project_name: str,
current_user_storage: Path,
Expand All @@ -93,7 +96,7 @@ def _resolve_new_project_path(
project_name_index_from_start = current_user_storage.parts.index(
current_project_name
)
base_project_path = self._resolve_base_projects_path(
base_project_path = cls._resolve_base_projects_path(
current_project_name, current_user_storage
)
return base_project_path.joinpath(
Expand Down
12 changes: 8 additions & 4 deletions backend/qualibrate_app/api/core/domain/bases/root.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@
from collections.abc import Sequence
from typing import Any, Optional, Union

from qualibrate_config.models import QualibrateConfig

from qualibrate_app.api.core.domain.bases.base_with_settings import (
DomainWithConfigBase,
)
from qualibrate_app.api.core.domain.bases.branch import BranchBase
from qualibrate_app.api.core.domain.bases.node import NodeBase
from qualibrate_app.api.core.domain.bases.snapshot import SnapshotBase
from qualibrate_app.api.core.types import IdType
from qualibrate_app.config import QualibrateAppSettings

__all__ = ["RootBase"]


class RootBase(ABC):
def __init__(self, settings: QualibrateAppSettings):
self._settings = settings
class RootBase(DomainWithConfigBase, ABC):
def __init__(self, settings: QualibrateConfig):
super().__init__(settings)

@abstractmethod
def get_branch(self, branch_name: str) -> BranchBase:
Expand Down
12 changes: 8 additions & 4 deletions backend/qualibrate_app/api/core/domain/bases/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
from enum import IntEnum
from typing import Any, ClassVar, Optional, Union

from qualibrate_config.models import QualibrateConfig

from qualibrate_app.api.core.domain.bases.base_with_settings import (
DomainWithConfigBase,
)
from qualibrate_app.api.core.domain.bases.i_dump import IDump
from qualibrate_app.api.core.models.snapshot import Snapshot as SnapshotModel
from qualibrate_app.api.core.types import (
Expand All @@ -14,7 +19,6 @@
from qualibrate_app.api.core.utils.find_utils import (
get_subpath_value_on_any_depth,
)
from qualibrate_app.config import QualibrateAppSettings

__all__ = ["SnapshotBase", "SnapshotLoadType"]

Expand All @@ -27,18 +31,18 @@ class SnapshotLoadType(IntEnum):
Full = 4


class SnapshotBase(IDump, ABC):
class SnapshotBase(DomainWithConfigBase, IDump, ABC):
_items_keys: ClassVar[tuple[str, ...]] = ("data", "metadata")

def __init__(
self,
id: IdType,
content: Optional[DocumentType] = None,
*,
settings: QualibrateAppSettings,
settings: QualibrateConfig,
):
super().__init__(settings)
self._id = id
self._settings = settings
if content is None:
self._load_type = SnapshotLoadType.Empty
self.content = {}
Expand Down
11 changes: 5 additions & 6 deletions backend/qualibrate_app/api/core/domain/bases/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
from pathlib import Path
from typing import Any, Optional

from qualibrate_config.models import QualibrateConfig

from qualibrate_app.api.core.domain.bases.i_dump import IDump
from qualibrate_app.api.core.models.storage import Storage as StorageModel
from qualibrate_app.api.exceptions.classes.storage import QFileNotFoundException
from qualibrate_app.api.exceptions.classes.values import QValueException
from qualibrate_app.config import QualibrateAppSettings

__all__ = ["DataFileStorage", "StorageLoadType"]

Expand All @@ -22,9 +23,9 @@ class StorageLoadType(IntEnum):
class DataFileStorage(IDump):
data_file_name = "data.json"

def __init__(self, path: Path, settings: QualibrateAppSettings):
def __init__(self, path: Path, settings: QualibrateConfig):
if not path.is_dir():
rel_path = path.relative_to(settings.qualibrate.storage.location)
rel_path = path.relative_to(settings.storage.location)
raise QFileNotFoundException(f"{rel_path} does not exist.")
self._path = path
self._load_type = StorageLoadType.Empty
Expand All @@ -33,9 +34,7 @@ def __init__(self, path: Path, settings: QualibrateAppSettings):

@property
def path(self) -> Path:
return self._path.relative_to(
self._settings.qualibrate.storage.location
)
return self._path.relative_to(self._settings.storage.location)

@property
def data(self) -> Optional[Mapping[str, Any]]:
Expand Down
Loading
Loading