Python SDK
The Python client in the rehearsal-kit package. Every resource and method, with its arguments and the API operation it calls.
The rehearsal-kit package is a Python client as well as a command. It needs Python 3.11 or later.
pip install rehearsal-kitfrom rehearsal.sdk import Rehearsal
rh = Rehearsal()
run = rh.evaluations.create("<wv_id>", ["<profile_id>"], splits=["dev"], repeats=2)
for event in rh.runs.events(run["run_id"]):
print(event["type"], event["summary"])
print(rh.runs.get(run["run_id"])["summary"])Every method returns the JSON of the API's answer, as a dict or a list. The client adds no types of its own,
so a field that the API adds is there at once.
The client
Rehearsal(api_key=None, base_url=None, timeout=60)| Argument | Meaning |
|---|---|
api_key | The key. Without it: the environment variable REHEARSAL_API_KEY, then the sign-in that rehearsal login saved |
base_url | The server. Without it: REHEARSAL_URL, then the saved sign-in, then https://rehearsalkit.xyz |
timeout | Seconds to wait for one request |
With no key anywhere, the constructor raises ValueError.
Errors
A request that the server refuses raises RehearsalError. It has two fields: status, the HTTP status, and
detail, the server's message. Errors lists them.
from rehearsal.sdk.client import RehearsalError
try:
rh.evaluations.create("<wv_id>", ["<profile_id>"])
except RehearsalError as error:
if error.status == 402: # the plan does not cover it: do not retry
print(error.detail)
else:
raiseAny operation
Three methods reach every operation of the REST API, for the ones below that have no method of their own.
| Method | Does |
|---|---|
rh.get(path, params=None) | A GET. Returns the JSON |
rh.post(path, body) | A POST with a JSON body. Returns the JSON |
rh.stream(path, cursor=0) | Reads a stream of events, and reconnects from the last event after a lost connection |
usage = rh.get("/v1/usage")
job = rh.post("/v1/improvements", {"profile_id": "<profile_id>", "run_id": "<run_id>"})rh.applications
rh.applications.create
rh.applications.create(name, source, images=None, policies='')Adds an application. source is {"kind": "git", "url": ..., "commit": ...}, and images maps each service to a pinned image.
Calls POST /v1/applications.
rh.applications.import_catalog
rh.applications.import_catalog()Adds the eight sample applications. Returns them as a list.
Calls POST /v1/applications/import-catalog.
rh.applications.list
rh.applications.list()The applications of the project.
Calls GET /v1/applications.
rh.applications.get
rh.applications.get(app_id)One application.
Calls GET /v1/applications/<app_id>.
rh.applications.upload_source
rh.applications.upload_source(app_id, archive)Uploads a .tar.gz of the source, for an application added with the source kind upload.
Calls POST /v1/applications/<app_id>/source.
rh.worlds
rh.worlds.build
rh.worlds.build(application_id, **options)Starts a build. It spends model budget. Options are the fields of the request body, for example scenario_target=8 and budget_usd=6. Returns job_id and world_version_id.
Calls POST /v1/world-builds.
rh.worlds.list
rh.worlds.list()The worlds, each with its versions.
Calls GET /v1/worlds.
rh.worlds.version
rh.worlds.version(wv_id)One world version.
Calls GET /v1/world-versions/<wv_id>.
rh.worlds.scenarios
rh.worlds.scenarios(wv_id)The jobs of a world version.
Calls GET /v1/world-versions/<wv_id>/scenarios.
rh.worlds.validate
rh.worlds.validate(wv_id)Re-checks a published world. It spends model budget. Returns a job.
Calls POST /v1/world-versions/<wv_id>/validate.
rh.worlds.bundle
rh.worlds.bundle(wv_id, include_images=False)Exports a world version as a bundle file. Returns a job.
Calls POST /v1/world-versions/<wv_id>/bundle.
rh.jobs
rh.jobs.get
rh.jobs.get(job_id)One server job: status, spent_usd, completed_phases, result, error.
Calls GET /v1/jobs/<job_id>.
rh.jobs.command
rh.jobs.command(job_id, command)pause, resume, stop or retry.
Calls POST /v1/jobs/<job_id>/commands.
rh.jobs.events
rh.jobs.events(job_id, cursor=0)The job's events, one at a time, until the job ends. It reconnects after a lost connection.
Calls GET /v1/jobs/<job_id>/events.
rh.jobs.wait
rh.jobs.wait(job_id, timeout_s=21600, poll_s=3)Asks every few seconds until the job has ended, and returns it. Raises TimeoutError after timeout_s.
rh.profiles
rh.profiles.create
rh.profiles.create(name, system_prompt='', **fields)Creates an agent profile. More fields go as keywords, for example model=... or driver="external".
Calls POST /v1/agent-profiles.
rh.profiles.list
rh.profiles.list()The agent profiles, every version.
Calls GET /v1/agent-profiles.
rh.evaluations
rh.evaluations.create
rh.evaluations.create(world_version_id, profile_ids, splits=None, repeats=None, **fields)Starts a run. It spends model budget. Returns run_id and episodes.
Without splits or repeats, the server runs every job twice with the default stress layer on.
Calls POST /v1/evaluations.
rh.evaluations.compare
rh.evaluations.compare(run_a, run_b=None)Compares the agents in one run, or two runs on the same world version.
Calls GET /v1/compare.
rh.runs
rh.runs.get
rh.runs.get(run_id)One run, with its status and summary.
Calls GET /v1/runs/<run_id>.
rh.runs.episodes
rh.runs.episodes(run_id)The episodes of a run.
Calls GET /v1/runs/<run_id>/episodes.
rh.runs.episode
rh.runs.episode(ep_id)One episode in full.
Calls GET /v1/episodes/<ep_id>.
rh.runs.events
rh.runs.events(run_id, cursor=0)The run's events, one at a time, until the run ends.
Calls GET /v1/runs/<run_id>/events.
rh.runs.intervene
rh.runs.intervene(ep_id, **body)Changes a running episode by hand. The keywords are the fields of the request body, for example kind="customer_message", text=....
Calls POST /v1/episodes/<ep_id>/interventions.
rh.runs.command
rh.runs.command(run_id, command)pause, resume or stop, for every part of the run.
Calls POST /v1/runs/<run_id>/commands.
rh.external
Drive an episode whose profile uses driver="external".
rh.external.observation
rh.external.observation(ep_id)The turn that waits for your agent in an episode, if one does.
Calls GET /v1/episodes/<ep_id>/observation.
rh.external.act
rh.external.act(ep_id, actor, tool, args, idempotency_key, wait_s=120)Sends one action and waits for its result, which it returns. Raises TimeoutError after wait_s; ask again with the same key.
Calls POST /v1/episodes/<ep_id>/actions, then GET /v1/episodes/<ep_id>/actions/<idempotency_key>.
The saved sign-in
rehearsal login writes the server and the key to one file, which only your user can read. The client reads it
when the environment has no key.
| Function | Does |
|---|---|
rehearsal.sdk.client.config_path() | Where the file is: ~/.config/rehearsal/config.json, or the path in REHEARSAL_CONFIG |
rehearsal.sdk.client.saved_login() | The saved url and api_key, or an empty dict |
Was this page helpful?