Skip to content

feat(ebuy): add the GSA eBuy requests resource - #70

Merged
vdavez merged 2 commits into
mainfrom
feat/ebuy
Sep 28, 2026
Merged

vdavez merged 2 commits into
mainfrom
feat/ebuy

Conversation

@makegov-mark

@makegov-mark makegov-mark Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

What

Adds the GSA eBuy requests resource (Tango API 5.1.0):

Method Endpoint Returns
list_ebuy_requests(page, limit, shape, flat, flat_lists, search, rfq_id, reference_number, request_type, status, sin, schedule, buyer_agency, agency, contract_number, issue_date_after, issue_date_before, close_date_after, close_date_before, ordering) GET /api/ebuy/requests/ PaginatedResponse of shaped dicts
get_ebuy_request(rfq_id, shape=None, flat=False, flat_lists=False) GET /api/ebuy/requests/{rfq_id}/ shaped dict
get_ebuy_attachment_url(rfq_id, doc_seq_num) -> str GET /api/ebuy/requests/{rfq_id}/attachments/{doc_seq_num}/download/ the signed URL the API redirects to
get_ebuy_access() -> EbuyAccess GET /api/ebuy/access/ EbuyAccess(enabled, reason, contracts)

Plus EbuyRequest / EbuyAttachment shape schemas, the EBUY_REQUESTS_MINIMAL / EBUY_REQUESTS_COMPREHENSIVE defaults (mirroring the API's list and retrieve defaults), and ebuy_request documented as an alert query type.

Behavior worth knowing

  • Access is scoped to the caller's account and requires Pro or above. With no linked contract the list is empty rather than an error; get_ebuy_access() tells "no access" from "no matches".
  • status is frozen at the last state a request was seen in. The docstrings, model and API reference say so and point at last_seen.
  • get_ebuy_attachment_url() requests with redirects disabled and returns the Location target, so no document is downloaded. A link entry (is_link) raises the new TangoAttachmentLinkError, a TangoValidationError subclass exposing the link as .url; an uncaptured document raises TangoNotFoundError with the API's detail.
  • The agency filter requires Tango API 5.3.0 and says so; the others work from 5.1.0.
  • As on every other resource in this SDK, an omitted shape sends the ShapeConfig default, which mirrors the API's own default so the response is the same while fields parse to typed values.
  • The comprehensive default names the attachment fields instead of attachments(*), because the SDK does not type-parse wildcard expands and doc_session_date would otherwise stay a string.
  • _request()'s status-to-exception mapping moved into _raise_for_status() unchanged, so the attachment method can reuse it.

Conformance

  • ebuy/requests is mapped in check_filter_shape_conformance.py and check_shape_coverage.py; its unmapped_resource entry is removed from contracts/shape_coverage_baseline.json. The vendored contract already covered the resource, so it is not refreshed.
  • generated_overlay.py was regenerated: now that the explicit schema covers eBuy attachments, the generator drops an orphan nested schema and renumbers the rest. No overlay-backed field changes type.

Testing

  • uv run pytest: 573 passed, 31 skipped (new tests/test_ebuy.py, 19 tests, mocked transport)
  • uv run ruff format --check tango/, uv run ruff check tango/, uv run mypy tango/: clean
  • scripts/check_filter_shape_conformance.py: no errors, no eBuy warnings
  • scripts/check_shape_coverage.py: no drift

No cassette-backed integration test, deliberately: a recorded eBuy response would publish buyer names, emails and contract details into this public repo, so the new tests mock the transport.

🤖 Generated with Claude Code

vdavez and others added 2 commits September 28, 2026 14:29
Adds `list_ebuy_requests()`, `get_ebuy_request()`, `get_ebuy_attachment_url()` and `get_ebuy_access()` over the `/api/ebuy/` resource (Tango API 5.1.0), with `EbuyRequest` / `EbuyAttachment` schemas, an `EbuyAccess` result type and the `EBUY_REQUESTS_MINIMAL` / `EBUY_REQUESTS_COMPREHENSIVE` default shapes.
All fourteen of the API's list filters are explicit named parameters.
`get_ebuy_attachment_url()` reads the download redirect without following it and returns the short-lived signed URL; a link entry raises `TangoValidationError` carrying the link.
The response-status handling in `_request()` moves into `_raise_for_status()` so the attachment method can share it.
`ebuy/requests` is now mapped in both conformance gates, and its unmapped-resource shape-coverage baseline entry is removed.
`ebuy_request` is documented as an alert query type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`get_ebuy_attachment_url()` now raises `TangoAttachmentLinkError`, a `TangoValidationError` subclass exposing the link as `.url`, when the entry is an external link rather than a stored document.
The `agency` filter on `list_ebuy_requests()` documents that it requires Tango API 5.3.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vdavez
vdavez marked this pull request as ready for review September 28, 2026 19:37
@vdavez
vdavez merged commit c33db62 into main Sep 28, 2026
11 checks passed
@makegov-mark makegov-mark Bot mentioned this pull request Sep 28, 2026
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.

1 participant