Skip to content

Commit

Permalink
refactor: pydantic 2
Browse files Browse the repository at this point in the history
  • Loading branch information
makkus committed Nov 1, 2023
1 parent ebb250b commit 3da175f
Show file tree
Hide file tree
Showing 68 changed files with 584 additions and 487 deletions.
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ dependencies = [
"orjson==3.8.10",
"pp-ez>=0.2.0",
"puremagic>=1.15",
"pydantic>=1.10.0,<2.0.0",
"pydantic>=2.0.0,<3.0.0",
"pydantic-settings>=2.0.0",
"pytz>=2022.6",
"pyzmq>=25.0.0",
"regex>=2022.4.0",
Expand All @@ -68,7 +69,7 @@ dependencies = [
"sortedcontainers>=2.4.0",
"stevedore>=5.0.0,<6.0.0",
"structlog>=21.5.0",
"typing_extensions==4.5.0",
"typing_extensions>=4.6.0",
"tzlocal>=2.1,<5.0",
]
dynamic = ["version"]
Expand Down
8 changes: 8 additions & 0 deletions src/kiara/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import structlog
import typing

from .utils import is_develop, is_debug
from .utils.class_loading import (
KiaraEntryPointItem,
find_kiara_model_classes_under,
Expand Down Expand Up @@ -86,6 +87,13 @@ def DBG(
except ImportError: # Graceful fallback if IceCream isn't installed.
pass

if is_develop() or is_debug():
try:
from icecream import install

install()
except ImportError: # Graceful fallback if IceCream isn't installed.
pass

"""Top-level package for kiara."""

Expand Down
2 changes: 1 addition & 1 deletion src/kiara/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ def save_values(
persisted_data=None,
)

return StoreValuesResult.construct(__root__=stored)
return StoreValuesResult.model_construct(root=stored)

def create_context_summary(self) -> ContextInfo:
return ContextInfo.create_from_context(kiara=self)
Expand Down
28 changes: 13 additions & 15 deletions src/kiara/context/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Mapping, Union

import structlog
from pydantic import BaseModel, root_validator, validator
from pydantic.config import Extra
from pydantic.env_settings import BaseSettings
from pydantic import BaseModel, ConfigDict, field_validator, model_validator
from pydantic.fields import Field, PrivateAttr
from pydantic_settings import BaseSettings, SettingsConfigDict
from ruamel import yaml as r_yaml

from kiara.context.runtime_config import KiaraRuntimeConfig
Expand Down Expand Up @@ -71,8 +70,7 @@ def archive_uuid(self) -> uuid.UUID:


class KiaraContextConfig(BaseModel):
class Config:
extra = Extra.forbid
model_config = ConfigDict(extra="forbid")

context_id: str = Field(description="A globally unique id for this kiara context.")

Expand Down Expand Up @@ -105,10 +103,9 @@ def add_pipelines(self, *pipelines: str):


class KiaraSettings(BaseSettings):
class Config:
extra = Extra.forbid
validate_assignment = True
env_prefix = "kiara_setting_"
model_config = SettingsConfigDict(
extra="forbid", validate_assignment=True, env_prefix="kiara_setting_"
)

syntax_highlight_background: str = Field(
description="The background color for code blocks when rendering to terminal, Jupyter, etc.",
Expand All @@ -120,10 +117,9 @@ class Config:


class KiaraConfig(BaseSettings):
class Config:
env_prefix = "kiara_"
extra = Extra.forbid
use_enum_values = True
model_config = SettingsConfigDict(
env_prefix="kiara_", extra="forbid", use_enum_values=True
)

@classmethod
def create_in_folder(cls, path: Union[Path, str]) -> "KiaraConfig":
Expand Down Expand Up @@ -196,15 +192,17 @@ def load_from_file(cls, path: Union[Path, None] = None) -> "KiaraConfig":
_context_data: Dict[str, KiaraContextConfig] = PrivateAttr(default_factory=dict)
_config_path: Union[Path, None] = PrivateAttr(default=None)

@validator("context_search_paths")
@field_validator("context_search_paths")
@classmethod
def validate_context_search_paths(cls, v):

if not v or not v[0]:
v = [KIARA_MAIN_CONTEXTS_PATH]

return v

@root_validator(pre=True)
@model_validator(mode="before")
@classmethod
def _set_paths(cls, values: Any):

base_path = values.get("base_data_path", None)
Expand Down
10 changes: 5 additions & 5 deletions src/kiara/context/runtime_config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from enum import Enum

from pydantic import BaseSettings, Extra, Field
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict


class JobCacheStrategy(Enum):
Expand All @@ -12,10 +13,9 @@ class JobCacheStrategy(Enum):


class KiaraRuntimeConfig(BaseSettings):
class Config:
extra = Extra.forbid
validate_assignment = True
env_prefix = "kiara_runtime_"
model_config = SettingsConfigDict(
extra="forbid", validate_assignment=True, env_prefix="kiara_runtime_"
)

job_cache: JobCacheStrategy = Field(
description="Name of the strategy that determines when to re-run jobs or use cached results.",
Expand Down
27 changes: 11 additions & 16 deletions src/kiara/data_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@
import uuid
from typing import TYPE_CHECKING, Any, Generic, Mapping, Tuple, Type, TypeVar, Union

import orjson
import structlog
from deepdiff import DeepHash
from pydantic import BaseModel, Extra, PrivateAttr, ValidationError
from pydantic import BaseModel, ConfigDict, PrivateAttr, ValidationError
from rich import box
from rich.console import Console, ConsoleOptions, RenderResult
from rich.rule import Rule
Expand All @@ -41,21 +40,20 @@
from kiara.defaults import (
INVALID_HASH_MARKER,
INVALID_SIZE_MARKER,
KIARA_HASH_FUNCTION,
NO_SERIALIZATION_MARKER,
SpecialValue,
)
from kiara.exceptions import KiaraValueException, ValueTypeConfigException
from kiara.models.python_class import PythonClass
from kiara.models.values import DataTypeCharacteristics, ValueStatus
from kiara.models.values.value_schema import ValueSchema
from kiara.utils.hashing import KIARA_HASH_FUNCTION

#
# if obj.__class__.__module__ == "builtins":
# return obj.__class__.__name__
# else:
# return f"{obj.__class__.__module__}.{obj.__class__.__name__}"
from kiara.utils.json import orjson_dumps

if TYPE_CHECKING:
from kiara.models.values.value import (
Expand All @@ -80,24 +78,21 @@ class DataTypeConfig(BaseModel):
a ``DataType`` is not configurable, unless the ``_config_cls`` class attribute points to a sub-class of this class.
"""

class Config:
json_loads = orjson.loads
json_dumps = orjson_dumps
extra = Extra.forbid
model_config = ConfigDict(extra="forbid")

@classmethod
def requires_config(cls) -> bool:
"""Return whether this class can be used as-is, or requires configuration before an instance can be created."""
for field_name, field in cls.__fields__.items():
if field.required and field.default is None:
for field_name, field in cls.model_fields.items():
if field.is_required() and field.default is None:
return True
return False

_config_hash: Union[int, None] = PrivateAttr(default=None)

def get(self, key: str) -> Any:
"""Get the value for the specified configuation key."""
if key not in self.__fields__:
if key not in self.model_fields.keys():
raise Exception(
f"No config value '{key}' in module config class '{self.__class__.__name__}'."
)
Expand Down Expand Up @@ -131,7 +126,7 @@ def __rich_console__(
my_table = Table(box=box.MINIMAL, show_header=False)
my_table.add_column("Field name", style="i")
my_table.add_column("Value")
for field in self.__fields__:
for field in self.model_fields.keys():
my_table.add_row(field, getattr(self, field))

yield my_table
Expand Down Expand Up @@ -193,7 +188,9 @@ def _calculate_data_type_hash(
def __init__(self, **type_config: Any):

try:
self._type_config: TYPE_CONFIG_CLS = self.__class__.data_type_config_class()(**type_config) # type: ignore # TODO: double-check this is only a mypy issue
self._type_config: TYPE_CONFIG_CLS = (
self.__class__.data_type_config_class()(**type_config)
)
except ValidationError as ve:
raise ValueTypeConfigException(
f"Error creating object for type: {ve}",
Expand Down Expand Up @@ -496,9 +493,7 @@ def create_renderable(self, **config):
table.add_column("key")
table.add_column("value", style="i")
table.add_row("type_name", self.data_type_name)
config_json = self.type_config.json(
exclude_unset=True, option=orjson.OPT_INDENT_2
)
config_json = self.type_config.model_dump_json(exclude_unset=True, indent=2)
config = Syntax(config_json, "json", background_color="default")
table.add_row("type_config", config)

Expand Down
18 changes: 10 additions & 8 deletions src/kiara/data_types/included_core_types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import (
TYPE_CHECKING,
Any,
ClassVar,
Dict,
Generic,
Iterable,
Expand Down Expand Up @@ -50,7 +51,7 @@ class NoneType(DataType[SpecialValue, DataTypeConfig]):

"""Type indicating a 'None' value."""

_data_type_name = "none"
_data_type_name: ClassVar[str] = "none"

@classmethod
def python_class(cls) -> Type:
Expand Down Expand Up @@ -96,7 +97,7 @@ class AnyType(
this might or might not change).
"""

_data_type_name = "any"
_data_type_name: ClassVar[str] = "any"

@classmethod
def python_class(cls) -> Type:
Expand Down Expand Up @@ -185,7 +186,7 @@ class BytesType(AnyType[bytes, DataTypeConfig]):

"""An array of bytes."""

_data_type_name = "bytes"
_data_type_name: ClassVar[str] = "bytes"

@classmethod
def python_class(cls) -> Type:
Expand Down Expand Up @@ -230,15 +231,16 @@ def _pretty_print_as__string(
class StringTypeConfig(DataTypeConfig):

allowed_strings: Union[None, List[str]] = Field(
description="A list of allowed strings, if empty or None, any string is allowed."
description="A list of allowed strings, if empty or None, any string is allowed.",
default=None,
)


class StringType(AnyType[str, StringTypeConfig]):

"""A string."""

_data_type_name = "string"
_data_type_name: ClassVar[str] = "string"

@classmethod
def data_type_config_class(cls) -> Type[TYPE_CONFIG_CLS]:
Expand Down Expand Up @@ -309,7 +311,7 @@ class BooleanType(AnyType[bool, DataTypeConfig]):

"A boolean."

_data_type_name = "boolean"
_data_type_name: ClassVar[str] = "boolean"

@classmethod
def python_class(cls) -> Type:
Expand Down Expand Up @@ -357,7 +359,7 @@ class DictValueType(AnyType[KiaraDict, DataTypeConfig]):
[DictModel][kiara_plugin.core_types.models.DictModel] class.
"""

_data_type_name = "dict"
_data_type_name: ClassVar[str] = "dict"

@classmethod
def python_class(cls) -> Type:
Expand Down Expand Up @@ -528,7 +530,7 @@ class KiaraModelValueBaseType(
This type should not be used by user-facing modules and/or operations.
"""

_data_type_name = None # type: ignore
_data_type_name: ClassVar[str] = None # type: ignore

@classmethod
def data_type_config_class(cls) -> Type[TYPE_CONFIG_CLS]:
Expand Down
15 changes: 7 additions & 8 deletions src/kiara/data_types/included_core_types/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
#
# Mozilla Public License, version 2.0 (see LICENSE or https://www.mozilla.org/en-US/MPL/2.0/)

from typing import TYPE_CHECKING, Any, Dict, Mapping, Type, Union
from typing import TYPE_CHECKING, Any, ClassVar, Dict, Mapping, Type, Union

import humanfriendly
import orjson.orjson
import structlog
from pydantic import Field
from rich import box
Expand Down Expand Up @@ -41,7 +40,7 @@ class FileValueType(KiaraModelValueBaseType[KiaraFile, FileTypeConfig]):

"""A file."""

_data_type_name = "file"
_data_type_name: ClassVar[str] = "file"

@classmethod
def retrieve_available_type_profiles(cls) -> Mapping[str, Mapping[str, Any]]:
Expand Down Expand Up @@ -118,7 +117,7 @@ def _pretty_print_as__string(
self, value: "Value", render_config: Mapping[str, Any]
) -> Any:

data: Any = value.data
data: KiaraFile = value.data
max_lines = render_config.get("max_lines", 34)
try:
lines = []
Expand All @@ -139,9 +138,9 @@ def _pretty_print_as__string(
"",
"[b]File metadata:[/b]",
"",
data.json(option=orjson.OPT_INDENT_2),
data.model_dump_json(indent=2),
]
return "\n".join("lines")
return "\n".join(lines)

def _pretty_print_as__terminal_renderable(
self, value: "Value", render_config: Mapping[str, Any]
Expand All @@ -166,7 +165,7 @@ def _pretty_print_as__terminal_renderable(
"",
"[b]File metadata:[/b]",
"",
data.json(option=orjson.OPT_INDENT_2),
data.model_dump_json(indent=2),
]
preview = Panel(
"Binary file or non-utf8 enconding, not printing content...",
Expand All @@ -192,7 +191,7 @@ class FileBundleValueType(AnyType[KiaraFileBundle, FileTypeConfig]):

"""A bundle of files (like a folder, zip archive, etc.)."""

_data_type_name = "file_bundle"
_data_type_name: ClassVar[str] = "file_bundle"

@classmethod
def retrieve_available_type_profiles(cls) -> Mapping[str, Mapping[str, Any]]:
Expand Down
Loading

0 comments on commit 3da175f

Please sign in to comment.