URL-based entity fetch¶
Load typed models from Congress.gov API URLs embedded in API responses (url fields, CountRef, and reference types).
A lot of Congress.gov responses are shallow on purpose — a bill's cosponsors, actions, or
related bills often come back as a count plus a URL rather than the full list. This module
gives those stubs a .fetch() method so you can turn "there are 14 cosponsors, here's the
URL" into an actual Cosponsors object without hand-building the request yourself.
Requirements¶
- URL must target
api.congress.govunder the/v3prefix (with or without scheme). - An
AuthenticatedClientmust be available viaclient=,self.client, or a parent collection’sclient. - Extensions register on import:
import congressgov.services.extensions(orfrom congressgov import Bill).
Core API¶
from congressgov.services.core.url_resolver import fetch_from_url
bill = fetch_from_url(
"https://api.congress.gov/v3/bill/119/hr/5054?format=json",
client=my_client,
)
Async:
from congressgov.services.core.url_resolver import fetch_from_url_async
bill = await fetch_from_url_async("/v3/bill/119/hr/5054", client=my_client)
Instance methods¶
| Type | Method | Notes |
|---|---|---|
URL, CountRef |
.fetch() |
Uses .url; on a Bill, updates the matching attribute (e.g. cosponsors) |
BillRef, MemberRef, AmendmentRef, … |
.fetch() |
Uses .url or ID fields |
SponsoredLegislationItem, CosponsoredLegislationItem |
.fetch() |
Bill or amendment URL/IDs → full model |
Sponsor, Cosponsor |
.fetch_member() |
Member detail URL (polymorphic return) |
Naming: get_*() vs .fetch()¶
get_*()/expand()— load a known sub-resource onto a parent entity (e.g.member.get_sponsored_legislation()→ list of stubs)..fetch()— resolve a stub, ref, or URL into a full model (e.g.item.fetch()→BillorAmendment).
Example (sponsored legislation):
member = Member(client).get(bioguide_id="A000374")
sponsored = member.get_sponsored_legislation() # list of stubs on the member
bill = sponsored.sponsoredLegislation[0].fetch() # stub → full Bill/Amendment
Same pattern elsewhere:
bill_ref.fetch() # BillRef → Bill
count_stub.fetch() # CountRef → Actions, Cosponsors, etc.
sponsor.fetch_member() # Sponsor → Member (named because return type differs)
On a bill detail, CountRef stubs are linked to the parent bill. Fetching a sub-resource stores the result on the bill and returns the same object:
bill = item.fetch(client=client)
cosponsors = bill.cosponsors.fetch(client=client, limit=250)
assert bill.cosponsors is cosponsors # Cosponsors(cosponsors=[...], pagination=...)
Use limit=250 (or paginate with offset) when the default page size (20) is not enough.
Skip-if-loaded and refresh¶
Extension fetch paths avoid duplicate HTTP when a parent entity already holds hydrated data:
Bill.get_*()helpers acceptrefresh=Trueto force a new request.Bill.expand()andApiServiceexpansion skip attributes that are already loaded unlessforce_fetch=Trueis passed in fetch options.CountRef.fetch()on a bill returns the stored collection when the parent field is hydrated; passforce_fetch=Trueto refetch.
URL fetch helpers accept the same flag:
bill = fetch_from_url(url, client=client, force_fetch=True)
cosponsors = bill.cosponsors.fetch(client=client, force_fetch=True, limit=250)
Deprecated: fetch_legislation() / fetch_legislation_async() on sponsorship items (use .fetch() / .fetch_async()).
Regenerating routes¶
Route table: src/congressgov/services/core/url_routes_generated.py
poetry run python -m codegen.scripts.generate_url_routes
# or
poetry run python -m codegen generate-url-routes
Source: codegen/config/legacy_client_aliases.yaml (sync with client get_* exports).
Errors¶
ValueError— non-API URL or missingurl/IDsUnsupportedApiUrlError— path not in route tableClientNotFoundError— no client resolved