Job Submission¶
The Core SDK provides a high-level submit_job() method that handles the entire job lifecycle in a single call: upload, prepare, submit, and wait for completion.
JobSubmissionConfig¶
JobSubmissionConfig defines all parameters for a job submission:
from openquantum_sdk.clients import JobSubmissionConfig
config = JobSubmissionConfig(
backend_class_id="ionq:forte-1",
name="My Quantum Job",
job_subcategory_id="oth:oth",
shots=1024,
)
Required Fields¶
| Field | Type | Description |
|---|---|---|
backend_class_id |
str |
Target backend (UUID or short code, e.g., "ionq:forte-1") |
name |
str |
Display name for the job |
job_subcategory_id |
str |
Job subcategory (UUID or short code, e.g., "oth:oth") |
shots |
int |
Number of measurement shots |
Optional Fields¶
| Field | Type | Default | Description |
|---|---|---|---|
organization_id |
str |
None |
Organization UUID. Auto-discovered if not provided. |
configuration_data |
dict |
None |
Backend-specific configuration data. |
execution_plan |
str |
"auto" |
"auto", or a specific ExecutionPlanType enum value. |
queue_priority |
str |
"auto" |
"auto", or a specific QueuePriorityType enum value. |
auto_approve_quote |
bool |
True |
Automatically approve the pricing quote. |
verbose |
bool |
False |
Print progress messages during submission. |
job_timeout_seconds |
int |
86400 |
Maximum time to wait for job completion (1 day). |
Execution Plan and Queue Priority¶
When set to "auto" (the default), the SDK selects the cheapest available execution plan and the lowest-cost queue priority. You can also specify explicit values:
from openquantum_sdk.enums import ExecutionPlanType, QueuePriorityType
config = JobSubmissionConfig(
backend_class_id="ionq:forte-1",
name="Priority Job",
job_subcategory_id="oth:oth",
shots=1024,
execution_plan=ExecutionPlanType.PUBLIC,
queue_priority=QueuePriorityType.PRIORITY,
)
Submitting a Job¶
Use submit_job() with either a file path or raw bytes:
From a File¶
From a String¶
qasm = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
measure q[0] -> c[0];
measure q[1] -> c[1];
"""
job = scheduler.submit_job(config, file_content=qasm.encode("utf-8"))
Warning
file_content must be bytes, not str. Encode your string with .encode("utf-8").
Downloading Results¶
After a job completes, download the output:
The download_job_output() method fetches the result from the presigned URL in the job's output_data_url field and parses it as JSON.
Note
download_job_output() takes a JobRead object (returned by submit_job()), not a job ID string.
Error Handling¶
The SDK raises specific exceptions for API errors:
from openquantum_sdk.models import APIError
try:
job = scheduler.submit_job(config, file_path="circuit.qasm")
except APIError as e:
print(f"Status: {e.error_response.status_code}")
print(f"Message: {e.error_response.message}")
print(f"Request ID: {e.error_response.error_code}")
except TimeoutError as e:
print(f"Job timed out: {e}")
except RuntimeError as e:
print(f"Submission error: {e}")
Common error scenarios:
| HTTP Status | Meaning |
|---|---|
| 401 | Invalid or expired credentials |
| 402 | Insufficient credits |
| 409 | Active job limit reached (max 10 per organization) |
Verbose Mode¶
Enable verbose output to see progress during submission:
config = JobSubmissionConfig(
backend_class_id="ionq:forte-1",
name="Verbose Job",
job_subcategory_id="oth:oth",
shots=1024,
verbose=True,
)
job = scheduler.submit_job(config, file_path="circuit.qasm")
Output:
Step 1/5: Uploading job input...
Step 2/5: Preparing job and fetching quote...
> Preparation status: Completed
> Preparation complete.
Step 3/5: Processing quote...
> Auto-selected plan: Public Plan (2 credits)
> Auto-selected priority: Standard Queue (+0)
Step 3/5: Quote approved automatically (auto_approve_quote=True)
Step 4/5: Submitting job (Public Plan + Standard Queue)...
Step 5/5: Job 'abc123...' created. Waiting for completion (timeout: 86400s)...
> Job status: Completed
> Job finished with status: Completed
Job Categories¶
Every job requires a job_subcategory_id (e.g., "oth:oth"). The high-level submit_job() accepts short codes and resolves them automatically, but for low-level submission you may need to discover the valid category and subcategory UUIDs.
Listing Categories¶
categories = scheduler.get_job_categories()
for cat in categories.categories:
print(f"{cat.id}: {cat.name} ({cat.short_code})")
Listing Subcategories¶
subcategories = scheduler.get_job_subcategories(category_id="<category-uuid>")
for sub in subcategories.categories:
print(f"{sub.id}: {sub.name} ({sub.short_code})")
Both methods support pagination with limit and cursor parameters.
Polling Utility¶
The SDK provides a generic poll_for_status utility for polling any status endpoint. It is used internally by submit_job() to wait for job preparation and completion, but you can also use it directly for low-level workflows.
from openquantum_sdk import poll_for_status
result = poll_for_status(
get_status_fn=my_status_checker,
resource_id="resource-uuid",
interval=5, # seconds between polls (default: 5)
timeout=300, # max seconds before TimeoutError (default: 300)
)
| Parameter | Type | Default | Description |
|---|---|---|---|
get_status_fn |
Callable[[str], tuple[bool, Any]] |
-- | Takes a resource ID, returns (is_done, result) |
resource_id |
str |
-- | ID passed to get_status_fn on each call |
interval |
int |
5 |
Seconds between polling attempts |
timeout |
int |
300 |
Maximum seconds before TimeoutError is raised |
Example with job status polling:
def check_job(job_id):
job = scheduler.get_job(job_id)
return job.status in ("Completed", "Failed", "Cancelled"), job
job = poll_for_status(check_job, "your-job-uuid", interval=10, timeout=600)
print(f"Final status: {job.status}")
Low-Level Submission¶
For finer control, you can use the individual methods instead of submit_job():
from openquantum_sdk.models import JobPreparationCreate, JobCreate
# Step 1: Upload
upload_id = scheduler.upload_job_input(file_path="circuit.qasm")
# Step 2: Prepare
prep = JobPreparationCreate(
organization_id="your-org-uuid",
backend_class_id="ionq:forte-1",
name="Manual Job",
upload_endpoint_id=upload_id,
job_subcategory_id="oth:oth",
shots=1024,
)
prep_resp = scheduler.prepare_job(prep)
# Step 3: Poll preparation
result = scheduler.get_preparation_result(prep_resp.id)
# Step 4: Submit
job_create = JobCreate(
organization_id="your-org-uuid",
job_preparation_id=prep_resp.id,
execution_plan_id=result.quote[0].execution_plan_id,
queue_priority_id=result.quote[0].queue_priorities[0].queue_priority_id,
)
job = scheduler.create_job(job_create)
# Step 5: Poll job status
job = scheduler.get_job(job.id)
Related Pages¶
- Backend Discovery -- Find available backends before submitting.
- Examples -- Complete workflows.
- Job Lifecycle -- Detailed job state machine.