47 lines
1.2 KiB
Python

"""Basic utilities for structuring experiment configurations based on Pydantic schemas."""
import re
from abc import abstractmethod
from typing import Annotated
from pydantic import BaseModel, IPvAnyAddress, AfterValidator
from typing_extensions import Generic
from benchmarks.core.experiments.experiment import TExperiment
def drop_config_suffix(name: str) -> str:
return name[:-6] if name.endswith('Config') else name
class ConfigModel(BaseModel):
model_config = {
'alias_generator': drop_config_suffix
}
# This is a simple regex which is not by any means exhaustive but should cover gross syntax errors.
VALID_DOMAIN_NAME = re.compile(r"^localhost$|^(?!-)([A-Za-z0-9-]+\.)+[A-Za-z]{2,6}$")
def is_valid_domain_name(domain_name: str):
stripped = domain_name.strip()
matches = VALID_DOMAIN_NAME.match(stripped)
assert matches is not None
return stripped
DomainName = Annotated[str, AfterValidator(is_valid_domain_name)]
class Host(BaseModel):
address: IPvAnyAddress | DomainName
class ExperimentBuilder(Generic[TExperiment], ConfigModel):
""":class:`ExperimentBuilders` can build real :class:`Experiment`s out of :class:`ConfigModel`s. """
@abstractmethod
def build(self) -> TExperiment:
pass