datacrop — official Python client
Typed, httpx-based client for the DataCrop US-ag data
API (api.datacrop.dev). Auth is Bearer-only — there is no keyless data route.
pip install datacrop # httpx only
pip install "datacrop[pandas]" # + pandas for series_to_pandas
Quickstart (free tier)
The free tier covers corn, wheat and soybean at 500 requests/day
(keys created before 2026-08-20 keep their original 2,000/day — check
grandfathered on /v1/me).
from datacrop import DataCrop
client = DataCrop(api_key="dc_...")
# Price series with provenance on every row
corn = client.series("corn", start_date="2026-06-01")
for row in corn.series[:3]:
print(row.date, row.value, row.unit, "←", row.source, row.source_ref)
print(corn.license.attribution) # who to credit for these rows
# Which identifiers exist, and which is the curated primary
ids = client.identifiers("wheat")
# Straight to pandas via the CSV endpoint
df = client.series_to_pandas("corn")
print(df.attrs["datacrop"]) # pagination/freshness/attribution headers
# Quota awareness (X-RateLimit-* headers; None on unlimited tiers)
print(client.quota) # Quota(limit=500, remaining=..., reset=...)
The warning gate (implemented, currently dormant server-side)
GET /v1/series returns 422 when the catalog documents that pooling the
series you asked for is structurally misleading. The client raises
WarningGateError with each warning's stable id, and acknowledged_retry()
re-issues the request acknowledging those specific ids — never the blanket
acknowledge_warnings=true, which would also wave through any future
critical warning without a human reading it.
Stated plainly, because you can test it: as of 2026-08-20 no production
series populates a critical relational caveat, so this gate will not fire on
any request you make today. The contract exists client-side so that when a
caveat does land in the catalog, your pipeline reads it before affirming it —
rather than discovering a breaking 422 in production. Non-critical warnings
already ride along on every response as warnings[], each with a stable id.
Surface
| Method | Endpoint | Tier |
|---|---|---|
series / iter_series / series_to_pandas |
GET /v1/series |
all |
identifiers |
GET /v1/identifiers |
all |
freshness |
GET /v1/freshness/{commodity} |
all |
lineage |
GET /v1/lineage |
all |
license |
GET /v1/license |
all |
catalog |
GET /v1/catalog |
all |
forecasts |
GET /v1/forecasts |
Pro+ |
basis |
GET /v1/basis |
Pro+ |
revisions |
GET /v1/revisions |
Pro+ |
fundamentals |
GET /v1/fundamentals |
Pro+ |
positioning |
GET /v1/positioning |
Pro+ |
energy |
GET /v1/energy |
Pro+ |
exports |
GET /v1/exports |
Pro+ |
weather_events |
GET /v1/weather-events |
Pro+ |
Responses are dataclasses mirroring the API's field names exactly (see
api/API.md). Rows keep source / source_ref (or the endpoint's
source-native series_ref, aliased as .source_ref), and every top-level
response exposes .license — None where the endpoint's payload carries no
licence block, in which case client.license() returns the full manifest.
Other honesty surfaces worth reading before you model:
ForecastsResponse.point_published (False ⇒ P50 is the band median, not a
call), RevisionsResponse.coverage.tracking_since (absence before that date
means "not observed", not "not revised"), and FundamentalsRow.derived
(DataCrop-computed rows carry their formula).
Rate limits
client.quota reflects the last response's X-RateLimit-* headers; unlimited
tiers send none, so it stays None for them. On 429 the client raises
RateLimitError (with resets_at) by default; construct with
DataCrop(api_key=..., wait_on_limit=True) to sleep until the UTC-midnight
reset and retry once instead.
Data sources and licensing
DataCrop serves public agricultural data from USDA AMS Market News, USDA NASS
QuickStats, and FRED, normalized with per-row provenance. Per-source licence
and redistribution terms are served with the data itself — GET /v1/license
returns the manifest for exactly the sources present in your response, and
every response exposes it as .license.
This product uses the FRED® API but is not endorsed or certified by the Federal Reserve Bank of St. Louis. This product uses the NASS API but is not endorsed or certified by NASS.
Running the tests
All tests run against a mocked httpx transport — no network, no API key.
# from clients/python/ (bash)
PYTHONPATH=. python -m pytest tests -q
# or, after `pip install -e clients/python[test]`, from anywhere:
python -m pytest clients/python/tests -q
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file datacrop-0.1.0.tar.gz.
File metadata
- Download URL: datacrop-0.1.0.tar.gz
- Upload date:
- Size: 20.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
725bd1705f4abd337156da2364ed5bcaf90ef0b2fa74756afa750defade85cb9
|
|
| MD5 |
19dc2686752385b6884c67d3feaa09f3
|
|
| BLAKE2b-256 |
9fa4e82ea670dfd3eeac339af8b41f603e97d84eed032f7806de1e9d6bd83375
|
File details
Details for the file datacrop-0.1.0-py3-none-any.whl.
File metadata
- Download URL: datacrop-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f9ae506aa69d3a26c4b66abf50d5eecb000dc291af34dcebaaf8625b0178d88
|
|
| MD5 |
43b7f0eaedbc41ab6f1ec5b04a38d6fd
|
|
| BLAKE2b-256 |
bbba0a336d70708770841719b0606e632de4e97440d463277b7cd8e3bd19ca47
|