Archive experiments#
Archiving is a soft delete: the experiment stops accepting new work and stays readable. There is no unarchive. The hosted plane and the local driver share the semantics, so the local run below shows what a hosted archive does.
Archive an experiment#
Finish or abandon the study first; archiving is permanent.
Call
client.archive_experiment(exp.id). Hosted, this isDELETE /v1/experiments/{id}, answering 204.Read
client.experiment(exp.id).state.Keep reading:
experiment(),best(),suggestions(), andobservations()keep working, and so doclose_suggestion()andclose_all_suggestions()for suggestions that were still open.
from tauopt import ApiError, Client
client = Client(driver="local")
exp = client.create_experiment(
name="finished-study",
parameters=[{"name": "x", "type": "double", "bounds": (0.0, 1.0)}],
metric={"name": "y", "objective": "minimize"},
parallel_bandwidth=2,
)
for _ in range(3):
sug = client.suggest(exp.id)
client.observe(exp.id, suggestion_id=sug.id, value=(sug.assignments["x"] - 0.4) ** 2)
pending = client.suggest(exp.id) # left open on purpose
client.archive_experiment(exp.id)
print("state:", client.experiment(exp.id).state)
print("best still readable:", client.best(exp.id).count)
print("open suggestions still listed:", [s.id for s in client.suggestions(exp.id, state="open")])
print("observations still listed:", len(client.observations(exp.id)))
client.close_suggestion(exp.id, pending.id) # dismissals keep working
print("closed:", [s.id for s in client.suggestions(exp.id, state="closed")])
for label, call in [
("suggest", lambda: client.suggest(exp.id)),
("observe", lambda: client.observe(exp.id, assignments={"x": 0.5}, value=0.01)),
("update", lambda: client.update_experiment(exp.id, name="renamed")),
("archive again", lambda: client.archive_experiment(exp.id)),
]:
try:
call()
except ApiError as e:
print(f"{label}: {e}")
state: deleted
best still readable: 1
open suggestions still listed: ['local-1-s4']
observations still listed: 3
closed: ['local-1-s1', 'local-1-s2', 'local-1-s3', 'local-1-s4']
suggest: [404] not_found: no experiment 'local-1'
observe: [404] not_found: no experiment 'local-1'
update: [404] not_found: no experiment 'local-1'
archive again: [404] not_found: no experiment 'local-1'
In the output above, state reads deleted, every read still answers, and suggest, observe, and update_experiment refuse with a 404 not_found, as does the second archive. Local ids look like local-1; hosted ids differ, and the suggestion values printed here depend on the machine and dependency set.
Free a hosted active-experiment slot#
The hosted beta caps active experiments at 25 by default. Past the cap, create_experiment answers a 429 experiment_quota_exceeded that carries no Retry-After: waiting does not help, archiving does. The other 429 types (bandwidth_full, quota_exceeded, quota_unverifiable, the rate limits and the admission bounds) are listed in the errors reference and handled in Run against the hosted service. The quotas never throttle reads or observations; the beta lane’s per-instance pre-authentication rate limit (150 requests per second, burst 300) applies to every /v1 request on that lane, reads included, and answers rate_limited with Retry-After 1.
One transport subtlety: the hosted DELETE is retried on 429 and on 500, 502, 503, and 504, so a success whose response was lost can surface the retry’s 404 even though the archive landed. Treat not_found from archive_experiment as already archived; the cap slot is free either way.
Keep a finished study auditable#
Because an archived experiment stays readable, best(exp.id) and observations(exp.id) answer long after it stopped accepting work, and suggestions(exp.id, state="open") shows what was in flight when it was archived. On the local driver that window closes with the process: ids and state do not survive a restart, so write down what you need before exiting (see Replay a suggestion).