Python SDK
Install, authenticate, track runs, register models, and call the prompt registry from Python.
The geneflow Python package is the official client. It's a drop-in for mlflow at the surface level (same function shapes), and exposes additional GeneFlow-native modules.
pip install geneflow
# or from this repo:
pip install -e packages/geneflow-python
Setup
import geneflow
geneflow.set_tracking_uri("https://api.genedata.io")
geneflow.set_tenant("ACME")
Or via env vars (auto-picked up):
export GENEFLOW_TRACKING_URI=https://api.genedata.io
export GENEDATA_PAT=$(genedata auth token) # or MLFLOW_TRACKING_TOKEN
export GENEFLOW_TENANT_ID=ACME
Tracking
with geneflow.start_run(experiment_name="fraud_v3", run_name="run-7") as run:
geneflow.log_param("max_depth", 7)
geneflow.log_params({"lr": 0.01, "subsample": 0.8})
for step in range(1, 6):
geneflow.log_metric("auc", 0.7 + step * 0.04, step=step)
geneflow.log_metric("cost_usd", 2.34) # GeneFlow tracks $ per run
geneflow.set_tag("env", "training")
Retrieve later:
from geneflow.tracking import get_run_cost, get_metric_history
history = get_metric_history(run.run_id, "auc")
cost = get_run_cost(run.run_id)
print(cost) # {'cost_usd': 2.34, 'tokens_used': 0, 'duration_ms': 12831}
Artifacts
from geneflow import artifacts
artifacts.upload(run_id, "/tmp/model.pkl", dst_path="model/model.pkl")
files = artifacts.list_artifacts(run_id)
local = artifacts.download(run_id, "model/model.pkl", dst_path="/tmp/dl.pkl")
Model registry
from geneflow import models
models.register("fraud-detector", description="XGBoost fraud model")
v1 = models.create_version(
"fraud-detector",
source=f"runs:/{run.run_id}/model",
run_id=run.run_id,
)
models.transition("fraud-detector", v1["model_version"]["version"], to_stage="Staging")
# Compare two versions: $ + metric deltas
diff = models.compare("fraud-detector", 1, 2)
Model serving (geneflow.serving)
from geneflow import serving
ep = serving.create_endpoint(
name="fraud-prod",
model_name="fraud-detector",
model_version=3,
instance_type="cpu-large",
min_replicas=2,
max_replicas=10,
drift_check_enabled=True,
)
# Live metrics
m = serving.get_metrics(ep["id"], window_minutes=60)
print(f"QPS={m['qps']:.2f} p95={m['p95LatencyMs']}ms err={m['errorRatePct']:.2f}%")
# Rolling update to v4
serving.update_endpoint(ep["id"], model_version=4, reason="precision win")
# Drift baseline (run once per registered version)
serving.save_drift_baselines(
model_name="fraud-detector",
model_version=3,
features=[{
"feature_name": "transaction_amount",
"feature_type": "numeric",
"histogram": {"buckets": [12, 34, 88, 150, 90, 40, 21, 8, 3, 1], "edges": [0,50,100,150,200,250,300,400,600,1000,5000]},
"mean": 142.0, "stddev": 87.2, "sample_size": 100_000,
}],
)
# Run drift check
serving.check_drift(ep["id"], window_minutes=60)
# Tear down
serving.delete_endpoint(ep["id"])
Prompts (geneflow.prompts)
from geneflow import prompts
p = prompts.register(
name="customer_support",
content="You are a {{tone}} support agent. {{question}}",
)
p2 = prompts.register("customer_support", content="...") # bumps to v2
prompts.transition("customer_support", 1, to_stage="Staging", reason="initial deploy")
# Semantic search across the registry
hits = prompts.search_similar("polite responses to angry users", k=3)
# Eval
es = prompts.create_eval_set("support-v1", examples=[...])
prompts.run_eval(es["id"], prompt_version_id=p.id, judge_method="llm_as_judge")
Lineage (geneflow.lineage)
from geneflow import lineage
lineage.upstream(run.run_id, kind="feature_group", id="user_features_v2")
lineage.upstream(run.run_id, kind="dataset", id="s3://bucket/train/2026-05.parquet")
# Downstream: what models came from this feature group?
ds = lineage.get_downstream(kind="feature_group", id="user_features_v2")
Projects (geneflow.projects)
from geneflow import projects
projects.run(
uri="git@github.com:org/repo.git",
entry_point="train",
parameters={"alpha": 0.1},
backend="kubernetes", # or "local" / "docker"
experiment_name="fraud_v3",
)
MLflow import (geneflow.import_mlflow)
from geneflow.import_mlflow import import_from
job = import_from(
source_uri="https://mlflow.old-company.com",
experiment_prefix="mlflow:",
dry_run=True,
)
print(job["counts"])
Or use the CLI: gfctl import-mlflow ....
Common gotchas
MLFLOW_TRACKING_URIworks too — we honor that env var so existing scripts run unchanged.X-Tenant-Idprecedence —set_tenant()wins, else env, else JWT claim.- PAT scoping — your token must have
geneflow:writefor tracking andgeneflow:servefor serving operations. - Artifact uploads — for files >100 MiB, use
artifacts.sign_upload()+ your own multipart S3 client instead ofupload().