Releases: makegov/tango-python
Release list
v1.4.0
Added
-
list_protests()now acceptsnaics_code, filtering protests by the solicitation's NAICS code. The API has always supported it (verified live: 15,027 protests unfiltered, 12 for541519, 2 for336411), butprotestswas absent from the conformance checker's resource-to-method map, so the gap was never reported. -
list_psc()now acceptshas_awards, restricting results to codes with contract award history (2,526 PSC codes unfiltered, 2,243 with awards).Falseis sent explicitly rather than dropped, since the API distinguishes the two. This param has always worked but was invisible to the contract until makegov/tango#2948 added theview_handled_paramsdeclaration for params a viewset reads straight fromquery_params. That PR also fixed a truthiness bug wherehas_awards=falsefiltered identically totrue, and is deployed — verified live at 2,526 forFalseand 2,243 forTrue.One caveat that is not an SDK issue:
/api/psc/responses are cached for 30 days per query-param key, so any?has_awards=key requested before that deploy still serves the old awards-only result until its entry expires or is invalidated.
Fixed
-
The reverse shape-coverage gate was blind to seven resources, and the SDK's schemas had silently drifted behind four of them. The gate skipped any resource whose contract shape tree was falsy (
if not shape: continue). Tango published"shape": nullforentities,opportunities,notices,protests,itdashboard,events, andnews— five of them because its contract generator crashed on tier-aware viewsets (makegov/tango#2944) — so the gate reported full coverage while checking nothing for them. Re-vendoring the fixed contract surfaced 69 real gaps (36 fields, 20 expands, 13 flattened expands) across entities, notices, protests, and itdashboard, all now closed by a regenerated overlay.The user-visible consequence was worse than missing schema entries. Because
ShapeParservalidates client-side, the SDK rejected 13 fields the API accepts, before ever issuing a request —list_entities(shape="display_name")raisedShapeValidationErroragainst an endpoint that returns 200 for it. Affected:Entity'sdisplay_name,entity_type,entity_structure,organization_structure,profit_structure,purpose_of_registration,country_of_incorporation,past_performance,registered,sba_business_types, andProtest'sdecisions,resolved_agency,resolved_protester. All 13 now validate. Note thatregisteredandsba_business_typesregressed in 1.3.0 — they validated under 1.1.1 — so the overlay generation had narrowedEntitywhile nothing was watching.The gate no longer skips silently: a resource declaring
shape_supported: truewith no shape tree is now a hard finding (contract_missing_shape) reported as an upstream contract defect rather than an SDK one. Contracts predatingschema_version: 2omit the key, where a null tree stays genuinely ambiguous and skipping remains correct. -
Seven resources with working SDK methods were never conformance-checked at all.
RESOURCE_TO_METHODomittedprotests,psc,mas_sins,departments,business_types, andassistance_listingsentirely, and mappedofficestoNoneas "not yet implemented" even thoughlist_officesexists. Their filter coverage had never been validated. Wiring them up found one real gap (protests.naics_code, above); the other six were already complete.eventsandnewsstay mapped toNone— genuinely absent from the SDK, now with a note explaining thatlist_webhook_event_typesis unrelated. -
refresh_contract.py+probe_shape_types.pyre-run against the corrected contract.contracts/observed_shape_types.jsongained live-sampled types for the five newly-visible resources (entities alone contributes 136 observed paths), so the regenerated overlay resolves their types from real API responses rather than name heuristics.
Changed
CONTRACT_OMITTED_PARAMSnow warns when an entry is no longer needed, mirroring how baseline entries are burned down, and the list is now empty — which is the goal state. It briefly heldmas_sins: search, added because the API applies it (330 results unfiltered, 0 for a nonsense term, 32 foroffice) while the contract recordedfilter_params: [], so the checker would otherwise have flagged a working parameter as a silent no-op and invited its removal. Both that entry andbudget/accounts: searchwere retired by the new warning once makegov/tango#2944 and #2948 taught the contract generator to publish them. The carve-out mechanism stays for the next such case.
v1.3.0
Added
-
DIBBS, exclusions, and SBIR/STTR endpoint support. Six endpoint families
Tango shipped in v4.16–v4.18 had no SDK support at all — no models, no methods.
Addedlist_dibbs_rfqs/get_dibbs_rfq,list_dibbs_rfps/get_dibbs_rfp,
list_dibbs_awards/get_dibbs_award,list_exclusions/get_exclusion,
list_sbir_topics/get_sbir_topic, and
list_sbir_solicitations/get_sbir_solicitation, with all 85 filter params,
shape schemas, andShapeConfigdefaults. New models:DibbsRfq,DibbsRfp,
DibbsAward,Exclusion,SbirTopic,SbirSolicitation.Two API behaviors are worth knowing.
is_open(DIBBS) and
is_currently_excluded(exclusions) are derived at query time, so filter with
theopen/activekwargs rather than shaping on those fields. And DIBBS
total_contract_priceis the order total repeated on every line item —
never sum it across rows; deduplicate on award + delivery-order number first. -
Reverse shape-coverage: the SDK now captures every field and expand the API
returns. The conformance check only validated one direction — that the SDK's
shape constants reference allowed fields. Nothing checked the reverse, so the
hand-maintainedtango/shapes/explicit_schemas.pyhad silently fallen ~200+
fields behind the API: 209 leaf fields, 41 whole nested expand branches, and 3
resources (naics, psc, mas_sins) the typed shape API could not request at all.
A new generated overlay (tango/shapes/generated_overlay.py, produced by
scripts/generate_shape_overlay.pyand merged over the base bySchemaRegistry)
closes all of them, with types resolved from live-API sampling rather than
guessed. Notable now-shapeable data: contract/IDV acquisition attributes
(fair_opportunity_limited_sources,subcontracting_plan, …),contracts.officers
andperiod_of_performance, the fullorganizationshierarchy
(obligation_rank,l1..l8_fh_key,budget_appropriation,children/parent),
otas/otidvstransactions, and the deepvehicles.awardees[.orders]tree.
Code-object expands (set_aside,award_type,idv_type, …), previously
modeled inconsistently asstr/baredict, now uniformly resolve to
{code, description}. -
Reverse shape-coverage gate.
scripts/check_shape_coverage.pywalks Tango's
shape trees (from the vendored contract) against the SDK schemas and fails when
the SDK misses anything the API exposes and it isn't in
contracts/shape_coverage_baseline.json. Offline against the vendored contract —
no token, runs on forks — and wired into thelint.ymlconformance job.
Regenerate the overlay withscripts/generate_shape_overlay.py(from the vendored
contract +contracts/observed_shape_types.json, no API key); refresh the type
observations withscripts/probe_shape_types.py(maintainer-run, needs a key). -
Contract-first conformance system. The canonical API filter/shape
contract is now vendored atcontracts/filter_shape_contract.json(refresh
with the newscripts/refresh_contract.py), so the conformance check runs
out of the box — locally, in CI, and on forks — with no tango checkout or
access token.scripts/check_filter_shape_conformance.pygained three new
checks on top of filter coverage: staleness (an SDK filter argument the
API no longer accepts is an error — it would silently no-op), types
(each argument's annotation is validated against the contract's
schema_version: 2per-filter type metadata), and a known-gaps baseline
(contracts/conformance_baseline.json) that downgrades accepted missing
params from errors to warnings so backlog is tracked instead of silent. A
new--suggestflag prints ready-to-paste typed parameter scaffolds for
any missing filters. The first run against the current API surface found 7
real coverage gaps, now baselined:keyon contracts/IDVs/OTAs/OTIDVs,
cageon entities,idon forecasts, andopportunity_idon
opportunities. -
TangoValidationErrornow exposes the API's structured validation details
directly:.issues(the list of{"path": ..., "reason": ...}entries the
server returns for shape errors) and.available_fields(the endpoint's
valid field set, when included). Both were previously reachable only by
digging through.response_data. (#45)
Changed
- The CI conformance job (
lint.yml) now runs unconditionally against the
vendored contract instead of silently skipping when
TANGO_API_REPO_ACCESS_TOKENis absent; the token is only used for a
best-effort staleness notice comparing the vendored contract to tango HEAD.
scripts/pr_review.pylikewise defaults its conformance step to the
vendored contract (override withTANGO_CONTRACT_MANIFEST). - 400 error messages now name the rejected field(s) and reason when the API
returns structuredissues— e.g.
Invalid request parameters: Invalid shape: tradeoff_process (unknown_field)
instead of justInvalid request parameters: Invalid shape. (#45)
Fixed
docs/WEBHOOKS.mdlisted only five of the eight webhook alert types. It
was missingalerts.exclusion.match,alerts.dibbs_rfq.match, and
alerts.dibbs_rfp.match. No SDK change was needed — event types are served by
the API and never hardcoded, so the new types already worked — but the
hand-written list had gone stale. Also documents two things that surprise
people: DIBBS awards are not alertable, and nothing fires when a record
merely lapses (an exclusion hitting its termination date, or an RFQ/RFP
passing its close date, emits no event). A production smoke test now asserts
every live event type appears in the doc, so the list cannot silently fall
behind again.- Refreshed the vendored API contract, which had gone stale by seven
resources. It tracked 25 resources against Tango's current 32, so the
conformance and coverage checks were validating against out-of-date truth and
could not see DIBBS, exclusions, SBIR, orbudget/accountsat all. Refreshing
it also surfaced 72 additional fields on existing resources, now covered.
Nested routes are keyed with a slash (budget/accounts), which silently broke
the oldbudget_accountsmapping — both keys are now accepted. check_filter_shape_conformance.pyno longer reports false stale params.
It resolved SDK arguments to API params only through an explicit
api_param_mappingdict, so methods that express the translation as tuple
tables —("account_title__icontains", account_title)and
range_filters = (("apportioned", apportioned, apportioned_gte, ...))— looked
like they exposed dozens of params the API rejects. They do not:
list_budget_accountscorrectly sendsapportioned__gte,fiscal_year__lte,
andaccount_title__icontains. The checker now understands both tuple forms
(inAssign,AnnAssign, and inlineforiterables), with an explicit
api_param_mappingstill taking precedence. This letbudget/accountsbe
conformance-checked for the first time; its genuinely missing lookup variants
(agency_code__in,bureau_name__icontains, …) are now baselined.
v1.2.0
Added
list_budget_accounts()now exposes the full range-filter surface that the REST endpoint has always supported. Every numeric metric on/api/budget/accounts/— the 26 fields in the backend'sRANGE_NUMERIC_FIELDSlist (enacted_ba,apportioned,obligated_total,unobligated_balance,contract_obligated,contract_share_of_obligated_capped,ba_growth_next_year_pct,actual_vs_requested_contract, all the ratio fields and their_cappedvariants, etc.) — is now accepted in three forms: exact match (field=), greater-or-equal (field_gte=), and less-or-equal (field_lte=). Previously only the identity / taxonomy filters were exposed, which forced callers to discover accounts by exact symbol lookup; the new surface makes pipeline-style queries (e.g. "all FY24 accounts where contract share ≥ 60%, unobligated balance ≥ $200M, and next-year growth ≥ 15%, sorted by largest headroom first") a single SDK call. The new params map to the API'sfield__gte/field__lteform;ordering=already accepted any of these fields and continues to.
Full changelog: https://github.com/makegov/tango-python/blob/v1.2.0/CHANGELOG.md
v1.1.3
Added
- Reference-data list/get methods now accept
shape(and the associated
flat/flat_lists) parameters, matching the underlying API which has
always supported the shape system viaShapeOnDemandMixin. Affected:
list_naics/get_naics,list_psc/get_psc,
list_assistance_listings/get_assistance_listing,
list_business_types/get_business_type,
list_mas_sins/get_mas_sin. Whenshapeis omitted, behavior is
unchanged — the API applies its own per-resource default.
list_business_typesreturns raw dicts (instead ofBusinessType
instances) when ashapeis supplied so the caller gets exactly the
shape requested.
v1.1.2
Changed
get_entity_budget_flows()now exposes the backend's standard page/limit pagination andfiscal_yearfilter, and returnsPaginatedResponse[dict[str, Any]]instead of a raw dict. The backend has always paginated this endpoint viaStandardResultsSetPagination; the previous signature gave callers no way to reach pages beyond the first or to narrow by fiscal year. Callers that were indexingresult["results"]on the old return value should switch toresult.results(and can now useresult.next/page=to walk further pages).- Completed the strict-
mypyburn-down acrosstango/shapes/(parser, generator, factory, schema). All changes are type-annotation/typing corrections with no runtime behavior change, except:FieldSchema.nested_modelis now typedtype | str | None(it always accepted string model names from the explicit schemas; the annotation was wrong).ModelFactory.validate_dataandShapeParser._validate_field_speclikewise accepttype | strfor the model argument.- Removed two dead
elif field_spec.is_wildcard:branches (inTypeGenerator.generate_typeandModelFactory.create_instance) and the now-orphaned_parse_nested_wildcardhelper. These were unreachable — wildcard field specs are fully handled by the top-of-loop branch thatcontinues before reaching them — so removal is behavior-preserving.
Docs
docs/API_REFERENCE.mdnow documents the Budget surface that shipped in v1.1.0: a new## Budgetsection coveringlist_budget_accounts,get_budget_account,get_budget_account_quarters, andget_budget_account_recipients; aget_entity_budget_flows()entry under Entity Sub-resources; aBUDGET_ACCOUNTS_MINIMALrow in the ShapeConfig table; and a Budget entry in the table of contents.
CI
- Bumped GitHub Actions off the deprecated Node 20 runtime (forced off 2026-06-02):
actions/checkoutv4→v6,astral-sh/setup-uvv4→v8.1.0 (pinned exact — no floatingv8major tag is published yet), andcodecov/codecov-actionv3→v5 (with the renamedfiles:input). mypyis now a hard gate inlint.yml(no longer advisory). Thetango/package type-checks cleanly under strict mypy.
Full Changelog: v1.1.1...v1.1.2
v1.1.1
Removed
- The
notebooksoptional extra (jupyter,ipykernel). It only powered local
editing ofdocs/quick_start.ipynb, which still renders on GitHub/PyPI without
it, and its transitive tree (jupyter-server, jupyterlab, nbconvert, tornado,
etc.) accounted for the bulk of the repo's open Dependabot alerts. Contributors
who want to re-run the notebook canpip install jupyterdirectly. The shipped
SDK is unaffected — its only runtime dependency remainshttpx.
Changed
- Refreshed the dev/test dependency lock to clear the remaining Dependabot
alerts (patchedidna,pygments,pytest,python-dotenv; dropped
urllib3/requeststransitives). Dev-tool majors moved forward
(mypy1.18→2.1,pytest8→9,ruff0.14→0.15,vcrpy7→8); all lint,
type, and test gates stay green. No change to the shipped SDK's runtime deps.
v1.1.0
Fixed
_parse_webhook_alert: aligned the parser output with theWebhookAlert
type contract. Sparse server payloads now hydratequery_typeandfilters
as""/{}(matching their declared non-null types) rather thanNone,
andstatusis typed as theLiteral["active", "paused"]the model promises.
Clears the four type-check errors this introduced; no change for full payloads.Contractmodel: removed dead fields (id,award_id,recipient_name,
award_amount,awarding_agency,funding_agency) and added the real API
fields (key,piid,obligated,total_contract_value,
base_and_exercised_options_value,awarding_office,funding_office,
naics_code,psc_code,set_aside,solicitation_identifier,
parent_award,legislative_mandates,subawards_summary,
place_of_performance). The deprecated fields remain declared withNone
defaults for one minor cycle (they never returned data) and will be removed
in2.0.0. NewOrganizationOfficePayloaddataclass for the office fields.
(Contractis a documentation-only dataclass — not instantiated or exported
— so there is no runtime impact.)list_contracts: no longer sendspage=1to the cursor-only/api/contracts/
endpoint. When no cursor is supplied, neitherpagenorcursoris sent and
the API returns the first page by default.- Shape validation: registered the
ContractOrIDVCompetitionnested schema
(alias ofCompetition) so nested selections like
competition(extent_competed,number_of_offers_received)on contract / IDV
shapes validate instead of raisingShapeValidationError.
Added
- Budget accounts surface (tango v4.6.8):
list_budget_accounts,
get_budget_account,get_budget_account_quarters,
get_budget_account_recipients. NewBudgetAccountdataclass exported from
the top-level package, plusShapeConfig.BUDGET_ACCOUNTS_MINIMAL. - Singleton detail GETs:
get_contract,get_contract_subawards,
get_contract_transactions,get_forecast,get_grant,get_notice,
get_opportunity,get_subaward. get_entity_budget_flows(uei)for/api/entities/{uei}/budget-flows/.list_otidv_awards(key)for/api/otidvs/{key}/awards/(parity with Node).grant_idfilter kwarg onlist_grants(supports multi-value OR via|).
CI
- Re-enabled
lint.ymlas a PR + push-to-main gate.ruff formatand
ruff checkare hard gates;mypyruns advisory (continue-on-error) pending
burn-down of ~28 pre-existing type errors. The filter/shape conformance check
is a separate job that skips cleanly until aTANGO_API_REPO_ACCESS_TOKEN
secret for the private manifest repo is configured, at which point it becomes
a hard gate.
v1.0.0
First stable release.
tango-pythonis now at full API parity with the
Tango HTTP surface, the legacy subject-based webhook subscription
mechanism has been removed in favor of filter alerts, the shape parser
agrees byte-for-byte with the server's expand-alias handling, and the
SDK's docs are auto-published todocs.makegov.com/sdks/python/via the
composer pipeline (makegov/docs#15 / makegov/docs#16). From1.xon,
we'll only do breaking changes on a major bump.Originally tracked as: API parity (PR #25), subject-based webhook
removal (PR #27 / issue #2275), shape-validator alias support (PR #28 /
issue #2266), and the docs-only content port (makegov/docs#16).
Added
orderingparameter onlist_forecasts,list_grants,list_subawards,list_gsa_elibrary_contracts, andlist_opportunities. Prefix with-for descending. Closes a parity gap with the API surface (these endpoints all accept?ordering=server-side).create_webhook_endpointacceptsname=(keyword-only) and now requires it. The Tango API enforces unique(user, name)on endpoints; omittingnamereturns a 400 server-side, so the SDK raisesTangoValidationErrorclient-side instead of round-tripping. (0.7.0 — never publicly released — emitted aDeprecationWarninginstead.)update_webhook_endpointacceptsname=for renaming an endpoint.- Webhook alerts (filter subscriptions):
list_webhook_alerts,get_webhook_alert,create_webhook_alert,update_webhook_alert,delete_webhook_alert— the canonical write surface over/api/webhooks/alerts/. NewWebhookAlertdataclass exported from the top-level package. resolve(name, target_type, ...)— POST/api/resolve/to rank entity / organization candidates from a free-text name. ReturnsResolveResultwithResolveCandidateentries (both exported).validate(identifier_type, value)— POST/api/validate/to validate the format of a PIID, solicitation number, or UEI. ReturnsValidateResult(exported).- Reference data:
list_departments,get_department,list_psc,get_psc,get_psc_metrics,get_naics,get_naics_metrics,get_business_type,list_assistance_listings,get_assistance_listing,list_mas_sins,get_mas_sin. - Entity sub-resources:
list_entity_contracts,list_entity_idvs,list_entity_otas,list_entity_otidvs,list_entity_subawards,list_entity_lcats,get_entity_metrics. All shape-aware where the underlying endpoint supports shaping. - IDV sub-resources:
list_idv_lcats. - Agency sub-resources:
list_agency_awarding_contracts,list_agency_funding_contracts. - Misc:
search_opportunity_attachments(q, top_k, include_extracted_text)for/api/opportunities/attachment-search/;get_version()for/api/version/;list_api_keys()for/api/api-keys/.
Changed
create_webhook_alertacceptsendpoint=(keyword-only). Required for accounts with multiple webhook endpoints; auto-resolves for single-endpoint accounts. Closes the multi-endpoint smoke-test gap (tango#2256).test_webhook_deliverynow sends the canonicalendpointbody key instead of the deprecatedendpoint_idalias (tango#2252). The Python kwarg name staysendpoint_id=for backwards compatibility; the wire payload is what changed.generate_signature(body, secret)now returns the full wire form"sha256=<hex>"instead of bare hex. Callers can assign the return value directly to theX-Tango-Signatureheader without wrapping in a format string. This is a breaking change for code that relied on the bare-hex return; pass it throughparse_signature_header()to recover the previous form.verify_signatureaccepts both prefixed and bare-hex inputs (unchanged), so receivers continue to work either way.
Removed
- Subject-based webhook subscription surface (tango#2275). Migrate to
create_webhook_alert(...)and the alerts API.- Methods:
list_webhook_subscriptions,get_webhook_subscription,create_webhook_subscription,update_webhook_subscription,delete_webhook_subscription. - Dataclasses:
WebhookSubscription,WebhookSubjectTypeDefinition. Both are no longer exported from the top-leveltangopackage — importing them raisesImportError. - Fields:
default_subject_typeremoved fromWebhookEventType;subject_typesandsubject_type_definitionsremoved fromWebhookEventTypesResponse. The server's/api/webhooks/event-types/response no longer carries these. - CLI: the entire
tango webhooks subscriptionsClick subgroup (list/get/create/delete). Use the SDK'sclient.create_webhook_alert(...)etc. directly — there is no CLI subgroup for alerts.
- Methods:
orderingkwarg fromlist_noticesandlist_protests. The notices and protests viewsets reject every?ordering=value at runtime (tango#2254); the kwarg silently sent unsupported values. Other five list methods retainordering.
Fixed
TangoClient._post()and_patch()accept bothjson_data=(positional) andjson=(keyword) for backward compatibility. Internal callers and docs examples that usejson=no longer fail withTypeError. Passing both now raisesTangoValidationErrorrather than silently preferring one — that ambiguity would hide caller bugs.get_psc_metrics/get_naics_metrics/get_entity_metricsdocstrings —period_groupingvalues are"month"/"quarter"/"year"(the path-segment values the API accepts), not"monthly"/"quarterly".docs/API_REFERENCE.md#get_agency— example usesclient.get_agency("GSA")consistently and notes the parameter accepts CGAC / FPDS / short code / abbreviation / canonical name.README.mdQuick Start —get_agency()returns anAgencydataclass, so the example uses attribute access (agency.name) instead ofagency['name']which wouldTypeError.scripts/smoke_api_parity.py—list_business_types(limit=1)is now wrapped in therun(...)helper so a failure on that call records FAIL instead of aborting the smoke run.tango webhooks endpoints createCLI now accepts and requires--name(passed through tocreate_webhook_endpoint(name=...)). Previously the option was absent, meaning the CLI could never set a custom endpoint name and every call would 400 server-side (the server enforcesunique(user, name)).WebhookAlert.query_typeandWebhookAlert.filterstightened fromOptionalto non-optional (stranddict[str, Any]respectively). Legacy nullable rows were purged by the tango#2275 migration; the server model and serializer guarantee non-null values for all current data.WebhookAlert.statusnarrowed fromstrtoLiteral["active", "paused"]— the server serializer produces exactly those two values.- Shape validator agrees with server on
naics(...)/psc(...)expansions. The client-sideShapeParser.validate()previously rejected the canonicalshape=naics(code,description)form (which the server has always accepted) and also rejected the aliasshape=naics_code(code,description). The parser now mirrors the server's_EXPAND_ALIASES(introduced in Tango PR makegov/tango#2259) and rewritesnaics_code(...)/psc_code(...)to their canonicalnaics(...)/psc(...)form at parse time. Bare scalar leaves (shape=naics_code/shape=psc_code) are left untouched and still return the raw column value, matching the server. Schemas forContract,Forecast,Opportunity,Notice, andVehiclegained explicitnaics/pscexpand entries backed by the existingCodeDescriptionnested model. Fixes makegov/tango#2266. Subawardschema matches the server'sSubawardSerializer. The previousSUBAWARD_SCHEMAdeclared two fields the server has never exposed (id,amount) and was missing every real field on the resource — includingpiid,key,awarding_office/funding_office/place_of_performance/subaward_details/fsrs_details/highly_compensated_officers/usaspending_permalink, and the denormalizedprime_awardee_*/recipient_*lookup columns. Shape strings that referenced any real field (e.g.shape="piid") would fail client-side validation withunknown_field, and conversely the SDK happily passedshape="id"/shape="amount"through to the server, where they were rejected.SUBAWARD_SCHEMAis now derived directly fromawards.serializers.subawards.SubawardSerializerand the resource's runtimeavailable_fields. TheSubawarddataclass intango/models.pywas updated to match. New nested schemasSubawardDetails,FsrsDetails,SubawardPlaceOfPerformance, andHighlyCompensatedOfficerare registered so the corresponding shape expansions validate end-to-end.
Documentation
- New
docs/ERRORS.md— full exception hierarchy, recovery patterns, and the shape-error classes (ShapeValidationError,ShapeParseError,TypeGenerationError,ModelInstantiationError). Ported fromdocs.makegov.com/sdks/python/errors.mdahead of the docs-site auto-pull cutover (makegov/docs#15 / makegov/docs#16). - New
docs/PAGINATION.md— page-based vs cursor-based strategies, iteration patterns, and thePaginatedResponsefield reference. Ported fromdocs.makegov.com/sdks/python/pagination.md. - New
docs/CLIENT.md—TangoClientconstructor reference,rate_limit_info/last_response_headersproperties, and retry-semantics note (the SDK has no built-in retry). Ported fromdocs.makegov.com/sdks/python/client.md.
CI
- New
.github/workflows/docs-dispatch.yml— fires on push tomainwhendocs/**,README.md, orCHANGELOG.mdchanges and dispatchesexternal_updatedatmakegov/docsso the public docs site rebuilds with the latest SDK content. Required for the makegov/docs#15 auto-pull pipeline.
v0.3.0
Added
- Vehicles endpoints:
list_vehicles,get_vehicle,list_vehicle_awardees - IDV endpoints:
list_idvs,get_idv,list_idv_awards,list_idv_child_idvs,list_idv_transactions,get_idv_summary,list_idv_summary_awards - Webhooks v2 client support: event type discovery, subscription CRUD, endpoint management, test delivery, sample payload helpers
Changed
- Expanded explicit schemas to support common IDV shaping expansions
- HTTP client now supports PATCH/DELETE helpers for webhook management endpoints
v0.2.0 (2025-11-17)
🎉 The gritty reboot of a Tango SDK!