Api
BaseModel and FileModel¶
Here we define our Pydantic BaseModel
with custom settings,
as well as a FileModel
that inherits from a BaseModel
but
also represents a file on disk.
BaseModel (BaseModel)
pydantic-model
¶
is_file_link(self) -> bool
¶
Generic attribute for models backed by a file.
Source code in hydrolib/core/basemodel.py
def is_file_link(self) -> bool:
"""Generic attribute for models backed by a file."""
return False
is_intermediate_link(self) -> bool
¶
Generic attribute for models that have children fields that could contain files.
Source code in hydrolib/core/basemodel.py
def is_intermediate_link(self) -> bool:
"""Generic attribute for models that have children fields that could contain files."""
return self.is_file_link()
show_tree(self, indent = 0)
¶
Recursive print function for showing a tree of a model.
Source code in hydrolib/core/basemodel.py
def show_tree(self, indent=0):
"""Recursive print function for showing a tree of a model."""
angle = "∟" if indent > 0 else ""
# Only print if we're backed by a file
if self.is_file_link():
print(" " * indent * 2, angle, self)
# Otherwise we recurse through the fields of a model
for _, value in self:
# Handle lists of items
if not isinstance(value, list):
value = [value]
for v in value:
if hasattr(v, "is_intermediate_link") and v.is_intermediate_link():
# If the field is only an intermediate, print the name only
if not v.is_file_link():
print(" " * (indent * 2 + 2), angle, v.__class__.__name__)
v.show_tree(indent + 1)
FileModel (BaseModel, ABC)
pydantic-model
¶
Base class to represent models with a file representation.
It therefore always has a filepath
and if it is given on
initilization, it will parse that file.
This class extends the validate
option of Pydantic,
so when when a Path is given to a field with type FileModel
,
it doesn't error, but actually initializes the FileModel
.
__init__(self, filepath: Optional[pathlib.Path] = None, *args, **kwargs)
special
¶
Initialize a model.
The model is empty (with defaults) if no filepath
is given,
otherwise the file at filepath
will be parsed.
Source code in hydrolib/core/basemodel.py
def __init__(self, filepath: Optional[Path] = None, *args, **kwargs):
"""Initialize a model.
The model is empty (with defaults) if no `filepath` is given,
otherwise the file at `filepath` will be parsed."""
# Parse the file if path is given
context_dir_reset_token = None
if filepath:
filepath = Path(filepath) # so we also accept strings
# If a context is set, use it
if (folder := context_dir.get(None)) and not filepath.is_absolute():
logger.info(f"Used context to get {folder} for {filepath}")
filepath = folder / filepath
# Otherwise we're the root filepath
# and should set the context
else:
logger.info(f"Set context to {filepath.parent}")
context_dir_reset_token = context_dir.set(filepath.parent)
data = self._load(filepath)
data["filepath"] = filepath
kwargs.update(data)
super().__init__(*args, **kwargs)
_reset_context_dir(context_dir_reset_token)
__str__(self) -> str
special
¶
Return str(self).
Source code in hydrolib/core/basemodel.py
def __str__(self) -> str:
return str(self.filepath if self.filepath else "")
is_file_link(self) -> bool
¶
Generic attribute for models backed by a file.
Source code in hydrolib/core/basemodel.py
def is_file_link(self) -> bool:
return True
save(self, folder: Optional[pathlib.Path] = None) -> Path
¶
Save model and child models to their set filepaths.
If a folder is given, for models with an unset filepath,
we generate one based on the given folder
and a default name.
Otherwise we override the folder part of already set filepaths.
This can thus be used to copy complete models.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
folder |
Optional[pathlib.Path] |
path to the folder where this FileModel will be stored |
None |
Source code in hydrolib/core/basemodel.py
def save(self, folder: Optional[Path] = None) -> Path:
"""Save model and child models to their set filepaths.
If a folder is given, for models with an unset filepath,
we generate one based on the given `folder` and a default name.
Otherwise we override the folder part of already set filepaths.
This can thus be used to copy complete models.
Args:
folder: path to the folder where this FileModel will be stored
"""
if not self.filepath and not folder:
raise ValueError(
"Either set the `filepath` on the model or pass a `folder` when saving."
)
if not folder:
folder = self.filepath.absolute().parent
self._apply_recurse("_save", folder)
return self.filepath.absolute()