workflow.variables.metadata
Typed metadata for model artifacts in Michelangelo workflow tasks.
TRAINING_FRAMEWORK_CUSTOM
Training framework identifier for user-defined CustomModel subclasses.
TRAINING_FRAMEWORK_PYTORCH
Training framework identifier for plain torch.nn.Module models.
TRAINING_FRAMEWORK_LIGHTNING
Training framework identifier for pytorch_lightning.LightningModule models.
ModelMetadata Objects
@dataclass
class ModelMetadata()
Typed metadata carried by a model artifact through workflow tasks.
Captures framework, assembly state, and optional binary payloads so downstream tasks (pusher, validator, serving) can make decisions without opening the artifact itself.
Subclass to add provider-specific fields and extend to_registry_dict()
to include them:
@dataclass
class MyModelMetadata(ModelMetadata):
training_job_id: str | None = None
experiment_id: str | None = None
def to_registry_dict(self) -> dict[str, str]:
result = super().to_registry_dict()
if self.training_job_id is not None:
result["training_job_id"] = self.training_job_id
if self.experiment_id is not None:
result["experiment_id"] = self.experiment_id
return result
Attributes:
training_framework- Name of the training framework (e.g."pytorch","xgboost","huggingface").Nonewhen not recorded.model_class- Fully-qualified import path of the model class (e.g."mypackage.models.Classifier"). Used to re-instantiate the model for validation or fine-tuning.Nonewhen not recorded.assembled-Truewhen the feature-transform and model-inference stages have been fused into a single artifact. The pusher uses this to decide whether a separate transform upload is needed.deployable-Truewhen the model has been packaged into a serving-ready format (e.g. Triton config + weights). The pusher setsdeployable_artifact_urionly when this isTrue.is_incremental_training-Truewhen this model was produced by an incremental training run (BASELINE or continuation of an existing incremental chain). Used by downstream tasks to propagate chain metadata.baseline_model_identifier- Opaque string tag identifying the original baseline model at the root of an incremental training chain.Nonefor non-incremental models, and for the first run of a new incremental chain (the BASELINE run itself). Set on continuation runs to the identifier of the original baseline.transform_spec- Opaque feature-transform specification propagated from a native-transform model through assembly, used to reconstruct the transform at serve time.Nonewhen the model has no associated transform. See_transform_spec.feature_stats- Opaque feature statistics propagated from a native-transform model through assembly (e.g. normalization parameters).Nonewhen not recorded. See_feature_stats._schema- Serialised (pickled) input/output schema. This, not a liveschemafield, is what actually crosses a workflow taskboundary- a liveModelSchemaobject passed by value through the workflow orchestrator can be large enough to exceed its argument-size limits when inlined. Use theschemaproperty to read it back as a live object. Not included inrepr._sample_data- Serialised sample inference payload used for smoke-testing the deployed model, for the same reason_schemais serialised rather than carried live. Use thesample_dataproperty to read it back. Not included inrepr._transform_spec- Serialisedtransform_spec, for the same live-object-crossing-a-task-boundary reason as_schema. Set via thetransform_specproperty setter, which pickles the value for you. Not included inrepr._feature_stats- Serialisedfeature_stats, for the same reason. Set via thefeature_statsproperty setter. Not included inrepr._hyperparameters- Serialised (pickled) training hyperparameters. This, not a livehyperparametersfield, is what crosses a workflow task boundary, for the same workflow-orchestrator argument-size reason as_schema. Use thehyperparametersproperty to read or write it as a live dict. Not included inrepr.hyperparameters- Live training hyperparameters as a Python dict, lazily unpickled from_hyperparameters. Used byModelVariable.load_lightning_model()to re-instantiate the model class viamodel_class(**hyperparameters). Has asetter- assigning a dict pickles it into_hyperparametersfor you._e2e_schema- Serialised end-to-end schema produced by fusing aFeaturePackageArtifact's schema into this model's ownschemaduring assembly, for the same live-object-crossing-a-task-boundary reason as_schema. Use thee2e_schemaproperty to read it back. Not included inrepr._e2e_sample_data- Serialised end-to-end sample data produced the same way as_e2e_schema. Use thee2e_sample_dataproperty to read it back. Not included inrepr.
Warnings:
The _schema, _sample_data, _transform_spec,
_feature_stats, _hyperparameters, _e2e_schema, and
_e2e_sample_data fields are unpickled on read (schema,
sample_data, transform_spec, feature_stats,
hyperparameters, e2e_schema, e2e_sample_data
properties). Unpickling
executes arbitrary code embedded in the payload, so only construct
ModelMetadata from a trusted source (e.g. your own workflow task
output), never from unvalidated external input.
Example:
>>> meta = ModelMetadata(training_framework="xgboost", deployable=True)
>>> meta.training_framework
'xgboost'
>>> meta.deployable
True
schema
@property
def schema() -> ModelSchema | None
Typed input/output schema, lazily unpickled from _schema.
Set via _schema (e.g. _schema=io.BytesIO(pickle.dumps(schema)))
rather than as a constructor keyword — this stays a read-only view so
the only thing carried across a workflow task boundary is the
serialised payload, never a live object passed by value.
Returns:
The unpickled ModelSchema, or None if _schema is unset.
sample_data
@property
def sample_data() -> list[dict[str, Any]] | None
Sample inference inputs, lazily unpickled from _sample_data.
Set via _sample_data for the same reason schema is backed by
_schema — see that property's docstring.
Returns:
The unpickled sample data, or None if _sample_data is unset.
transform_spec
@property
def transform_spec() -> dict[str, Any] | None
Feature-transform spec, lazily unpickled from _transform_spec.
Unlike schema/sample_data, this has a setter: callers may
assign a live dict directly (meta.transform_spec = {...}) and it
is pickled into _transform_spec for you, since the value only
needs to cross a task boundary after assembly, not at construction.
Returns:
The unpickled spec, or None if _transform_spec is unset.
feature_stats
@property
def feature_stats() -> dict[str, Any] | None
Feature statistics, lazily unpickled from _feature_stats.
Has a setter for the same reason transform_spec's does — see
that property's docstring.
Returns:
The unpickled stats, or None if _feature_stats is unset.
hyperparameters
@property
def hyperparameters() -> dict[str, Any] | None
Training hyperparameters, lazily unpickled from _hyperparameters.
Has a setter for the same reason transform_spec's does — see
that property's docstring.
Returns:
The unpickled hyperparameters, or None if
_hyperparameters is unset.
e2e_schema
@property
def e2e_schema() -> ModelSchema | None
End-to-end schema, lazily unpickled from _e2e_schema.
Set when a feature package is fused into this model during assembly
(see fuse_e2e_schema); read-only for the same reason schema
is, via the same _schema-backing pattern.
Returns:
The unpickled ModelSchema, or None if _e2e_schema is unset.
e2e_sample_data
@property
def e2e_sample_data() -> list[dict[str, Any]] | None
End-to-end sample data, lazily unpickled from _e2e_sample_data.
Set when a feature package is fused into this model during assembly
(see build_e2e_sample_data); read-only, mirroring sample_data.
Returns:
The unpickled sample data, or None if _e2e_sample_data is unset.
to_registry_dict
def to_registry_dict() -> dict[str, str]
Return a flat string dict of public fields suitable for registry tags.
Omits None-valued optional fields and serialises bool fields as
"true" / "false" (lowercase) for consistent cross-registry
storage. Binary payload fields (_schema, _sample_data,
_transform_spec, _feature_stats, _hyperparameters) are excluded.
Subclasses should override this method to include their own fields:
@dataclass
class MyModelMetadata(ModelMetadata):
training_job_id: str | None = None
def to_registry_dict(self) -> dict[str, str]:
result = super().to_registry_dict()
if self.training_job_id is not None:
result["training_job_id"] = self.training_job_id
return result
Returns:
A dict[str, str] ready for ModelRegistryClient.register_model( metadata=...).
DatasetMetadata Objects
@dataclass
class DatasetMetadata()
Typed metadata carried by a DatasetVariable through workflow tasks.
Currently scoped to the one field tabular_native_transform needs to
record; extend with additional fields as more tasks need to annotate
dataset variables (mirroring how ModelMetadata grew field-by-field
per task).
Attributes:
derived_features- Names of output columns present in the dataset that were not present in its original input (i.e. produced by a transform), in sorted order. Empty when no transform was applied, or when every output column overlaps an input column name.
Example:
>>> meta = DatasetMetadata(derived_features=["scaled_amount"])
>>> meta.derived_features
['scaled_amount']
FeaturePackageMetadata Objects
@dataclass
class FeaturePackageMetadata()
Typed metadata carried by a feature-package artifact.
A feature package describes the schema and sample data produced by a
feature-computation stage (e.g. a feature store lookup or a batch feature
pipeline) that precedes a model. Assemblers fuse this into the model's
own schema/sample data to produce the end-to-end serving contract; see
fuse_e2e_schema and build_e2e_sample_data.
Attributes:
_schema- Serialised (pickled)FeatureSchema, for the same live-object-crossing-a-task-boundary reason asModelMetadata._schema. Use theschemaproperty to read it back. Not included inrepr._sample_data- Serialised sample feature payload, for the same reason_schemais serialised. Use thesample_dataproperty to read it back. Not included inrepr.
Warnings:
The _schema and _sample_data fields are unpickled on read.
Unpickling executes arbitrary code embedded in the payload, so only
construct FeaturePackageMetadata from a trusted source, never
from unvalidated external input.
schema
@property
def schema() -> FeatureSchema
Typed feature schema, lazily unpickled from _schema.
Returns:
The unpickled FeatureSchema, or an empty FeatureSchema()
if _schema is unset.
sample_data
@property
def sample_data() -> list[dict[str, Any]] | None
Sample feature inputs, lazily unpickled from _sample_data.
Returns:
The unpickled sample data, or None if _sample_data is unset.
SourceMessageType Objects
class SourceMessageType(Enum)
The type of value a MessageVariable holds.
MessageMetadata Objects
@dataclass
class MessageMetadata()
Metadata of a MessageVariable.