Artifact formats and library integrations¶
Dagster asset observation¶
Install the optional Dagster integration with:
@dagster_asset(...) is applied directly inside Dagster's @asset. It opens
the OCLP observation context for an existing @run workflow, while that
workflow's existing @computation and Artifact declarations continue to
produce the only OCLP records. On completion, the adapter adds the OCLP run
identity, record-store path, outcome, and an explicit selection of Dagster
context fields to the Dagster asset materialization metadata.
import dagster as dg
from oclp.dagster import dagster_asset
@dg.asset
@dagster_asset(
workflow=train,
publisher=publisher_for_dagster_context,
source=source_for_dagster_context,
)
def trained_model(context: dg.AssetExecutionContext) -> None:
train(...)
This is an integration boundary, not an orchestration DSL. It never derives an
OCLP Computation from an asset, creates a parent Execution for a Dagster run,
or reflects arbitrary Dagster context. The initial allow-list is run_id,
asset_key, partition_key, and retry_number; select only values that are
useful to navigate the Dagster materialization.
An OCLP Artifact is format-neutral. The Python SDK's concrete
ArtifactType declarations provide the local persistence and loading policy
for an Artifact payload. This page is the canonical inventory of integrations
shipped by the SDK—not a claim that OCLP itself requires any of these
libraries or formats.
The same concrete type is used at both sides of a Computation boundary:
from xgboost import XGBRegressor
from oclp import XGBoostModelArtifact, computation
@computation(
inputs={"model": XGBoostModelArtifact},
outputs={"candidate": XGBoostModelArtifact(name="Candidate model")},
)
def promote(model: XGBRegressor) -> XGBRegressor:
return model
The output declaration tells the SDK how to materialize the normal Python return value. The input declaration validates the Artifact's durable media type; the parameter annotation selects the adapter that loads verified bytes.
Supported representations¶
| Artifact type | Durable format / media type | Optional SDK extra | Function return | Downstream parameter | Status |
|---|---|---|---|---|---|
BytesArtifact |
caller-declared media type | — | bytes |
an application adapter | Supported |
FileArtifact |
caller-declared media type | — | pathlib.Path |
an application adapter | Supported |
JsonArtifact |
JSON / application/json |
— | JSON-compatible value | dict[...] or an application adapter |
Supported |
JsonArtifact(serialization="pandas-table") |
pandas table JSON / application/json |
pandas in application | pandas.DataFrame |
pandas.DataFrame |
Supported |
JsonLinesArtifact |
JSON Lines / application/x-ndjson |
— | pandas.DataFrame or iterable of mappings |
pandas.DataFrame, list[dict[...]], or tuple[dict[...], ...] |
Supported |
CsvArtifact |
CSV / text/csv |
pandas in application | pandas.DataFrame |
pandas.DataFrame |
Supported |
ParquetArtifact |
Parquet / application/vnd.apache.parquet |
oclp[parquet] |
pandas.DataFrame |
pandas.DataFrame |
Supported |
ArrowIpcArtifact |
Arrow IPC file / application/vnd.apache.arrow.file |
oclp[arrow] |
pyarrow.Table or pandas.DataFrame |
pyarrow.Table or pandas.DataFrame |
Supported |
NpyArtifact |
NumPy .npy / application/x-npy |
oclp[numpy] |
numpy.ndarray |
numpy.ndarray |
Supported |
NpzArtifact |
NumPy .npz / application/x-npz |
oclp[numpy] |
mapping of named arrays | dict[str, numpy.ndarray] |
Supported |
YamlArtifact |
YAML / application/yaml |
oclp[yaml] |
mapping | dict[...] |
Supported |
TomlArtifact |
TOML / application/toml |
oclp[toml] |
mapping | dict[...] |
Supported |
XmlArtifact |
UTF-8 XML / application/xml |
oclp[xml] |
XML str |
str or xml.etree.ElementTree.Element |
Supported |
CatBoostModelArtifact |
native CatBoost .cbm / application/x-catboost-model |
oclp[catboost] |
fitted CatBoost model | CatBoostRegressor, CatBoostClassifier, or CatBoostRanker |
Supported |
XGBoostModelArtifact |
native XGBoost UBJSON .ubj / application/x-xgboost-ubjson |
oclp[xgboost] |
fitted XGBoost sklearn model or Booster |
XGBRegressor, XGBClassifier, XGBRanker, or Booster |
Supported |
LightGBMModelArtifact |
native LightGBM model .txt / application/x-lightgbm-model |
oclp[lightgbm] |
fitted lightgbm.Booster |
lightgbm.Booster |
Supported |
SklearnModelArtifact |
skops .skops / application/x-skops |
oclp[sklearn] |
fitted scikit-learn BaseEstimator |
the exact annotated sklearn estimator type | Supported |
Media types beginning with application/x- are SDK conventions where a format
does not have a registered IANA media type. They make the representation
unambiguous within OCLP records without claiming an external standard.
Representation configuration belongs beside the output port¶
The concrete Artifact declaration is the single place to configure how a
returned value becomes durable bytes. The SDK validates known options instead
of accepting opaque serializer **kwargs that might vary between libraries or
silently create an invalid representation.
from oclp import JsonLinesArtifact, YamlArtifact, computation
@computation(
name="Publish predictions and configuration",
outputs={
"predictions": JsonLinesArtifact(
name="Prediction batch",
sort_keys=True,
newline="\n",
),
"config": YamlArtifact(
name="Training configuration",
indent=2,
sort_keys=True,
),
},
)
def publish() -> dict[str, object]:
return {
"predictions": [{"id": "a", "score": 0.9}],
"config": {"learning_rate": 0.1},
}
Changing a declared representation option changes the stored bytes and hence the Artifact digest. The source-bound Computation identifies the code that made that serialization decision.
JsonLinesArtifact is intentionally separate from JsonArtifact: records
with one JSON object per line are a different durable contract, not merely a
lines=True rendering option. ArrowIpcArtifact writes the Arrow IPC file
format (also known as Feather V2), with Arrow's registered file media type.
See Arrow's format documentation.
XML documents¶
XmlArtifact accepts an XML str, persists it as UTF-8 .xml bytes, and
validates it with defusedxml. DTDs and entity processing are rejected: XML
must be a safe, well-formed document. An explicit XML encoding declaration
must say UTF-8; otherwise it must be omitted. A downstream callable can ask
for the original str or a safely parsed xml.etree.ElementTree.Element.
The SDK deliberately preserves the returned XML text rather than silently canonicalizing it. Equivalent XML documents can differ physically in attribute order, whitespace, and other permitted syntax; XML canonicalization is an application-level choice, while an OCLP Artifact digest identifies the exact persisted bytes. See Canonical XML and Python's XML security guidance.
Native model formats¶
CatBoostModelArtifact materializes the fitted returned object through
CatBoost's native save_model() API as .cbm bytes. The adapter verifies the
Artifact digest before loading the payload into the downstream annotated model
class.
XGBoostModelArtifact explicitly writes .ubj, XGBoost's UBJSON model
format, rather than accepting a version-dependent default. It accepts an
XGBoost Booster or sklearn-wrapper model with save_model() and reloads it
as the exact annotated XGBoost class. XGBoost also supports JSON, but the SDK
uses UBJSON as its shipped native representation to keep artifacts compact
without losing model semantics. See XGBoost model I/O.
LightGBMModelArtifact persists the native model returned as a
lightgbm.Booster. The LightGBM sklearn wrappers expose a fitted Booster as
booster_, but do not provide a stable native wrapper-loader boundary, so the
SDK does not reconstruct wrapper internals. Use the Booster for the native
artifact contract, or SklearnModelArtifact when the portable Python wrapper
object itself is required. LightGBM documents booster_ as the underlying
fitted Booster.
SklearnModelArtifact uses the skops .skops format rather than pickle
or joblib. It works with fitted scikit-learn BaseEstimator values and
returns the same annotated estimator type to the downstream function. The
default adapter refuses unknown types in a payload. A project that intentionally
uses reviewed custom types must configure an additional
SklearnModelAdapter(trusted_types=(...)) in its OclpRun adapter registry;
the producer cannot grant that trust through the Artifact itself. This is a
Python-environment representation, not a cross-language serving format. See
skops secure persistence.
Compatibility and safety¶
The Artifact digest proves that a consumer reads the exact persisted bytes. It does not make a model automatically compatible with every runtime. A model's source framework and version remain part of its execution provenance; applications should pin the environment that loads it.
The optional model libraries retain their own system-runtime requirements. For example, XGBoost and LightGBM installations on some platforms also require an OpenMP runtime; that is a framework requirement, not an OCLP payload concern.
The SDK intentionally does not currently provide a generic pickle/joblib
Artifact type. Those formats only belong in trusted, version-compatible Python
environments; skops and ONNX have different safety and portability tradeoffs.
See scikit-learn's model persistence guidance.