ump-sdk
Service authors import ump_sdk
Every Python service in the prototype builds on ump-sdk, so they all answer health checks, report errors and identify callers the same way.
It implements the transport side of spec §19: OpenAPI services and typed errors as RFC 9457 problem details. Analysts rarely import it directly; babelfin uses its clients when it talks to a running core.
Quick path
Section titled “Quick path”- Install:
pip install -e 'packages/ump-sdk'from a checkout (it pulls in ump-spec). - Build an app with the factory and run it.
from fastapi import Dependsfrom ump_sdk import JobRunner, Principal, create_app, get_principal, mount_job_routes, run
app = create_app("models", "0.1.0", description="model registry")jobs = JobRunner("models")mount_job_routes(app, jobs)
@app.get("/v1/hello")def hello(p: Principal = Depends(get_principal)): return {"you": p.id}
if __name__ == "__main__": run(app, "models") # serves on the port registered for "models"The factory adds CORS for the web app, /healthz, /v1/meta, the UMP-Spec-Version header, problem+json error handlers and the X-UMP-Principal identity stub.
X-UMP-Principal and UMP_ON_GATE_FAIL are conveniences of the proof of concept, outside the standard. A conforming server takes the gate mode from the body member on_gate_fail or the UMP-On-Gate-Fail request header, and sends UMP-Spec-Version on every response (section 19). Callers are authenticated as section 19 requires, not by a header that names them.
Main entry points
Section titled “Main entry points”| Name | What it does |
|---|---|
create_app(name, version) | A FastAPI app with the house conventions. |
CoreClient / AsyncCoreClient | Typed clients for the core API. Any status of 400 or more raises ProblemError with .problem, .status and .code. |
AdapterClient / AsyncAdapterClient | Clients for the engine adapter contract, returning ump_spec.adapter models. |
JobRunner, mount_job_routes | An in-process background job helper that stands in for a workflow engine, with progress steps and job routes scoped to the caller. |
PORTS, base_url(name) | The port registry and the URL for each service. |
get_settings() | Shared settings from UMP_* environment variables. |
Call core
Section titled “Call core”from ump_sdk import CoreClient, ProblemError
core = CoreClient(principal="user:maya.chen")try: ... # any call on coreexcept ProblemError as err: err.status, err.code # e.g. 403 and the gate's error codeWhen a service is down, clients raise a 502 problem with code UPSTREAM_UNAVAILABLE instead of a raw connection error.
Environment variables
| Variable | Effect |
|---|---|
UMP_<NAME>_URL | Overrides one service’s base URL. Dashes in the name become underscores. |
UMP_VAR_DIR | Runtime state folder. |
UMP_DEFAULT_PRINCIPAL | Caller identity when no header is sent. |
UMP_ON_GATE_FAIL | fallback or strict gate mode. A POC convenience; the standard’s knob is the UMP-On-Gate-Fail header (section 19). |
UMP_CLIENT_REF_SALT | Salt for client references in shared rows. |
Identity and scope
get_principal reads the X-UMP-Principal header, or a ?principal= query parameter on GET requests only. caller_scope asks core’s /v1/whoami which clients the caller may see and caches the answer. require_client_scope refuses a request for any other client. This is a prototype stub, not authentication, and X-UMP-Principal is not part of the standard.