Skip to content

Value Objects

Value Objects are immutable objects that represent domain concepts without identity. Equality is based on their attributes, not on a unique identifier.


KO (KEGG Orthology)

KO dataclass

KO(id: str)

Immutable Value Object for KEGG Orthology.

Parameters:

Name Type Description Default
id str

KO identifier in format 'KXXXXX' where X are digits Example: 'K00001', 'K12345'

required

Raises:

Type Description
ValueError

If ID does not start with 'K' or does not have exactly 6 characters

Notes

This object is immutable (frozen=True) ensuring that once created it cannot be modified, respecting the DDD Value Object principle.

Functions

__post_init__
__post_init__()

Validates KO ID format after initialization.

Raises:

Type Description
ValueError

If ID is invalid (does not start with 'K' or length != 6).

Source code in src/domain/value_objects/kegg_orthology.py
def __post_init__(self):
    """
    Validates KO ID format after initialization.

    Raises
    ------
    ValueError
        If ID is invalid (does not start with 'K' or length != 6).
    """
    if not self.id:
        logger.warning("KO validation failed: Empty ID")
        raise ValueError("KO ID cannot be empty")

    if not self.id.startswith("K"):
        logger.warning(
            "KO validation failed: Invalid prefix", extra={"ko_id": self.id}
        )
        raise ValueError(f"Invalid KO ID: {self.id}. Must start with 'K'")

    if len(self.id) != 6:
        logger.warning(
            "KO validation failed: Invalid length",
            extra={"ko_id": self.id, "length": len(self.id)},
        )
        raise ValueError(
            f"Invalid KO ID: {self.id}. Must have exactly 6 characters"
        )

    # Verifica se os 5 últimos caracteres são dígitos
    if not self.id[1:].isdigit():
        logger.warning(
            "KO validation failed: Non-numeric suffix", extra={"ko_id": self.id}
        )
        raise ValueError(
            f"Invalid KO ID: {self.id}. Last 5 characters must be digits"
        )

    logger.debug("KO created successfully", extra={"ko_id": self.id})
__str__
__str__() -> str

Returns string representation of KO.

Returns:

Type Description
str

The KO ID.

Source code in src/domain/value_objects/kegg_orthology.py
def __str__(self) -> str:
    """
    Returns string representation of KO.

    Returns
    -------
    str
        The KO ID.
    """
    return self.id
__repr__
__repr__() -> str

Returns debug representation of KO.

Returns:

Type Description
str

Representation in format "KO('KXXXXX')".

Source code in src/domain/value_objects/kegg_orthology.py
def __repr__(self) -> str:
    """
    Returns debug representation of KO.

    Returns
    -------
    str
        Representation in format "KO('KXXXXX')".
    """
    return f"KO('{self.id}')"
__hash__
__hash__() -> int

Allows using KO as dictionary key or in sets.

Returns:

Type Description
int

Hash of the ID.

Source code in src/domain/value_objects/kegg_orthology.py
def __hash__(self) -> int:
    """
    Allows using KO as dictionary key or in sets.

    Returns
    -------
    int
        Hash of the ID.
    """
    return hash(self.id)

SampleId

SampleId dataclass

SampleId(value: str)

Value Object for sample identifier.

Parameters:

Name Type Description Default
value str

Sample identifier name (cannot be empty)

required

Raises:

Type Description
ValueError

If value is empty or contains only spaces

Notes

This object is immutable ensuring identifier consistency throughout the application lifecycle.

Functions

__post_init__
__post_init__()

Validates the identifier after initialization.

Raises:

Type Description
ValueError

If value is empty or None.

Source code in src/domain/value_objects/sample_id.py
def __post_init__(self):
    """
    Validates the identifier after initialization.

    Raises
    ------
    ValueError
        If value is empty or None.
    """
    if not self.value or not self.value.strip():
        raise ValueError("Sample ID cannot be empty")
__str__
__str__() -> str

Returns string representation of Sample ID.

Returns:

Type Description
str

The identifier value.

Source code in src/domain/value_objects/sample_id.py
def __str__(self) -> str:
    """
    Returns string representation of Sample ID.

    Returns
    -------
    str
        The identifier value.
    """
    return self.value
__repr__
__repr__() -> str

Returns debug representation of Sample ID.

Returns:

Type Description
str

Representation in format "SampleId('value')".

Source code in src/domain/value_objects/sample_id.py
def __repr__(self) -> str:
    """
    Returns debug representation of Sample ID.

    Returns
    -------
    str
        Representation in format "SampleId('value')".
    """
    return f"SampleId('{self.value}')"
__hash__
__hash__() -> int

Allows using SampleId as dictionary key.

Returns:

Type Description
int

Hash of the value.

Source code in src/domain/value_objects/sample_id.py
def __hash__(self) -> int:
    """
    Allows using SampleId as dictionary key.

    Returns
    -------
    int
        Hash of the value.
    """
    return hash(self.value)

Pathway

Pathway dataclass

Pathway(id: str, name: str)

Value Object for KEGG metabolic pathway.

Parameters:

Name Type Description Default
id str

Pathway identifier (e.g., 'map00010')

required
name str

Descriptive pathway name (e.g., 'Glycolysis / Gluconeogenesis')

required

Raises:

Type Description
ValueError

If ID or name are empty

Notes

Pathways are immutable and uniquely identified by ID.

Functions

__post_init__
__post_init__()

Validates pathway fields.

Raises:

Type Description
ValueError

If ID or name are invalid.

Source code in src/domain/value_objects/pathway.py
def __post_init__(self):
    """
    Validates pathway fields.

    Raises
    ------
    ValueError
        If ID or name are invalid.
    """
    if not self.id or not self.id.strip():
        raise ValueError("Pathway ID cannot be empty")

    if not self.name or not self.name.strip():
        raise ValueError("Pathway name cannot be empty")
__str__
__str__() -> str

Returns string representation of pathway.

Returns:

Type Description
str

Pathway name.

Source code in src/domain/value_objects/pathway.py
def __str__(self) -> str:
    """
    Returns string representation of pathway.

    Returns
    -------
    str
        Pathway name.
    """
    return self.name
__repr__
__repr__() -> str

Returns debug representation of pathway.

Returns:

Type Description
str

Representation in format "Pathway('id', 'name')".

Source code in src/domain/value_objects/pathway.py
def __repr__(self) -> str:
    """
    Returns debug representation of pathway.

    Returns
    -------
    str
        Representation in format "Pathway('id', 'name')".
    """
    return f"Pathway('{self.id}', '{self.name}')"
__hash__
__hash__() -> int

Hash based on pathway ID.

Returns:

Type Description
int

Hash of the ID.

Source code in src/domain/value_objects/pathway.py
def __hash__(self) -> int:
    """
    Hash based on pathway ID.

    Returns
    -------
    int
        Hash of the ID.
    """
    return hash(self.id)

Compound

Compound dataclass

Compound(cpd: str, name: str, smiles: Optional[str] = None, chebi: Optional[str] = None)

Value Object for chemical compound.

Parameters:

Name Type Description Default
cpd str

Compound identifier code (e.g., 'C00001')

required
name str

Compound name (e.g., 'H2O', 'Water')

required
smiles Optional[str]

SMILES notation of the compound

None
chebi Optional[str]

ChEBI identifier

None

Raises:

Type Description
ValueError

If cpd or name are empty

Notes

Compounds are uniquely identified by cpd code. SMILES and ChEBI are optional for data enrichment.

Functions

__post_init__
__post_init__()

Validates required compound fields.

Raises:

Type Description
ValueError

If cpd or name are invalid.

Source code in src/domain/value_objects/compound.py
def __post_init__(self):
    """
    Validates required compound fields.

    Raises
    ------
    ValueError
        If cpd or name are invalid.
    """
    if not self.cpd or not self.cpd.strip():
        raise ValueError("Compound code (cpd) cannot be empty")

    if not self.name or not self.name.strip():
        raise ValueError("Compound name cannot be empty")
__str__
__str__() -> str

Returns string representation of compound.

Returns:

Type Description
str

Compound name.

Source code in src/domain/value_objects/compound.py
def __str__(self) -> str:
    """
    Returns string representation of compound.

    Returns
    -------
    str
        Compound name.
    """
    return self.name
__repr__
__repr__() -> str

Returns debug representation of compound.

Returns:

Type Description
str

Representation with cpd and name.

Source code in src/domain/value_objects/compound.py
def __repr__(self) -> str:
    """
    Returns debug representation of compound.

    Returns
    -------
    str
        Representation with cpd and name.
    """
    return f"Compound('{self.cpd}', '{self.name}')"
__hash__
__hash__() -> int

Hash based on compound code.

Returns:

Type Description
int

Hash of cpd.

Source code in src/domain/value_objects/compound.py
def __hash__(self) -> int:
    """
    Hash based on compound code.

    Returns
    -------
    int
        Hash of cpd.
    """
    return hash(self.cpd)
has_structure
has_structure() -> bool

Checks if compound has structural information (SMILES).

Returns:

Type Description
bool

True if SMILES is defined.

Source code in src/domain/value_objects/compound.py
def has_structure(self) -> bool:
    """
    Checks if compound has structural information (SMILES).

    Returns
    -------
    bool
        True if SMILES is defined.
    """
    return self.smiles is not None and len(self.smiles.strip()) > 0
has_chebi
has_chebi() -> bool

Checks if compound has ChEBI reference.

Returns:

Type Description
bool

True if ChEBI is defined.

Source code in src/domain/value_objects/compound.py
def has_chebi(self) -> bool:
    """
    Checks if compound has ChEBI reference.

    Returns
    -------
    bool
        True if ChEBI is defined.
    """
    return self.chebi is not None and len(self.chebi.strip()) > 0


Value Object Principles

According to Domain-Driven Design (DDD):

  1. Immutability: Once created, cannot be changed
  2. Equality by Value: Two value objects are equal if all attributes match
  3. No Identity: Don't have a unique identifier
  4. Validation: Business rules enforced at construction time