Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/bin/sh
#
# This pre-commit hook cleans Jupyter notebooks before they are committed.
# It uses nb-clean to remove unnecessary metadata, which helps to reduce
# noise in commits and avoid merge conflicts.

# Check if uv is installed. If not, warn the user and exit gracefully.
if ! command -v uv >/dev/null 2>&1; then
echo "-----------------------------------------------------------------"
echo "Warning: 'uv' is not installed, so notebooks will not be cleaned."
echo "For cleaner commits, please install uv:"
echo "https://astral.sh/uv"
echo "-----------------------------------------------------------------"
exit 0
fi

# Get a list of staged .ipynb files.
STAGED_NOTEBOOKS=$(git diff --cached --name-only --filter=ACM -- "*.ipynb")

if [ -z "$STAGED_NOTEBOOKS" ]; then
exit 0
fi

echo "Cleaning staged notebooks..."

# Loop through the staged notebooks and clean them.
for notebook in $STAGED_NOTEBOOKS; do
echo " - $notebook"
uvx nb-clean clean --remove-all-notebook-metadata "$notebook"
git add "$notebook"
done

echo "Notebook cleaning complete."
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ If you're unfamiliar with Jupyter but you're used to a traditional IDE or code e

---

## Git Hooks

This repository includes a _`pre-commit` Git hook_ to automatically clean Jupyter notebook metadata using `nb-clean` before committing. This helps reduce unnecessary noise in commits and avoid merge conflicts.

To enable this, run the following command in your terminal from the root of this repository:

```shell
git config core.hooksPath .githooks
```

**Note:** If `uv` is not installed, the hook will issue a warning and skip the cleaning process.

---

## Support

For support, you can submit issues or PRs in this repository. Alternatively, you can contact us at [support@ionq.com](mailto:support@ionq.com?subject=SDK%20help).
117 changes: 92 additions & 25 deletions api.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,91 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "import json\nimport time\n\nimport requests\n\nfrom helpers import get_ionq_api_key\n\n# Before you begin, get your API key from https://cloud.ionq.com/settings/keys\n\n# If your API key is stored as \"IONQ_API_KEY\" in your local environment, this\n# should find it. Otherwise you'll be prompted to enter your API key manually.\n\napi_key = get_ionq_api_key()"
"source": [
"import json\n",
"import time\n",
"\n",
"import requests\n",
"\n",
"from helpers import get_ionq_api_key\n",
"\n",
"# Before you begin, get your API key from https://cloud.ionq.com/settings/keys\n",
"\n",
"# If your API key is stored as \"IONQ_API_KEY\" in your local environment, this\n",
"# should find it. Otherwise you'll be prompted to enter your API key manually.\n",
"\n",
"api_key = get_ionq_api_key()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "# Define helper functions for interacting with IonQ's API.\n\ndef submit_job(headers, data):\n \"\"\"Submit a quantum job to IonQ's API.\"\"\"\n url = \"https://api.ionq.co/v0.3/jobs\"\n response = requests.post(url, headers=headers, data=data)\n response_json = response.json()\n assert response.status_code == 200, f\"Error: {response_json.get('message', 'Unknown error')}\"\n return response_json[\"id\"]\n\ndef query_job(job_id, headers):\n \"\"\"Query the status of a submitted job.\"\"\"\n url = f\"https://api.ionq.co/v0.3/jobs/{job_id}\"\n response = requests.get(url, headers=headers)\n response_json = response.json()\n assert response.status_code == 200, f\"Error: {response_json.get('message', 'Unknown error')}\"\n return response_json[\"status\"]\n\ndef get_job_results(job_id, headers):\n \"\"\"Retrieve the results of a completed job.\"\"\"\n url = f\"https://api.ionq.co/v0.3/jobs/{job_id}/results\"\n response = requests.get(url, headers=headers)\n response_json = response.json()\n assert response.status_code == 200, f\"Error: {response_json.get('message', 'Unknown error')}\"\n return response_json"
"source": [
"# Define helper functions for interacting with IonQ's API.\n",
"\n",
"def submit_job(headers, data):\n",
" \"\"\"Submit a quantum job to IonQ's API.\"\"\"\n",
" url = \"https://api.ionq.co/v0.3/jobs\"\n",
" response = requests.post(url, headers=headers, data=data)\n",
" response_json = response.json()\n",
" assert response.status_code == 200, f\"Error: {response_json.get('message', 'Unknown error')}\"\n",
" return response_json[\"id\"]\n",
"\n",
"def query_job(job_id, headers):\n",
" \"\"\"Query the status of a submitted job.\"\"\"\n",
" url = f\"https://api.ionq.co/v0.3/jobs/{job_id}\"\n",
" response = requests.get(url, headers=headers)\n",
" response_json = response.json()\n",
" assert response.status_code == 200, f\"Error: {response_json.get('message', 'Unknown error')}\"\n",
" return response_json[\"status\"]\n",
"\n",
"def get_job_results(job_id, headers):\n",
" \"\"\"Retrieve the results of a completed job.\"\"\"\n",
" url = f\"https://api.ionq.co/v0.3/jobs/{job_id}/results\"\n",
" response = requests.get(url, headers=headers)\n",
" response_json = response.json()\n",
" assert response.status_code == 200, f\"Error: {response_json.get('message', 'Unknown error')}\"\n",
" return response_json"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "# Set up the request headers and define our circuit.\n# This circuit creates a Bell state with two qubits using IonQ's native format.\n\nheaders = {\n \"Authorization\": f\"apiKey {api_key}\",\n \"Content-Type\": \"application/json\",\n}\n\ndata = {\n \"name\": \"API Example Circuit\",\n \"shots\": 100,\n \"target\": \"simulator\",\n \"input\": {\n \"format\": \"ionq.circuit.v0\",\n \"gateset\": \"qis\",\n \"qubits\": 2,\n \"circuit\": [\n {\n \"gate\": \"h\",\n \"target\": 0\n },\n {\n \"gate\": \"cnot\",\n \"control\": 0,\n \"target\": 1\n }\n ]\n }\n}\n"
"source": [
"# Set up the request headers and define our circuit.\n",
"# This circuit creates a Bell state with two qubits using IonQ's native format.\n",
"\n",
"headers = {\n",
" \"Authorization\": f\"apiKey {api_key}\",\n",
" \"Content-Type\": \"application/json\",\n",
"}\n",
"\n",
"data = {\n",
" \"name\": \"API Example Circuit\",\n",
" \"shots\": 100,\n",
" \"target\": \"simulator\",\n",
" \"input\": {\n",
" \"format\": \"ionq.circuit.v0\",\n",
" \"gateset\": \"qis\",\n",
" \"qubits\": 2,\n",
" \"circuit\": [\n",
" {\n",
" \"gate\": \"h\",\n",
" \"target\": 0\n",
" },\n",
" {\n",
" \"gate\": \"cnot\",\n",
" \"control\": 0,\n",
" \"target\": 1\n",
" }\n",
" ]\n",
" }\n",
"}\n"
]
},
{
"cell_type": "markdown",
Expand Down Expand Up @@ -65,7 +135,23 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "# Now we'll send the job to our backend for processing.\n\njob_id = submit_job(headers, json.dumps(data))\n\n# And wait for the job to complete.\n\nstatus = \"ready\"\nwhile status != \"completed\":\n time.sleep(1) # Wait for 1 second before querying again.\n status = query_job(job_id, headers)\n\n# Once the job has completed, we can retrieve and display the results.\n\nresults = get_job_results(job_id, headers)\nprint(results)"
"source": [
"# Now we'll send the job to our backend for processing.\n",
"\n",
"job_id = submit_job(headers, json.dumps(data))\n",
"\n",
"# And wait for the job to complete.\n",
"\n",
"status = \"ready\"\n",
"while status != \"completed\":\n",
" time.sleep(1) # Wait for 1 second before querying again.\n",
" status = query_job(job_id, headers)\n",
"\n",
"# Once the job has completed, we can retrieve and display the results.\n",
"\n",
"results = get_job_results(job_id, headers)\n",
"print(results)"
]
},
{
"cell_type": "markdown",
Expand All @@ -77,26 +163,7 @@
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv (3.14.2)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.2"
},
"orig_nbformat": 4
},
"metadata": {},
"nbformat": 4,
"nbformat_minor": 2
}
}
73 changes: 35 additions & 38 deletions cirq.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -31,11 +31,26 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "import cirq\nimport cirq_ionq\nimport matplotlib.pyplot as plt\n\nfrom helpers import get_ionq_api_key\n\n# Before you begin, get your API key from https://cloud.ionq.com/settings/keys\n\n# If your API key is stored as \"IONQ_API_KEY\" in your local environment, this\n# should find it. Otherwise you'll be prompted to enter your API key manually.\n\napi_key = get_ionq_api_key()\n\nservice = cirq_ionq.Service(api_key=api_key, default_target='simulator')"
"source": [
"import cirq\n",
"import cirq_ionq\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from helpers import get_ionq_api_key\n",
"\n",
"# Before you begin, get your API key from https://cloud.ionq.com/settings/keys\n",
"\n",
"# If your API key is stored as \"IONQ_API_KEY\" in your local environment, this\n",
"# should find it. Otherwise you'll be prompted to enter your API key manually.\n",
"\n",
"api_key = get_ionq_api_key()\n",
"\n",
"service = cirq_ionq.Service(api_key=api_key, default_target='simulator')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -52,19 +67,9 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0: ───H───@───M───\n",
" │ │\n",
"1: ───────X───M───\n"
]
}
],
"outputs": [],
"source": [
"# Before submitting the job, we can visualize the circuit using print().\n",
"\n",
Expand All @@ -76,33 +81,25 @@
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "# Now we'll send the job to our backend for processing and plot the results.\n\nresult = service.run(circuit, name=\"Cirq example\", repetitions=100)\n_ = cirq.plot_state_histogram(result, plt.subplot())\nplt.show()"
"source": [
"# Now we'll send the job to our backend for processing and plot the results.\n",
"\n",
"result = service.run(circuit, name=\"Cirq example\", repetitions=100)\n",
"_ = cirq.plot_state_histogram(result, plt.subplot())\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"source": "## And that's a wrap!\n\nTo continue learning with Cirq, check out more examples and documentation at https://quantumai.google/cirq",
"metadata": {}
"metadata": {},
"source": [
"## And that's a wrap!\n",
"\n",
"To continue learning with Cirq, check out more examples and documentation at https://quantumai.google/cirq"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "venv (3.14.2)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.2"
}
},
"metadata": {},
"nbformat": 4,
"nbformat_minor": 4
}
}
Loading