Skip to content

ump_workflow.loader

module ump-workflow

Open a bundle in the load order S4 fixes, then run it on new data (S2: score by default).

Load order, always: (1) every file’s sha256 against workflow.json and SHA256SUMS (read_bundle); (2) parse data only: inspect, the contract check and the Tier D summary need no trust; (3) code trust: the code’s sha256 must be in finprint’s trust store, or trust_code=True was passed after reading .code; otherwise nothing runs and answers come from summary.json (WORKFLOW_CODE_UNTRUSTED, SUMMARY_FALLBACK); (4) the env pin against the running versions (ENV_DRIFT warns, ENV_MAJOR_DRIFT refuses score and allows refit); (5) only then the module is executed from its verified source bytes under a unique module name. The bundle is never put on sys.path and nothing is written into it (no __pycache__).

The prep recipe’s named-step code (prep.recipe.json) is code too, and trusting the module never covers it: it runs only when each step’s hash is in finprint’s trust store (.trust_steps() after reading .step_code) or trust_steps=True is passed. Otherwise finprint refuses (CODE_UNTRUSTED) and answers come from the summary.

class

class RunResult

route: where the rerun went (score, refit, not_available); source: where the answers came from (score, refit or summary); answers: {name: {value, lo, hi, level, draws_summary, estimand, proposed}}; rows: rows used after the contract’s exclusions; history_end: the last period of the input that was run (the bundle’s training end when the answers are the summary’s).

Fields

NameTypeDefaultDescription
routestr
sourcestr
answersdict[str, dict[str, Any]]field(default_factory=dict)
noteslist[dict[str, Any]]field(default_factory=list)
rowsint0
history_endstr | NoneNone
Methods and properties (2)

to_dict method

def to_dict(self) -> dict[str, Any]

init constructor

RunResult(
self,
route: str,
source: str,
answers: dict[str, dict[str, Any]] = dict(),
notes: list[dict[str, Any]] = list(),
rows: int = 0,
history_end: str | None = None,
) -> None

Source: packages/ump-workflow/src/ump_workflow/loader.py, line 62

class

class OpenBundle

A verified bundle. .module exists only once the code is trusted.

Fields

NameTypeDefaultDescription
datadata
env_reportEnvReportcompare_env(data.workflow.get('env') or {})
Methods and properties (16)

init constructor

OpenBundle(
self,
data: BundleData,
*,
trust_code: bool = False,
trust_steps: bool = False,
trusted_hashes: Iterable[str] | None = None,
) -> None

workflow property

workflow: dict[str, Any]

code property

code: str

code_sha256 property

code_sha256: str

contract property

contract: InputContract

summary property

summary: dict[str, Any]

questions property

questions: list[dict[str, Any]]

trusted property

trusted: bool

trust method

def trust(self) -> None

Trust this code hash on this machine (finprint’s trust store, persisted). Read .code first. The prep recipe’s named-step code is not covered: see .step_code and .trust_steps().

step_code property

step_code: dict[str, str]

{step_id: source} of every named step in the prep recipe: code that runs on the input before the module does. Read it before .trust_steps().

trust_steps method

def trust_steps(self) -> None

Trust the prep recipe’s named-step code on this machine (finprint’s trust store, persisted). Read .step_code first.

inspect method

def inspect(self) -> dict[str, Any]

check method

def check(self, df: pd.DataFrame, *, mode: Mode = 'score') -> InputReport

The contract check (ump_spec.rules.check_input) on df; data only.

module property

module: types.ModuleType

answers method

def answers(self, df: pd.DataFrame) -> dict[str, dict[str, Any]]

Answers from the saved state on df as given (no contract check, no prep).

run method

def run(
self,
df: pd.DataFrame,
*,
mode: Mode | None = None,
allow_refit: bool = True,
inputs: dict[str, Any] | None = None,
) -> RunResult

Answer the bundle’s questions on df. mode defaults to the bundle’s (score). Score reuses the saved state; input that breaks continuity routes to a labelled refit (fit on df with the saved seed and params) unless allow_refit=False; anything unavailable falls back to the labelled summary. inputs binds the prep recipe’s other inputs (df binds its first).

Source: packages/ump-workflow/src/ump_workflow/loader.py, line 81

function

def load_module(source: str, name: str, filename: str | None = None) -> types.ModuleType

Execute source as a fresh module called name (registered in sys.modules while it runs, as dataclasses and pickle-free introspection need). No file is imported and no bytecode is written.

Source: packages/ump-workflow/src/ump_workflow/loader.py, line 44

function

def open_bundle(
path: str | Path,
*,
trust_code: bool = False,
trust_steps: bool = False,
trusted_hashes: Iterable[str] | None = None,
) -> OpenBundle

Verify and parse a bundle (no code runs). trust_code=True trusts its module for this object only; trust_steps=True trusts its prep recipe’s named-step code (.step_code) for this object only. trusted_hashes (sha256 hex, as share.trusted_hashes_from_approval returns) trusts the module and each named step whose hash it names, for this object only: never written to the machine’s trust store.

Source: packages/ump-workflow/src/ump_workflow/loader.py, line 340

NameTypeValueDescription
ModeLiteral['score', 'refit']