finprint.schema
module finprint
The recipe file, <output>.recipe.json (schema ump.transform_recipe/0.1).
The normative model is ump_spec.models.TransformRecipe (packages/ump-spec/schemas/transform-recipe.json).
This package keeps an identical copy because analysts install it without ump_spec; the JSON Schema in
schema/transform_recipe.schema.json is generated from these models (finprint schema), one test fails
when it drifts from these models and another (tests/test_spec_alignment.py, run when ump_spec is
importable) fails when it differs from ump_spec’s.
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
(kept as a short prefix plus their hash).
Classes
Section titled “Classes”RecipeNote
Section titled “RecipeNote”class
class RecipeNote(_Model)Fields
| Name | Type | Default | Description |
|---|---|---|---|
code | NoteCodeName | ||
severity | Literal['info', 'warn'] | ||
message | str | ||
cells | list[int] | list() | Notebook execution counts the note is about. |
step_id | str | None | None |
Source: packages/finprint/src/finprint/schema.py, line 40
ReaderSpec
Section titled “ReaderSpec”class
class ReaderSpec(_Model)Fields
| Name | Type | Default | Description |
|---|---|---|---|
fn | Literal['read_csv', 'read_excel', 'read_parquet', 'read_catalogue'] | ||
kwargs | dict[str, Any] | dict() | Reader keyword arguments, tagged JSON (no path). |
replayable | bool | True |
Source: packages/finprint/src/finprint/schema.py, line 48
RecipeInput
Section titled “RecipeInput”class
class RecipeInput(_Model)Fields
| Name | Type | Default | Description |
|---|---|---|---|
input_id | str | Also the frame id steps use to refer to this input. | |
name | str | ||
source | Literal['file', 'catalogue', 'in_memory'] | ||
path_basename | str | None | None | |
sha256 | str | None | None | sha256 hex of the file bytes (stored catalogue datasets: blob hash). |
fingerprint | str | Canonical-rows fingerprint of the frame as read (see fingerprint_basis). | |
fingerprint_basis | str | FINGERPRINT_BASIS | |
dataset_id | str | None | None | |
catalogue_fingerprint | str | None | None | The 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_seen | str | None | None | fetch_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 | None | None | |
reader | ReaderSpec | None | None | |
rows | int | ||
columns | dict[str, str] | Column name to pandas dtype. |
Source: packages/finprint/src/finprint/schema.py, line 54
RecipeStep
Section titled “RecipeStep”class
class RecipeStep(_Model)Fields
| Name | Type | Default | Description |
|---|---|---|---|
step_id | str | ||
kind | Literal['named', 'verb', 'cell_edit'] | ||
op | str | Method name, ‘loc.setitem’, ‘groupby.sum’, ‘call:pandas.concat’, a named step’s function name, or ‘unrecorded_change’. | |
args | dict[str, Any] | dict() | Tagged JSON: frames as {‘frame’: id}, series expressions as {‘expr’: …}. |
code | str | None | None | |
code_sha256 | str | None | None | |
inputs | list[str] | list() | Frame ids read by this step; the first is ‘self’. |
output | str | ||
output_kind | Literal['frame', 'series'] | 'frame' | |
rows_before | int | None | None | |
rows_after | int | ||
columns_added | list[str] | list() | |
columns_removed | list[str] | list() | |
dtype_changes | dict[str, str] | dict() | |
fingerprint | str | In-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. | |
replayable | bool | True | |
cell | int | None | None | Notebook execution count when the step ran. |
note | str | None | None |
Source: packages/finprint/src/finprint/schema.py, line 76
RecipeCell
Section titled “RecipeCell”class
class RecipeCell(_Model)Fields
| Name | Type | Default | Description |
|---|---|---|---|
execution_count | int | None | None | |
order | int | ||
source | str | ||
frames_changed | list[str] | list() |
Source: packages/finprint/src/finprint/schema.py, line 100
RecipeOutput
Section titled “RecipeOutput”class
class RecipeOutput(_Model)Fields
| Name | Type | Default | Description |
|---|---|---|---|
path_basename | str | None | None | |
frame_id | str | ||
format | Literal['csv', 'parquet'] | 'csv' | |
sha256 | str | None | None | sha256 hex of the file as written; null when rows were not written. |
fingerprint | str | Canonical-rows fingerprint of the file as written and read back. | |
fingerprint_basis | str | FINGERPRINT_BASIS | |
rows | int | ||
columns | dict[str, str] | ||
rows_written | bool | True | |
index_written | bool | False |
Source: packages/finprint/src/finprint/schema.py, line 107
RecipeEnvironment
Section titled “RecipeEnvironment”class
class RecipeEnvironment(_Model)Fields
| Name | Type | Default | Description |
|---|---|---|---|
python | str | ||
pandas | str | ||
numpy | str | ||
ump_recipe | str | ||
platform | str |
Source: packages/finprint/src/finprint/schema.py, line 120
RecipeVerification
Section titled “RecipeVerification”class
class RecipeVerification(_Model)Fields
| Name | Type | Default | Description |
|---|---|---|---|
status | VerificationStatus | 'not_checked' | |
first_divergent_step | str | None | None | |
checked_at | datetime | None | None | |
checked_by | Literal['self'] | None | None | |
message | str | None | None |
Source: packages/finprint/src/finprint/schema.py, line 128
TransformRecipe
Section titled “TransformRecipe”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
| Name | Type | Default | Description |
|---|---|---|---|
schema_version | Literal['ump.transform_recipe/0.1'] | 'ump.transform_recipe/0.1' | |
recipe_id | str | ||
title | str | ||
created_at | datetime | ||
author | str | None | None | |
inputs | list[RecipeInput] | ||
steps | list[RecipeStep] | ||
cells | list[RecipeCell] | list() | |
cells_included | bool | True | |
output | RecipeOutput | ||
capture | Literal['full', 'partial'] | 'full' | |
notes | list[RecipeNote] | list() | |
environment | RecipeEnvironment | ||
verification | RecipeVerification | RecipeVerification() |
Methods and properties (1)
to_json method
def to_json(self) -> strSource: packages/finprint/src/finprint/schema.py, line 136
Functions
Section titled “Functions”json_schema
Section titled “json_schema”function
def json_schema() -> dict[str, Any]JSON Schema 2020-12 for TransformRecipe (the form the published file holds).
Source: packages/finprint/src/finprint/schema.py, line 165
json_schema_text
Section titled “json_schema_text”function
def json_schema_text() -> strSource: packages/finprint/src/finprint/schema.py, line 171
load_recipe
Section titled “load_recipe”function
def load_recipe(path: str | Path) -> TransformRecipeSource: packages/finprint/src/finprint/schema.py, line 175
write_recipe
Section titled “write_recipe”function
def write_recipe(recipe: TransformRecipe, path: str | Path) -> NoneSource: packages/finprint/src/finprint/schema.py, line 179
Constants
Section titled “Constants”| Name | Type | Value | Description |
|---|---|---|---|
SCHEMA_VERSION | 'ump.transform_recipe/0.1' | ||
SCHEMA_ID | 'https://schemas.ump.dev/v1/transform-recipe.json' | Same $id as ump_spec’s exported schema, so the two files are equal. | |
FINGERPRINT_BASIS | 'canonical_rows/ump_recipe-2' | ||
CATALOGUE_FINGERPRINT_BASIS | 'canonical_rows' | ||
STEP_HASH_BASIS | 'memory_hash/ump_recipe-1' | ||
VerificationStatus | Literal['not_checked', 'reproduced', 'not_reproduced', 'not_replayable', 'inp... | ||
CopyPolicy | Literal['allowed', 'transient_only', 'aggregates_only'] | ||
Note | RecipeNote | ||
Environment | RecipeEnvironment | ||
Verification | RecipeVerification |