Skip to content

API Reference - Models

pyepisuite.models

ModuleError dataclass

A module that failed to estimate, returned in place of its result.

The three fields are deliberately required: that lets dacite tell an error payload apart from a real module result when resolving the Union[ModuleError, ...] used for every module on ResultEPISuite. A normal result has none of these keys, so it falls through to the result type; only a genuine error object matches here.

Source code in src/pyepisuite/models.py
@dataclass
class ModuleError:
    """A module that failed to estimate, returned in place of its result.

    The three fields are deliberately required: that lets dacite tell an error
    payload apart from a real module result when resolving the
    ``Union[ModuleError, ...]`` used for every module on ``ResultEPISuite``.
    A normal result has none of these keys, so it falls through to the result
    type; only a genuine error object matches here.
    """
    module: str
    code: str
    message: str

Parameters dataclass

Request inputs echoed back by the API.

Only the inputs actually supplied are present; everything else is absent. Names follow the v1.1.0 submit query parameters.

Source code in src/pyepisuite/models.py
@dataclass
class Parameters:
    """Request inputs echoed back by the API.

    Only the inputs actually supplied are present; everything else is absent.
    Names follow the v1.1.0 submit query parameters.
    """
    smiles: Optional[str] = None
    cas: Optional[str] = None
    chemicalName: Optional[str] = None
    logKow: Optional[NumericParameter] = None
    molecularWeight: Optional[NumericParameter] = None
    waterSolubilityMgPerL: Optional[NumericParameter] = None
    meltingPointC: Optional[NumericParameter] = None
    vaporPressureMmHg: Optional[NumericParameter] = None
    henryAtmM3PerMol: Optional[NumericParameter] = None
    logKoa: Optional[NumericParameter] = None
    koc: Optional[NumericParameter] = None
    boilingPointC: Optional[NumericParameter] = None
    subcooledVaporPressureMmHg: Optional[NumericParameter] = None
    aopRateConstant: Optional[NumericParameter] = None
    biowinScore: Optional[NumericParameter] = None
    biowin3: Optional[NumericParameter] = None
    biowin5: Optional[NumericParameter] = None
    tspUgPerM3: Optional[NumericParameter] = None
    theta: Optional[NumericParameter] = None
    userKpCmPerHour: Optional[NumericParameter] = None
    waterConcentrationMgPerCm3: Optional[NumericParameter] = None
    waterConcentrationMgPerLiter: Optional[NumericParameter] = None
    eventFrequencyPerDay: Optional[NumericParameter] = None
    exposureDurationYears: Optional[NumericParameter] = None
    exposureFrequencyDaysPerYear: Optional[NumericParameter] = None
    skinSurfaceAreaCm2: Optional[NumericParameter] = None
    bodyWeightKg: Optional[NumericParameter] = None
    averagingTimeDays: Optional[NumericParameter] = None
    fractionAbsorbed: Optional[NumericParameter] = None
    eventDurationHours: Optional[NumericParameter] = None
    halfLifeHoursPrimaryClarifier: Optional[NumericParameter] = None
    halfLifeHoursAerationVessel: Optional[NumericParameter] = None
    halfLifeHoursSettlingTank: Optional[NumericParameter] = None
    halfLifeAir: Optional[NumericParameter] = None
    halfLifeWater: Optional[NumericParameter] = None
    halfLifeSoil: Optional[NumericParameter] = None
    halfLifeSediment: Optional[NumericParameter] = None
    emissionRateAir: Optional[NumericParameter] = None
    emissionRateWater: Optional[NumericParameter] = None
    emissionRateSoil: Optional[NumericParameter] = None
    emissionRateSediment: Optional[NumericParameter] = None
    advectionTimeAir: Optional[NumericParameter] = None
    advectionTimeWater: Optional[NumericParameter] = None
    advectionTimeSoil: Optional[NumericParameter] = None
    advectionTimeSediment: Optional[NumericParameter] = None
    ohConcentrationE6OhPerCm3: Optional[NumericParameter] = None
    ozoneConcentrationE11MolPerCm3: Optional[NumericParameter] = None
    daylightHours: Optional[NumericParameter] = None
    riverWindMPerSec: Optional[NumericParameter] = None
    riverCurrentMPerSec: Optional[NumericParameter] = None
    riverDepthMeters: Optional[NumericParameter] = None
    lakeWindMPerSec: Optional[NumericParameter] = None
    lakeCurrentMPerSec: Optional[NumericParameter] = None
    lakeDepthMeters: Optional[NumericParameter] = None
    vaporPressureTemperatureC: Optional[NumericParameter] = None
    waterSolubilityProvider: Optional[str] = None
    removeMetals: Optional[BoolParameter] = None
    modules: Optional[List[str]] = None

TypedEcosarResult dataclass

One of the typed ECOSAR submodels (surfactant, polymer or dye).

These run only when the caller supplies the submodel's own inputs (chain length, ethoxylate count, and so on), so for an ordinary organic submission every typed submodel comes back as a ModuleError instead.

Source code in src/pyepisuite/models.py
@dataclass
class TypedEcosarResult:
    """One of the typed ECOSAR submodels (surfactant, polymer or dye).

    These run only when the caller supplies the submodel's own inputs (chain
    length, ethoxylate count, and so on), so for an ordinary organic submission
    every typed submodel comes back as a `ModuleError` instead.
    """
    model: Optional[str] = None
    module: Optional[str] = None
    submodule: Optional[str] = None
    success: Optional[bool] = None
    predictionCount: Optional[int] = None
    parameters: Optional[Dict[str, Any]] = None
    resolvedInputs: Optional[Dict[str, Any]] = None
    estimates: Optional[TypedEcosarEstimates] = None
    flags: Optional[Dict[str, Any]] = None
    modelDetails: Optional[Dict[str, Any]] = None
    predictions: Optional[List[TypedEcosarPrediction]] = None
    notes: Optional[List[str]] = None
    alerts: Optional[List[str]] = None
    smiles: Optional[str] = None
    input: Optional[str] = None
    parameterSchema: Optional[Dict[str, Any]] = None
    trace: Optional[Dict[str, Any]] = None
    output: Optional[str] = None

Value dataclass

A measured, estimated or user-supplied quantity with its provenance.

The v1.1.0 API models every value this way, whether it is an estimate, one of a property's experimental values, the selected value, or an echoed request parameter.

Source code in src/pyepisuite/models.py
@dataclass
class Value:
    """A measured, estimated or user-supplied quantity with its provenance.

    The v1.1.0 API models every value this way, whether it is an estimate, one
    of a property's experimental values, the selected value, or an echoed
    request parameter.
    """
    author: Optional[str] = None
    year: Optional[int] = None
    order: Optional[int] = None
    value: Optional[float] = None
    units: Optional[str] = None
    source: Optional[str] = None
    valueType: Optional[str] = None
    method: Optional[str] = None
    evidenceType: Optional[str] = None
    sourceDatabase: Optional[str] = None
    sourceTable: Optional[str] = None
    sourceId: Optional[int] = None
    referenceId: Optional[int] = None
    temperatureC: Optional[float] = None
    pressureMmHg: Optional[float] = None
    notes: Optional[str] = None

ensure_flags(value)

Normalize flags input to Optional[Dict[str,bool]].

Accepts dict, iterable of (key, val) pairs, iterable of keys, generator, and some string forms. Returns None when no usable value.

Source code in src/pyepisuite/models.py
def ensure_flags(value: Any) -> Optional[Dict[str, bool]]:
    """Normalize flags input to Optional[Dict[str,bool]].

    Accepts dict, iterable of (key, val) pairs, iterable of keys, generator, and some string forms.
    Returns None when no usable value.
    """
    if value is None:
        return None

    # Already a dict -> coerce values to bool
    if isinstance(value, dict):
        return {str(k): bool(v) for k, v in value.items()}

    # Strings handled below
    if isinstance(value, str):
        s = value.strip()
        # reject python repr of generator like "<generator object ...>"
        if s.startswith("<") and "generator" in s:
            return None
        # parse "a:True,b:False"
        if ":" in s and "," in s:
            out = {}
            for part in s.split(","):
                if ":" in part:
                    k, v = part.split(":", 1)
                    out[k.strip()] = v.strip().lower() in ("1", "true", "yes")
            return out or None
        # comma-separated keys -> True
        if "," in s:
            return {p.strip(): True for p in s.split(",") if p.strip()} or None
        # single token -> treat as key True
        return {s: True}

    # Iterable (list/tuple/generator) of pairs or keys
    try:
        it = iter(value)
    except TypeError:
        return None

    out: Dict[str, bool] = {}
    for item in it:
        if isinstance(item, (list, tuple)) and len(item) >= 2:
            k, v = item[0], item[1]
            out[str(k)] = bool(v)
        else:
            # single item -> key True
            out[str(item)] = True

    return out or None