Skip to content

fix: Fix estimate, usage, and job-response parsing against the live v0.4 API - #93

Open
antalszava wants to merge 13 commits into
mainfrom
fix_estimate_and_org_usage_schema
Open

fix: Fix estimate, usage, and job-response parsing against the live v0.4 API#93
antalszava wants to merge 13 commits into
mainfrom
fix_estimate_and_org_usage_schema

Conversation

@antalszava

@antalszava antalszava commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Fixes three runtime failures against the live v0.4 API — estimate_job_cost, get_usages, and get_job parsing — by patching stale/incorrect schemas in openapi-overlay.yaml and regenerating the client. Also unblocks committing generated output (pre-commit was rewriting it) and fixes a pytest deprecation in the integration tests.

Hand-written changes

Library

  • ionq_core/polling.py — the spec's GetJobResponse component became an anyOf union, so the generator no longer emits a model class for it; replaced the dead import with a TYPE_CHECKING-only union alias over the four job types.

Spec overlay (openapi-overlay.yaml)

  • GetJobEstimateResponse replaced with the shape the API actually serves (estimate_context / rate_card / estimated_total_cost / estimated_unit) — was raising KeyError: 'input_values'.
  • organization_id no longer format: uuid — real org ids are reverse-DNS strings; was raising badly formed hexadecimal UUID string.
  • Usage.from widened datedate-time — the API returns RFC 3339 date-times; was raising Invalid isoformat string.
  • ErrorMitigationOutput.debiasing widened to anyOf boolean/object — the API serves false when debiasing is off; was surfacing as a misleading Unexpected value 'ionq.circuit.v1' from the GetJobResponse union parser.

Tooling

  • .pre-commit-config.yaml — excluded generated files from trailing-whitespace / end-of-file-fixer; they were rewriting generator output at commit time and breaking the generated.yml byte-exact staleness check.
  • CHANGELOG.md — "Fixed" entries for the estimate, org-id, and Usage.from bugs.

Integration tests

  • conftest.py — new session-scoped base_url fixture (reads IONQ_API_URL, falls back to the default).
  • test_async.py / test_backends.py — fixtures thread base_url through instead of hardcoding it.
  • test_usage.py — new org_id fixture (reads IONQ_ORG_ID, skips when unset); used instead of the literal "self".
  • test_simulator_job.pycompleted_job_id moved from a class-scoped instance-method fixture to a module-level session fixture, fixing PytestRemovedIn10Warning: Class-scoped fixture defined as instance method is deprecated.
  • test_sessions.py — accepts "created" as a valid initial session status.

Generated changes

Everything under ionq_core/api/ and ionq_core/models/ (105 files: ~50 new models from the May-2026 upstream spec sync — the SingleCircuitJob / MultiCircuitJob / QaoaJob / QuantumFunctionJob families, result formats, artifact descriptors, the new move_job and schemas endpoints — plus modifications from the overlay fixes above). Mechanical openapi-python-client output; the generated.yml staleness check reproduces it byte-for-byte, so it doesn't need line-by-line review. openapi.json is the vendored upstream spec (1-line change).

Testing

  • Unit suite: 242 passed, 100% coverage on the hand-written surface.
  • Integration suite against the live API: all passing except the two known test_sessions failures (sessions not enabled for project, an account limitation).

Note on AI usage

  • PR description: generated by Claude;
  • PR: aided by Claude.

@antalszava antalszava changed the title fix: draft for fixing estimate_job_cost and get_usages fix: draft for fixing estimate_job_cost and get_usages [WIP] Aug 14, 2026
@antalszava antalszava changed the title fix: draft for fixing estimate_job_cost and get_usages [WIP] fix: Fix estimate, usage, and job-response parsing against the live v0.4 API Aug 19, 2026
@antalszava
antalszava marked this pull request as ready for review August 19, 2026 22:22
@antalszava
antalszava requested a review from a team as a code owner August 19, 2026 22:22
@antalszava
antalszava requested review from natestemen and splch August 19, 2026 22:22

@hodgestar-ionq hodgestar-ionq left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some questions and comments. Thank you for all the fixes.

Comment thread ionq_core/polling.py
Comment on lines +44 to +45
# The spec's GetJobResponse component is an anyOf union, which the
# generator inlines instead of emitting as a model class.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# The spec's GetJobResponse component is an anyOf union, which the
# generator inlines instead of emitting as a model class.
# The spec's GetJobResponse component is an anyOf union, which the
# generator inlines instead of emitting as a model class, so we manual
# construct an appropriate GetJobResponse type here:

Does this mean this definition will need to be manually updated if the model is changed? Is there a unit test that would catch the mismatch if a change was made?

Comment on lines +23 to +26
key = os.environ.get("IONQ_API_URL")
if not key:
return DEFAULT_BASE_URL
return key

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
key = os.environ.get("IONQ_API_URL")
if not key:
return DEFAULT_BASE_URL
return key
return os.environ.get("IONQ_API_URL", DEFAULT_BASE_URL)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, what was the reason for allowing the base URL used by the tests to be overridden by IONQ_API_URL?



@pytest.fixture(scope="session")
def completed_job_id(client):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did this fixture get moved?

I'm also confused about the scope. It looks like it could just be omitted? The scope of the client fixture is function.



def test_get_usages(client):
@pytest.fixture

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering why these tests need to be skipped? Are they run against a live API somewhere?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants