Files
ss-tools/scripts/dr_recovery_contract_base.py

59 lines
2.3 KiB
Python

# #region Tooling.DrRecovery.Contract.Primitives [C:3] [TYPE Module] [SEMANTICS dr,recovery]
# @BRIEF Strict sidecar base, artifact statistics, relative paths and timezone validation.
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, field_validator
from dr_recovery_contract_types import Text, Sha256
# #region Tooling.DrRecovery.Contract.Base [C:2] [TYPE Class]
class Closed(BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True, strict=True)
# #region Tooling.DrRecovery.Contract.Base.IntegerVersion [C:3] [TYPE Function] [SEMANTICS dr,recovery]
@field_validator("schema_version", mode="before", check_fields=False)
@classmethod
def integer_version(cls, value):
if type(value) is not int:
raise ValueError("invalid version")
return value
# #endregion Tooling.DrRecovery.Contract.Base.IntegerVersion
# #endregion Tooling.DrRecovery.Contract.Base
# #region Tooling.DrRecovery.Contract.Primitives.Stat [C:1] [TYPE Class] [SEMANTICS dr,recovery]
class Stat(Closed):
bytes: int = Field(gt=0)
sha256: Sha256
# #endregion Tooling.DrRecovery.Contract.Primitives.Stat
# #region Tooling.DrRecovery.Contract.Primitives.Artifact [C:3] [TYPE Class] [SEMANTICS dr,recovery]
class Artifact(Stat):
path: Text
# #region Tooling.DrRecovery.Contract.Primitives.Artifact.ConfinedRelativePath [C:3] [TYPE Function] [SEMANTICS dr,recovery]
@field_validator("path")
@classmethod
def confined_relative_path(cls, value):
if (
value.startswith("/")
or "\\" in value
or "\x00" in value
or any(part in ("", ".", "..") for part in value.split("/"))
or len(value) > 512
):
raise ValueError("invalid path")
return value
# #endregion Tooling.DrRecovery.Contract.Primitives.Artifact.ConfinedRelativePath
# #endregion Tooling.DrRecovery.Contract.Primitives.Artifact
# #region Tooling.DrRecovery.Contract.Primitives.Aware [C:3] [TYPE Function] [SEMANTICS dr,recovery]
def aware(value):
if datetime.fromisoformat(value).utcoffset() is None:
raise ValueError("timezone required")
return value
# #endregion Tooling.DrRecovery.Contract.Primitives.Aware
# #endregion Tooling.DrRecovery.Contract.Primitives