fix(cloud): migrate off deprecated /extract endpoint and stop misreading deprecation 429 as a quota error - #57
Closed
gbharg wants to merge 1 commit into
Closed
Conversation
…ing deprecation 429 as a quota error
Cloud mode POSTed to nanonets' deprecated `/extract` endpoint, which now
responds with HTTP 429 and a body of
`{"detail": "The /extract endpoint is deprecated. Please migrate to
/api/v1/extract."}`. The 429 handler only inspected the status code, so
whenever an API key was present it unconditionally raised
"Rate limit exceeded (10k/month)". Users with a valid key and unused quota
therefore saw a false "quota exceeded" error and OCR silently failed.
Changes:
- Point `api_url` at the current sync endpoint
`https://extraction-api.nanonets.com/api/v1/extract/sync`.
- Send `output_format` (required by the new endpoint), mapped from the legacy
`output_type` vocabulary; `output_type` is still sent for backward compat.
- Make the 429 handler body-aware: a deprecation notice now surfaces the real
message instead of a fabricated quota error; genuine rate-limit bodies are
still reported as such (and now include the server's detail).
- Parse the new nested response shape `result.<format>.content` while keeping
backward compatibility with the legacy top-level `content` field.
- Add offline (mocked) unit tests covering the endpoint, request params,
deprecation-vs-quota 429 handling, and both response shapes.
Verified: raw `POST /api/v1/extract/sync` with `output_format` and a valid
Bearer key returns HTTP 200 with correct OCR; the previous `/extract` call
returned the deprecation 429 described above.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Author
|
Closing this one -- we are handling the change downstream for now. Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cloud mode currently fails for users with a valid API key and unused quota, reporting a misleading
Rate limit exceeded (10k/month)error. The root cause is a deprecated endpoint whose deprecation response is misread as a quota error.Symptom
With a valid Nanonets key configured, any cloud extraction (e.g.
extract_markdown(),parse_pdf) raises:…even on a brand-new key that has never been used. OCR then silently fails.
Root cause
docstrange/processors/cloud_processor.pyPOSTs to nanonets' deprecated/extractendpoint:Nanonets now returns HTTP 429 for that endpoint, but with a deprecation body — not a quota body:
{"detail": "The /extract endpoint is deprecated. Please migrate to /api/v1/extract."}The 429 handler inspects only the status code and never reads the body, so whenever an API key is present it unconditionally raises
Rate limit exceeded (10k/month). A deprecation notice is thus reported to the user as an exhausted quota.Fix
https://extraction-api.nanonets.com/api/v1/extract/sync.output_format(required by the new endpoint), mapped from the legacyoutput_typevocabulary (markdown|html|csvpass through;flat-jsonand thespecified-*variants map tojson).output_typeis still sent for backward compatibility.result.<format>.content, while keeping backward compatibility with the legacy top-levelcontentfield.tests/test_cloud_deprecation.py, fully offline (HTTP + file I/O mocked; no API key or network needed), covering the endpoint, request params, deprecation-vs-quota 429 handling, and both response shapes.Verification
Confirmed against the live API (key redacted):
POST /extract(old) → HTTP 429, body{"detail": "The /extract endpoint is deprecated. Please migrate to /api/v1/extract."}.POST /api/v1/extract/syncwithoutoutput_format→ HTTP 422 (missing required field), key accepted (no 401/403).POST /api/v1/extract/syncwithoutput_format=markdown+ Bearer key → HTTP 200,"success": true, correct OCR of a scanned document.After applying this change, cloud extraction returns real OCR content on a valid key, and a deprecation 429 (if it ever recurs) is no longer misreported as a quota error.
Backward compatibility
contentresponse field is still handled.output_typeis still sent alongside the newoutput_format.🤖 Generated with Claude Code