OCLP Core is format-neutral. The Python SDK's concrete ArtifactType
declarations specify how a normal Python return value becomes durable bytes and
how a downstream typed parameter reloads those verified bytes. They work in an
ordinary observe_run(...) context and do not require a scheduler integration.
Use a concrete acquisition decorator when a function obtains or creates one durable value without being an OCLP Computation:
from oclp import json_artifact
@json_artifact(name="Customer orders")
def load_orders() -> dict[str, object]:
return {"rows": 42}Use the same concrete type on a Computation output and input to declare its durable representation at both sides of a data 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 modelThe output declaration selects persistence. The input declaration validates the durable media type, while the Python annotation selects the adapter that loads verified bytes.
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.
The concrete 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. JsonLinesArtifact is deliberately separate from
JsonArtifact: records with one JSON object per line are a different durable
contract, not merely a rendering option. ArrowIpcArtifact writes Arrow IPC
(Feather V2) with Arrow's registered file media type. See Arrow's format
documentation.
XmlArtifact accepts XML text, persists UTF-8 .xml bytes, and validates it
with defusedxml. DTDs and entity processing are rejected. An explicit XML
encoding declaration must say UTF-8; otherwise it must be omitted. A consumer
can request the original str or a safely parsed
xml.etree.ElementTree.Element.
The SDK preserves returned XML text rather than silently canonicalizing it. Equivalent documents can differ physically in attribute order or whitespace; canonicalization is an application choice, while the Artifact digest identifies the exact persisted bytes. See Canonical XML and Python's XML security guidance.
CatBoostModelArtifact persists a fitted model through CatBoost's native
save_model() API as .cbm bytes. XGBoostModelArtifact explicitly writes
UBJSON (.ubj) and reloads the exact annotated XGBoost class. LightGBMModelArtifact
persists a lightgbm.Booster; use SklearnModelArtifact when the sklearn
wrapper itself is the intended Python contract.
SklearnModelArtifact uses skops rather than pickle or joblib. Its
default adapter refuses unknown payload types. A project that intentionally
uses reviewed custom types must configure
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.
The Artifact digest proves that a consumer reads the exact persisted bytes; it does not make a model compatible with every runtime. Pin the environment that loads a framework-native model.
The SDK intentionally does not provide a generic pickle/joblib Artifact type.
Those formats belong only in trusted, version-compatible Python environments;
skops and ONNX have different safety and portability tradeoffs. See
scikit-learn's model persistence guidance.
