From 062305ee958dec051760a8d73b90cd11187c1bc5 Mon Sep 17 00:00:00 2001 From: Korawich Anuttra Date: Tue, 4 Jun 2024 15:26:02 +0700 Subject: [PATCH] :page_facing_up: docs: update doc-str on param. --- pyproject.toml | 2 ++ src/ddeutil/io/__base/__init__.py | 1 + src/ddeutil/io/__base/files.py | 14 ++++++++++++-- src/ddeutil/io/config.py | 4 ++++ src/ddeutil/io/exceptions.py | 4 +--- src/ddeutil/io/models/datasets/db.py | 23 ++++++----------------- src/ddeutil/io/param.py | 20 +++++++++++++++++--- tests/test_param.py | 24 ++++++++++++++++++++++++ 8 files changed, 67 insertions(+), 25 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f0b788b..b42a9ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,8 @@ dependencies = [ "fmtutil", "tzdata", "pydantic==2.7.2", + "msgspec==0.18.6", + "msgpack==1.0.8", "deepdiff==7.0.1", "pyyaml==6.0.1", "toml==0.10.2", diff --git a/src/ddeutil/io/__base/__init__.py b/src/ddeutil/io/__base/__init__.py index 8edddb5..2921d80 100644 --- a/src/ddeutil/io/__base/__init__.py +++ b/src/ddeutil/io/__base/__init__.py @@ -20,6 +20,7 @@ JsonEnvFl, JsonFl, MarshalFl, + MsgpackFl, PickleFl, TomlEnvFl, TomlFl, diff --git a/src/ddeutil/io/__base/files.py b/src/ddeutil/io/__base/files.py index a8af191..c4b529f 100644 --- a/src/ddeutil/io/__base/files.py +++ b/src/ddeutil/io/__base/files.py @@ -42,9 +42,8 @@ get_args, ) +import msgpack import toml - -# NOTE: import msgpack import yaml from ddeutil.core import must_split @@ -578,6 +577,16 @@ def write(self, data): marshal.dump(data, _w) +class MsgpackFl(Fl): + def read(self): + with self.open(mode="rb") as _r: + return msgpack.loads(_r.read()) + + def write(self, data): + with self.open(mode="wb") as _w: + msgpack.dump(data, _w) + + __all__ = ( "Fl", "EnvFl", @@ -591,5 +600,6 @@ def write(self, data): "TomlFl", "TomlEnvFl", "MarshalFl", + "MsgpackFl", "PickleFl", ) diff --git a/src/ddeutil/io/config.py b/src/ddeutil/io/config.py index 138703d..9a21e72 100644 --- a/src/ddeutil/io/config.py +++ b/src/ddeutil/io/config.py @@ -80,6 +80,10 @@ def load(self, name: str, *, order: int = 1) -> dict[str, Any]: :param order: An order number that want to get from ordered list of duplicate data. :type order: int(=1) + + :rtype: dict[str, Any] + :returns: A loaded data from open file object that already adding + `alias` key with a config name. """ rs: list[dict[Any, Any]] if rs := [ diff --git a/src/ddeutil/io/exceptions.py b/src/ddeutil/io/exceptions.py index d191bf3..de45994 100644 --- a/src/ddeutil/io/exceptions.py +++ b/src/ddeutil/io/exceptions.py @@ -8,8 +8,6 @@ """ from __future__ import annotations -from typing import Union - class BaseError(Exception): """Base Error Object that use for catch any errors statement of @@ -28,7 +26,7 @@ class ConfigNotFound(IOBaseError): class ConfigArgumentError(IOBaseError): """Error raise for a wrong configuration argument.""" - def __init__(self, argument: Union[str, tuple], message: str): + def __init__(self, argument: str | tuple, message: str) -> None: """Main Initialization that merge the argument and message input values with specific content message together like diff --git a/src/ddeutil/io/models/datasets/db.py b/src/ddeutil/io/models/datasets/db.py index 1cdcbda..2de4eeb 100644 --- a/src/ddeutil/io/models/datasets/db.py +++ b/src/ddeutil/io/models/datasets/db.py @@ -60,11 +60,8 @@ class Tbl(BaseTbl): ] @field_validator("pk") - def __receive_pk_from_schemas( - cls, - value: Pk, - info: ValidationInfo, - ) -> Pk: + def __receive_pk_from_features(cls, value: Pk, info: ValidationInfo) -> Pk: + """Receive the primary key from the features.""" # NOTE: # we respect that `info.data` should contain schema before `pk` # validation. @@ -87,25 +84,17 @@ def __prepare_fk(cls, value: list[Fk], info: ValidationInfo) -> list[Fk]: return value -class BaseFunc(BaseDef): +class BaseDefine(BaseDef): definition: str -class Func(BaseFunc): ... +class Func(BaseDefine): ... -class BaseProc(BaseDef): - definition: str - - -class Proc(BaseProc): ... - - -class BaseView(BaseDef): - definition: str +class Proc(BaseDefine): ... -class View(BaseView): ... +class View(BaseDefine): ... class BaseScm(BaseUpdatableModel): diff --git a/src/ddeutil/io/param.py b/src/ddeutil/io/param.py index 68ce16b..73b4ce5 100644 --- a/src/ddeutil/io/param.py +++ b/src/ddeutil/io/param.py @@ -79,7 +79,7 @@ class Stage(BaseModel): layer: int = Field(default=0) @field_validator("format", mode="before") - def validate_format(cls, value, info: ValidationInfo): + def validate_format(cls, value: str, info: ValidationInfo): # NOTE: # Validate the name in format string should contain any format name. if not ( @@ -125,6 +125,16 @@ def validate_rule_relate_with_format(cls, value, info: ValidationInfo): class PathData(BaseModel): + """Path Data Model that keep necessary paths for register or loading object. + + Examples: + >>> path_data = { + ... "root": "./", + ... "data": "./data", + ... "conf": "./config", + ... } + """ + root: Path = Field(default_factory=Path) data: Path = Field(default=None, validate_default=True) conf: Path = Field(default=None, validate_default=True) @@ -157,7 +167,6 @@ class Params(BaseModel, validate_assignment=True): @classmethod def from_yaml(cls, path: Union[str, Path]): """Load params from .yaml file""" - cls._origin_path = path return cls.model_validate(YamlEnvFl(path).read()) @field_validator("stages", mode="before") @@ -179,7 +188,12 @@ def stage_first(self) -> str: return min(self.stages.items(), key=lambda i: i[1].layer)[0] def get_stage(self, name: str) -> Stage: - """Return Stage model that match with stage name.""" + """Return Stage model that match with stage name. If an input stage + value equal 'base', it will return the default stage model. + + :param name: A stage name that want to getting from this params. + :type name: str + """ if name == "base": return Stage.model_validate( { diff --git a/tests/test_param.py b/tests/test_param.py index bf675c5..892ef30 100644 --- a/tests/test_param.py +++ b/tests/test_param.py @@ -1,7 +1,9 @@ from pathlib import Path import ddeutil.io.param as md +import pytest from ddeutil.io.__conf import UPDATE_KEY, VERSION_KEY +from ddeutil.io.exceptions import ConfigArgumentError def test_model_path_default(test_path): @@ -69,6 +71,28 @@ def test_model_stage_data(): "layer": 0, } == stage.model_dump() + with pytest.raises(ConfigArgumentError): + md.Stage.model_validate( + { + "alias": "persisted", + "format": "timestamp.json", + "rules": { + "timestamp": {"minutes": 15}, + }, + } + ) + + with pytest.raises(ConfigArgumentError): + md.Stage.model_validate( + { + "alias": "persisted", + "format": "{datetime:%Y%m%d}.json", + "rules": { + "timestamp": {"minutes": 15}, + }, + } + ) + def test_model_params(): params = md.Params.model_validate(