# 任务提交与报价

QuantumFerry 把一次实验分为准备、确认和读取结果。准备对象保存线路对应的报价，确认时自动关联。Qiskit、PennyLane 和 Core 共用平台流程，各自提供适合对应线路对象的接口。

## 选择提交入口

| 入口 | 输入 | 只准备报价 | 确认并取结果 |
| --- | --- | --- | --- |
| Core | OpenQASM UTF-8 bytes 或文件 | scheduler.prepare_submission(config, file_content=...) | prepared.confirm(wait=False)，再等待原 submission_id 并下载结果。 |
| Qiskit | QuantumCircuit 或线路列表 | backend.prepare(qc, shots=128) | job = prepared.confirm()，再 job.result(timeout=300)。 |
| PennyLane | QuantumScript / tape 或 tape 列表 | dev.prepare(tape) | prepared.confirm(wait=False)，再 prepared.result(timeout=300)。 |

以下参数和示例使用 Core；Qiskit 与 PennyLane 的具体写法见各自入门页。prepare 上传线路并生成报价，confirm 接受报价并执行实验。

## 先为客户端选择钱包

SchedulerClient 与 QuantumSourceService 默认使用 OPEN。使用 FULL 时，创建客户端时传 currency="FULL"；PennyLane 独立设备可直接选择，注入 scheduler 的设备继承 scheduler.currency。可通过只读 currency 属性查看当前选择。

准备完成后，金额和币种固定在对应报价中。需要切换钱包时，使用对应客户端准备新报价。HTTP 402 表示该次确认在余额检查阶段停止、线路尚未发送；发送结果待核实的任务继续使用原提交号查询。

## 定义一次 Core 任务

以下配置沿用快速开始中的 scheduler、backend_id、organization_id 和 qasm。根据程序需要，选择文件输入、字节输入或自动批准等用法。

```python
from quantum_source_sdk import JobSubmissionConfig

config = JobSubmissionConfig(
    backend_class_id=backend_id,
    organization_id=organization_id,
    name="bell-experiment",
    shots=128,
    input_format="openqasm2",
    configuration_data={"circuit_representation": "logical"},
)
```

| 参数 | 类型 / 默认值 | 用途 |
| --- | --- | --- |
| backend_class_id | str，必填 | 设备 ID 或 short_code。 |
| name | str，必填 | 供自己识别实验的名称。 |
| shots | int / None | 该线路的采样次数，填写正整数；也可由 configuration_data 提供。 |
| organization_id | str / None | 任务所属组织，涉及权限和共享名额；扣费使用当前用户钱包。多个组织时显式选择。 |
| job_subcategory_id | str / "oth:oth" | 任务分类。 |
| input_format | str / None | 输入程序格式。可填写 openqasm2 或 openqasm3；省略时由平台根据程序头识别版本。 |
| configuration_data | Mapping / None | 线路语义及设备配置。可调字段由所选设备的 configuration_schema 声明。 |
| execution_plan / queue_priority | "public" / "stand" | 当前平台执行通道的默认值。 |
| auto_approve_quote | bool / True | 控制 submit_job 便捷入口是否自动批准报价。 |
| job_timeout_seconds | float / 86400.0 | 高层确认等待的时间上限；准备阶段使用客户端 wait_timeout_seconds。 |
| verbose | bool / False | 准备成功时打印简短的 job_prepared 事件。 |
| submitted_with | str / "sdk" | 提交来源标签。 |
| provider | str / None | 可选厂商前缀；使用完整 short_code 时可省略。 |

本手册在顶层填写 shots。若 configuration_data 中也提供 shots，两个值应相同。当前平台使用 public + stand 通道，金额和币种由平台报价给出。

## 从字符串或文件准备

按线路保存方式选择一种输入：Python 字符串先编码为 UTF-8 bytes，再传给 file_content；已有文件则通过 file_path 指定本机路径，由 SDK 读取并上传。快速开始中的 qasm 已经是 bytes。

```python
prepared = scheduler.prepare_submission(config, file_content=qasm)
```

```python
# 另一种输入方式：从自己的文件准备一个独立实验
prepared = scheduler.prepare_submission(config, file_path="bell.qasm")
```

每次准备选择 file_content 或 file_path 中的一种。Core 接收带版本头的 OpenQASM 2/3 程序，SDK 和平台负责上传、解析与厂商格式转换。

## 选择程序的输入格式

| 声明 | 当前 SDK / 平台含义 |
| --- | --- |
| openqasm2 | 以 OPENQASM 2.0 开头的程序。 |
| openqasm3 | 以 OPENQASM 3.0 开头的程序。 |

## 使用自己的 OpenQASM 文件

将自己的 OpenQASM 程序保存为 experiment.qasm。需要在上传前查看程序时，可以先读取文件内容；后续将 qasm_bytes 作为 file_content 传入准备方法。

```python
from pathlib import Path

qasm_bytes = Path("experiment.qasm").read_bytes()
print(qasm_bytes.decode("utf-8"))
```

input_format 填写文件对应的 openqasm2 或 openqasm3。直接使用 Qiskit 线路或 PennyLane QNode 的用户，可在对应插件中完成提交和结果读取。

## 阅读报价，再确认这一条实验

```python
submission_id = prepared.preparation.id
print(prepared.quote)
```

报价列出任务数、总 shots、金额、币种和有效期。查看并接受报价后，运行下面的确认代码。尚未执行的报价过期时可重新准备；已发送任务的进度通过原提交号查询。

```python
receipt = prepared.confirm(wait=False)
```

confirm 确认执行实验。wait=False 在提交后返回平台受理信息；prepared.confirm(wait=True) 则在同一个调用中等待任务完成，等待上限由 JobSubmissionConfig.job_timeout_seconds 设置。

## 区分提交号与任务号

```python
receipt = scheduler.get_submission(submission_id)
print(receipt.submission_status)

job = scheduler.wait_for_submission(submission_id, timeout_seconds=300)
print(job.id)
result = scheduler.download_job_result(job)
print(result.primary_value)
```

| 对象 / 标识 | 何时使用 |
| --- | --- |
| prepared.preparation.id | 准备后保存，用于跟踪这一次提交的发送进度。 |
| receipt.submission_status | 平台发送进度。 |
| job.id | 任务记录的标识，用于查询计算状态。 |
| UnifiedResult.primary_value | 任务完成后的主要结果数据；类型由 result_kind 标识。 |

## 需要自动批准时用 submit_job

需要自动接受报价并执行新实验时，使用 scheduler.submit_job(config, file_content=qasm)。它依次准备、批准并等待完成。需要先展示报价时，选择本页的 prepare / confirm 分步流程。

## 在哪里设置设备专属选项

读取所选设备的 configuration_schema，把需要的选项放入 configuration_data，例如逻辑线路的 mapping 设置。Qiskit 还提供动态 Options 和单任务关键字；各客户端的完整用法见下方专章。

- [Qiskit 设备选项](capabilities-qiskit.html)
- [PennyLane 设备选项](capabilities-pennylane.html)
- [Core 配置字典](capabilities-core.html)

## 等待超时后继续查询

等待超时后，保留 prepared 或 submission_id，继续查询同一个任务。批次处理、取消操作与返回类型见 Core 教程；需要协助时提供错误提示、原记录 ID 和 Request ID。

- [Core 批次与恢复](core.html)
- [任务查询、分页与下载](job-query.html)
- [底层上传与确认](low-level.html)
- [结果与常见问题](results.html)
- [下载示例](testing.html)

## 下载本页 Jupyter Notebook

收录本页 Python 示例与说明，便于在 Jupyter Notebook 中学习和运行；安装命令保留为说明。

[下载《任务提交与报价》Notebook（.ipynb）](../../notebooks/sdk_user_guide_job_submission.ipynb)
