Skip to content

Latest commit

 

History

History
119 lines (92 loc) · 3.92 KB

File metadata and controls

119 lines (92 loc) · 3.92 KB

Python Client

opp_ci/client.py provides OppCiClient, a thin wrapper around the REST API for programmatic submission and querying.

Setup

from opp_ci.client import OppCiClient

ci = OppCiClient(url="https://ci.omnetpp.org/api", token="<submitter-token>")

Note the /api suffix on the URL — OppCiClient does not prepend it. The --remote CLI mode, by contrast, takes the bare coordinator URL (https://ci.omnetpp.org) in OPP_CI_COORDINATOR_URL and appends /api on your behalf.

Token roles are described in rest_api.md. Use a submitter token for run submission and a readonly token for read-only scripts.

Submitting runs

# Single run
run = ci.submit_run(project="inet", kind="smoke", git_ref="topic/my-feature")
print(run)  # {"id": 42, "lifecycle": "queued"}

# Fully-specified run on a podman/host-toolchain worker
ci.submit_run(
    project="inet-4.5", kind="fingerprint",
    mode="release", git_ref="master",
    os="Ubuntu", os_version="26.04", arch="amd64",
    compiler="clang", compiler_version="22",
    isolation="podman", toolchain="none",
    force=True,
)

# All jobs in a named matrix — returns the matrix_run_id and the list
# of run_ids spawned under it.
ci.submit_matrix(matrix_name="inet-full")

The kind parameter is what used to be called test before the phase-1 schema cutover. It picks the opp_repl entry point via COMMAND_MAP — see test_matrix_dimensions.md → Axis: kind for the canonical list.

Querying

ci.get_run(42)
ci.list_runs(project="inet", kind="fingerprint", status="FAIL")
ci.list_workers()

list_runs(status=…) is the convenience union filter: it accepts either a TestRunLifecycle value ("queued" / "running" / "finished" / "cancelled" / "timed_out") or a TestResultCode ("PASS" / "FAIL" / "ERROR" / "SKIPPED"). For strict single-column filtering, pass lifecycle=… or result_code=… instead — these and any other GET /runs query param are forwarded as-is (the method takes **filters). A bad value returns HTTP 400.

Admin operations (admin token required)

ci.register_worker(name="builder-1", tags=["linux", "amd64"], concurrency=4)
ci.create_token(name="github-bot", role="submitter")

ci.add_project("mm1k", github="levy/mm1k", deps=["omnetpp"])
ci.add_version("mm1k", "v1.0", git_ref="main")
ci.sync_catalog()
ci.create_user("alice", "secret", role="admin")
ci.update_user("alice", enabled=False)
ci.revoke_token(7)
ci.delete_run(42)
ci.delete_runs(project="mm1k", status="FAIL", before="2025-01-01", confirm=True)
ci.create_rule("inet", "tag", "*", matrix_name="inet-default")

Every opp_ci --remote <command> is one-to-one with an OppCiClient method, so the client covers the full coordinator surface: projects, versions, matrices, runs, workers, tokens, users, and GitHub rules. See Remote CLI Control for the command↔method mapping and role requirements.

Errors

Every method raises OppCiClientError on failure, with a tidy .detail (the server's detail: field on a 4xx/5xx, or the transport error message) and a .status_code (None for connection errors / timeouts):

from opp_ci.client import OppCiClient, OppCiClientError

try:
    ci.list_users()
except OppCiClientError as e:
    print(e.detail, e.status_code)   # "Requires role 'admin', got 'readonly'" 403

CLI equivalent

The CLI accepts --remote (or OPP_CI_REMOTE=1) to route through the API instead of running locally:

export OPP_CI_COORDINATOR_URL=https://ci.omnetpp.org   # no /api suffix
export OPP_CI_API_TOKEN=<submitter-token>

opp_ci --remote run --project inet-4.5 --kind smoke,fingerprint --ref master
opp_ci --remote list-runs --project inet --status FAIL

Useful for one-off submissions, cron jobs, or scripting around the CI without writing Python. Full walkthrough: Remote CLI Control.