Preparation
Every upload is prepared after it lands. The prepare run sorts the takes into
tasks (task discovery) and gives each task a Task: a published one it matched,
or a draft. It also splits takes into pieces and reads the task names the
dataset’s own metadata gives. Everything it does is a proposal or a flag:
nothing is removed and no Task is published. client.preparation reads and
changes what the dataset page’s Tasks tab shows.
Every method takes a dataset id, its full name
(accounts/{account}/datasets/{dataset}) or the preparation’s name
(.../preparation). A merged dataset or a mixture has no run of its own: its
uploads are prepared one by one, so get answers state NONE. Nothing here
starts a run. client.preparation is in qualia-sdk 0.8.0rc12 and later; on
0.8.0rc11 it raises AttributeError.
Read what preparation found
Section titled “Read what preparation found”from qualia import Qualia
client = Qualia()
prep = client.preparation.get(dataset_id)print(prep.state, prep.run_id, prep.error)for warning in prep.warnings: print("warning:", warning)
found = prep.discovery # None on runs from before discoveryfor task in found.tasks if found else []: # task_id: the matched Task or the draft ("" when no draft was made); # linked_tasks, below, says which print(task.name, task.episode_count, task.health_flag, task.task_id) print(" references:", task.reference_episode_ids)
names = prep.task_strings # the dataset's own task namesfor c in names.candidates if names else []: print(c.key, c.text, c.episode_count, c.blocked_reason, c.confirmation)state is NONE, QUEUED, RUNNING, SUCCEEDED, FAILED or SKIPPED.
discovery.status is RUNNING, DONE, FAILED or FALLBACK (one task for
the whole dataset). A run discovery did not split has its one Task in
task_match instead.
A found task with a task_id is a Task you can read, edit and publish with
client.tasks. One without a Task can become one:
task = client.tasks.create( found.tasks[0].name[:32], references=[ {"role": "SUCCESS", "episode": f"{dataset_name}/episodes/{episode}"} for episode in found.tasks[0].reference_episode_ids[:3] ],)client.datasets.update(dataset_name, linked_task=task.name)Tell an existing Task from a new draft
Section titled “Tell an existing Task from a new draft”Preparation links each found task’s episodes to a Task: one that already
existed in the account, when it matches, else a draft it writes. The
preparation names the Task (task_id) without saying which it is. Only the one
Task of a run that discovery did not split carries task_match.matched.
linked_tasks reads each named Task’s published revisions once and tells them
apart where a publication predates queueing or the server explicitly matched
a published revision. Otherwise a published Task’s origin is UNKNOWN:
prep = client.preparation.get(dataset_id)for linked in client.preparation.linked_tasks(dataset_id, preparation=prep): print(linked.display_name, linked.origin, linked.revision, linked.publish_time) if linked.origin == "EXISTING": print(" episodes linked to it now:", linked.linked_episode_count) print(" revisions checks use:", linked.linked_revisions) print(" their task labels:", linked.labels)origin | The Task |
|---|---|
EXISTING | Had a published revision before the prepare run was queued, or the server explicitly matched a published revision. Checks use the stored link revisions |
NEW_DRAFT | Has no published revision: a draft a prepare run wrote for this upload (this run, or an earlier run of the upload whose draft was kept; the two read the same) |
MISSING | Cannot be read any more: deleted, or out of the key’s reach |
UNKNOWN | The available data cannot establish the origin: no known publication predates queueing, or timestamps are missing |
The API has no stable completion timestamp. update_time is the last change
and can advance after success when calibration finishes. It cannot distinguish
a draft published after preparation from a Task published during preparation.
DRAFT_PUBLISHED and PUBLISHED_DURING_PREPARATION remain accepted origin values
for compatibility, but are no longer inferred from that mutable timestamp.
revision is the Task’s newest published revision (0 for none) and
publish_time when that was published; episode_count is how many takes the
run sorted into the task. For an EXISTING Task, linked_tasks reads every
page of its current episode links: linked_episode_count is how many are linked to
it now (they may have been linked elsewhere since the run), and labels the
task labels they carry with their counts, including the empty label.
linked_revisions gives (revision, episode_count) pairs from the stored
links, including inherited links; 0 means a draft link. Checks use those
revisions even when revision names a newer publication. To judge those
episodes against a Task of your own while keeping every label, including an
empty one, use link_task:
cursor = Nonewhile True: page = client.episodes.list( dataset_id, filter=f'linked_task = "{linked.task}"', cursor=cursor ) for episode in page.items: client.episodes.link_task(episode.name, my_task.name) if not page.page_info.has_next: break cursor = page.page_info.end_cursorlinked_tasks is in qualia-sdk 0.8.0rc14 and later; on 0.8.0rc13 it raises
AttributeError.
Wait for preparation to end
Section titled “Wait for preparation to end”Preparation starts by itself after an upload and takes minutes. Automatic checks depend on policy and upload eligibility. Free quality checks default on; paid video (VLM) checks default off and require opt-in. An eligible paid check may run after preparation if the current policy still enables it and admission succeeds.
wait covers preparation only. It reads the preparation every interval
seconds until it has ended, and returns that reading:
dataset_id = client.data.upload("./takes", "box-pick")["dataset_id"]
prep = client.preparation.wait( dataset_id, timeout=1800, # seconds; the default is 3600 on_progress=lambda p: print(p.state, p.discovery.status if p.discovery else ""),)if prep.state == "FAILED": raise SystemExit(prep.error)for warning in prep.warnings: # for example, task discovery fell back print("warning:", warning)What get reads | What wait does |
|---|---|
NONE: no prepare run | Reads again for up to 30 seconds, then returns it. An upload’s run is queued as the upload settles; a merged dataset, a mixture and a deployment that does not prepare uploads never get one |
QUEUED or RUNNING | Reads again |
QUEUED or RUNNING, discovery.status already FAILED or FALLBACK | Reads again: the run goes on without task discovery. on_progress gets this reading at once, and a timeout’s message carries discovery.reason |
SUCCEEDED | Returns it. With discovery.status FAILED or FALLBACK it ended with a fallback: warnings and discovery.reason say why, so check the tasks before publishing one |
FAILED | Returns it, never raises: error says why |
SKIPPED | Returns it: there was nothing to prepare |
An ended state, discovery.status RUNNING | Reads again: task discovery is running again, after confirm_task_strings |
on_progress is called with each reading whose state, discovery.status or
discovery.reason differs from the one before, the first reading included.
After timeout seconds wait raises TimeoutError, whose message says what
the last reading showed: the state, task discovery’s status and reason, the
run and when it last changed. Timing out stops nothing: the run goes on, and
get or another wait reads it later. A failed read that is transient (a
5xx, a timeout) is retried, as in checks.wait.
wait is in qualia-sdk 0.8.0rc14 and later; on 0.8.0rc13 it raises AttributeError.
Confirm the dataset’s task names
Section titled “Confirm the dataset’s task names”When task_strings.confirmable is true, a person decides which of the
dataset’s own task names to use as tasks. The set you send replaces the
decisions on the run’s names: a name not listed is cleared, and [] clears
them all. Send one choice per usable name, as the Tasks tab does: the ones to
use confirmed=True with a Task name of at most 32 characters, the rest
confirmed=False.
prep = client.preparation.get(dataset_id)usable = [ c for c in prep.task_strings.candidates if not c.blocked and not c.looks_like_code]client.preparation.confirm_task_strings( dataset_id, prep.run_id, [{"key": c.key, "display_name": "Fold the towel", "confirmed": True} for c in usable],)Confirmed names start task discovery again, which drafts a Task for each.
Read the preparation again to see them, or wait for the re-run to end.
| Refusal | Why |
|---|---|
409 ABORTED | A newer run replaced the names you read: read again and decide again |
400 FAILED_PRECONDITION | A blocked name (outcome words, a code, already a task label), or no names |
400 INVALID_ARGUMENT | A key the run does not have, a key twice, or a name over 32 characters |
403 PERMISSION_DENIED | A workspace’s service key: a person decides on task names |
A personal API key decides as the person who made it, and the decision records the key.
The CLI has the same: qualia dataset preparation (--wait waits; its table
tells each Task apart) and qualia dataset confirm-task-names.