Skip to content

ump_spec.models.recipe

module ump-spec

provisional (not yet in the spec) G-DATA-06 is in the gate registry but not yet in the specification’s gate catalogue, so it is not normative.

Transform recipes: how a derived dataset was made (POC blueprint TRANSFORM-RECIPES §4 and §6; spec §6).

TransformRecipe is the normative form of <output>.recipe.json (schema ump.transform_recipe/0.1), the file finprint writes beside an analyst’s output. The client package keeps its own copy of these models (analysts install it without ump_spec); its committed JSON Schema (packages/finprint/schema/transform_recipe.schema.json) MUST equal schemas/transform-recipe.json, and a test in finprint fails on drift. Class names are part of the schema ($defs keys), so they match the client package exactly, and every one carries a Recipe prefix (or is unique, ReaderSpec, TransformRecipe) so the web’s merged type bundle has no name collision with Note.

What a recipe never holds: row values, cell outputs, environment variables, absolute paths (basenames only), values of arguments whose name looks secret ("<redacted>") and string arguments longer than 200 characters (a short prefix plus their hash). Merkle leaves hold the recipe’s sha256 only, never its body.

RecipeRef is what a catalogued Dataset carries (Dataset.recipe): a pointer to the stored recipe blob plus the few facts the catalogue page and gate G-DATA-06 read. apps/data never executes a recipe, so verification is always the analyst’s own report (checked_by: "self").

class

class ReaderSpec(_Model)

Fields

NameTypeDefaultDescription
fnLiteral['read_csv', 'read_excel', 'read_parquet', 'read_catalogue']
kwargsdict[str, Any]dict()Reader keyword arguments, tagged JSON (no path).
replayableboolTrue

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 68

class

class RecipeCell(_Model)

Fields

NameTypeDefaultDescription
execution_countint | NoneNone
orderint
sourcestr
frames_changedlist[str]list()

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 120

class

class RecipeEnvironment(_Model)

Fields

NameTypeDefaultDescription
pythonstr
pandasstr
numpystr
ump_recipestr
platformstr

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 140

class

class RecipeExternalInput(_Model)

A recipe input with no catalogued match in the client’s scope (UNCATALOGUED_INPUT).

Fields

NameTypeDefaultDescription
input_idstr
namestr | NoneNone
sourceLiteral['file', 'catalogue', 'in_memory']'file'
sha256str | NoneNone
catalogue_fingerprintstr | NoneNone
fingerprint_seenstr | NoneNonefetch_record.fingerprint_seen the recipe carried, kept so the hash a catalogue read saw is not lost.

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 205

class

class RecipeInput(_Model)

Fields

NameTypeDefaultDescription
input_idstrAlso the frame id steps use to refer to this input.
namestr
sourceLiteral['file', 'catalogue', 'in_memory']
path_basenamestr | NoneNone
sha256str | NoneNonesha256 hex of the file bytes (stored catalogue datasets: blob hash).
fingerprintstrCanonical-rows fingerprint of the frame as read (see fingerprint_basis).
fingerprint_basisstrRECIPE_FINGERPRINT_BASIS
dataset_idstr | NoneNone
catalogue_fingerprintstr | NoneNoneThe catalogue’s rule (ump_spec.rules.canonical_rows_fingerprint, basis canonical_rows) over the frame as read, cells as plain JSON values; column and row order free. apps/data matches inputs to connected datasets by it.
fingerprint_seenstr | NoneNonefetch_record.fingerprint_seen from apps/data when read from the catalogue (blob hash for stored datasets, canonical rows of the raw rows for connected ones).
copy_policy_CopyPolicy | NoneNone
readerReaderSpec | NoneNone
rowsint
columnsdict[str, str]Column name to pandas dtype.

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 74

class

class RecipeInputMatch(_Model)

A recipe input matched to a catalogued dataset in the same client’s scope (a derived_from edge).

Fields

NameTypeDefaultDescription
input_idstr
namestr | NoneNone
dataset_idstr
dataset_versionint | NoneNoneThe version of the matched dataset whose hash the input matched (its derived_from edge points at that dataset).
matched_byLiteral['sha256', 'catalogue_fingerprint', 'dataset_id', 'dataset_id_drifted']sha256: file or blob bytes; catalogue_fingerprint: canonical rows of a connected dataset; dataset_id: read from the catalogue and its hashes agree; dataset_id_drifted: the input names this dataset but no catalogued version’s hash agrees (the source changed since it was catalogued, note DATA_DRIFTED). The dataset’s access terms apply either way.

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 190

class

class RecipeNote(_Model)

Fields

NameTypeDefaultDescription
codeRecipeNoteCode
severityLiteral['info', 'warn']
messagestr
cellslist[int]list()Notebook execution counts the note is about.
step_idstr | NoneNone

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 60

class

class RecipeOutput(_Model)

Fields

NameTypeDefaultDescription
path_basenamestr | NoneNone
frame_idstr
formatLiteral['csv', 'parquet']'csv'
sha256str | NoneNonesha256 hex of the file as written; null when rows were not written.
fingerprintstrCanonical-rows fingerprint of the file as written and read back.
fingerprint_basisstrRECIPE_FINGERPRINT_BASIS
rowsint
columnsdict[str, str]
rows_writtenboolTrue
index_writtenboolFalse

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 127

class

class RecipeRef(_Model)

What a catalogued dataset keeps of its recipe (Dataset.recipe). The body lives in the blob store.

Fields

NameTypeDefaultDescription
blob_uristrblob://sha256/<hex> of the recipe JSON as uploaded.
sha256strsha256 hex of the recipe JSON bytes; the only part of a recipe a Merkle leaf may hold.
recipe_idstr | NoneNone
titlestr | NoneNone
stepsintNumber of recorded steps.
captureRecipeCapture'full'
verificationRecipeVerificationRefRecipeVerificationRef()
inputs_matchedlist[RecipeInputMatch]list()
inputs_externallist[RecipeExternalInput]list()
output_matchesbooloutput.sha256 equals the uploaded file’s sha256. False: the recipe describes a different file (RECIPE_OUTPUT_MISMATCH).

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 217

class

class RecipeStep(_Model)

Fields

NameTypeDefaultDescription
step_idstr
kindLiteral['named', 'verb', 'cell_edit']
opstrMethod name, ‘loc.setitem’, ‘groupby.sum’, ‘call:pandas.concat’, a named step’s function name, or ‘unrecorded_change’.
argsdict[str, Any]dict()Tagged JSON: frames as {‘frame’: id}, series expressions as {‘expr’: …}.
codestr | NoneNone
code_sha256str | NoneNone
inputslist[str]list()Frame ids read by this step; the first is ‘self’.
outputstr
output_kindLiteral['frame', 'series']'frame'
rows_beforeint | NoneNone
rows_afterint
columns_addedlist[str]list()
columns_removedlist[str]list()
dtype_changesdict[str, str]dict()
fingerprintstrIn-memory hash of this step’s output (basis memory_hash/ump_recipe-1: values, column and index names, shape); replay compares it with the replayed object.
replayableboolTrue
cellint | NoneNoneNotebook execution count when the step ran.
notestr | NoneNone

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 96

class

class RecipeVerification(_Model)

Fields

NameTypeDefaultDescription
statusRecipeVerificationStatus'not_checked'
first_divergent_stepstr | NoneNone
checked_atdatetime | NoneNone
checked_byLiteral['self'] | NoneNone
messagestr | NoneNone

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 148

class

class RecipeVerificationRef(_Model)

The recipe’s own verification as uploaded. Self-reported: apps/data never replays a recipe.

Fields

NameTypeDefaultDescription
statusRecipeVerificationStatus'not_checked'
checked_atdatetime | NoneNone
checked_byLiteral['self'] | NoneNoneAlways ‘self’ when checked: the analyst’s machine ran the replay, not UMP.
first_divergent_stepstr | NoneNoneStep id (or ‘output’) where a replay first differed; only with not_reproduced.

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 179

class

class TransformRecipe(_Model)

<output>.recipe.json: inputs by hash, steps, notebook cells, the output’s fingerprint and the analyst’s own replay check.

Fields

NameTypeDefaultDescription
schema_versionLiteral['ump.transform_recipe/0.1']'ump.transform_recipe/0.1'
recipe_idstr
titlestr
created_atdatetime
authorstr | NoneNone
inputslist[RecipeInput]
stepslist[RecipeStep]
cellslist[RecipeCell]list()
cells_includedboolTrue
outputRecipeOutput
captureLiteral['full', 'partial']'full'
noteslist[RecipeNote]list()
environmentRecipeEnvironment
verificationRecipeVerificationRecipeVerification()

Source: packages/ump-spec/src/ump_spec/models/recipe.py, line 156

NameTypeValueDescription
CATALOGUE_FINGERPRINT_BASIS'canonical_rows'Basis of inputs[].catalogue_fingerprint: rules.canonical_rows_fingerprint over the frame’s cells as plain JSON values, the same basis a connected dataset registers its sha256 under.
RECIPE_FINGERPRINT_BASIS'canonical_rows/ump_recipe-2'Basis of inputs[].fingerprint and output.fingerprint (the client package’s round-trip rule).
RECIPE_NOTE_CODEStuple[str, ...]('RECIPE_PARTIAL', 'RECIPE_UNVERIFIED', 'RECIPE_NOT_REPRODUCED', 'RECIPE_OUTP...
RECIPE_SCHEMA_VERSION'ump.transform_recipe/0.1'
RECIPE_STEP_HASH_BASIS'memory_hash/ump_recipe-1'
RECIPE_VERIFICATION_STATUSEStuple[str, ...]('not_checked', 'reproduced', 'not_reproduced', 'not_replayable', 'inputs_mis...
RecipeCaptureLiteral['full', 'partial']
RecipeNoteCodeLiteral['RECIPE_PARTIAL', 'RECIPE_UNVERIFIED', 'RECIPE_NOT_REPRODUCED', 'RECI...
RecipeVerificationStatusLiteral['not_checked', 'reproduced', 'not_reproduced', 'not_replayable', 'inp...not_checked is untested, not failed (RECIPE_UNVERIFIED).