Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3bd9bf38ee | |||
| 831c3e19de |
@@ -83,7 +83,7 @@ auto-updates it every 5 minutes.
|
||||
| `price_series(commodity, geo?, start_year?, end_year?)` | Raw monthly price-received series for charting |
|
||||
| `input_cost_trend(item, geo?, years?)` | Real input cost + change. `item` = `diesel` (U.S. `$/gal`, weekly, EIA) or a fertilizer `$/ton` (`urea`/`uan`/`anhydrous`/`dap`/`map`/`potash`, monthly, USDA AgTransport); `geo` selects the fertilizer region (default `Cornbelt`) |
|
||||
| `input_cost_series(item, geo?)` | Raw historical series for an input cost (diesel `$/gal` or fertilizer `$/ton`, region-selectable) |
|
||||
| `latest_prices(commodity?, source?, delivery?, kind?, zip?, lat?, lng?, radius_miles?)` | Live snapshot table; every filter optional (`kind` = `grain`/`fertilizer`). Location filter (zip **or** lat/lng + `radius_miles`) keeps nearby sources, nearest-first, with distance |
|
||||
| `latest_prices(commodity?, source?, delivery?, kind?, zip?, lat?, lng?, radius_miles?, include_expired?)` | Live snapshot table; every filter optional (`kind` = `grain`/`fertilizer`). Current + future delivery months only by default; pass `include_expired=true` for past months (use only on an explicit historical request). Location filter (zip **or** lat/lng + `radius_miles`) keeps nearby sources, nearest-first, with distance |
|
||||
| `price_history(commodity?, source?, delivery?, days?)` | Time series per (elevator, crop, delivery); **every filter optional** — omit `commodity` to span all crops. Shows bid + basis trend + futures |
|
||||
| `basis_movement(commodity?, source?, delivery?, days?)` | Aggregated basis trend, one headline line per crop (the cheap overview) |
|
||||
| `basis_detail(commodity?, source?, delivery?, days?)` | Per-(elevator, crop, delivery) basis first→last drill-down |
|
||||
|
||||
@@ -56,10 +56,14 @@ def _get(path: str, **params: Any) -> dict | list:
|
||||
def latest(commodity: str | None = None, source: str | None = None,
|
||||
delivery: str | None = None, kind: str | None = None,
|
||||
zip: str | None = None, lat: float | None = None,
|
||||
lng: float | None = None, radius_miles: float | None = None) -> dict:
|
||||
lng: float | None = None, radius_miles: float | None = None,
|
||||
include_expired: bool = False) -> dict:
|
||||
# Only send include_expired when True — _get drops None, so the default
|
||||
# call keeps its existing query string (current + future months only).
|
||||
return _get("/api/data/latest",
|
||||
commodity=commodity, source=source, delivery=delivery, kind=kind,
|
||||
zip=zip, lat=lat, lng=lng, radius_miles=radius_miles)
|
||||
zip=zip, lat=lat, lng=lng, radius_miles=radius_miles,
|
||||
include_expired=True if include_expired else None)
|
||||
|
||||
|
||||
def history(commodity: str | None = None, source_id: int | None = None,
|
||||
|
||||
+12
-2
@@ -176,13 +176,22 @@ def latest_prices(
|
||||
Field(description="Search radius in miles around the location (default 50). "
|
||||
"Ignored unless a ZIP or lat/lng is given."),
|
||||
] = None,
|
||||
include_expired: Annotated[
|
||||
bool,
|
||||
Field(description="Include past/expired delivery months. Default off — only "
|
||||
"the current and future months are shown. Set true only when "
|
||||
"the farmer explicitly asks for historical/past delivery data."),
|
||||
] = False,
|
||||
) -> str:
|
||||
"""Snapshot of the latest scraped bid per (source, commodity, delivery).
|
||||
|
||||
Every filter is optional and AND'd together — pivot by elevator, crop,
|
||||
delivery, or kind in any combination. Pass a `zip` (or `lat`+`lng`) with
|
||||
optional `radius_miles` to keep only elevators near the farmer, sorted
|
||||
nearest-first with the distance shown."""
|
||||
nearest-first with the distance shown.
|
||||
|
||||
By default this shows current + future delivery months only; expired
|
||||
months are rolled off. Set `include_expired=true` for a historical view."""
|
||||
cm = commodity.strip().lower() if commodity else None
|
||||
with track("latest_prices", commodity=cm, source=source, delivery=delivery, kind=kind,
|
||||
zip=zip or "", radius=radius_miles or 0):
|
||||
@@ -190,7 +199,8 @@ def latest_prices(
|
||||
if err:
|
||||
return err
|
||||
payload = client.latest(commodity=cm, source=source, delivery=delivery, kind=kind,
|
||||
zip=zip, lat=lat, lng=lng, radius_miles=radius_miles)
|
||||
zip=zip, lat=lat, lng=lng, radius_miles=radius_miles,
|
||||
include_expired=include_expired)
|
||||
return fmt.fmt_latest(payload)
|
||||
|
||||
|
||||
|
||||
@@ -71,6 +71,30 @@ def test_get_drops_none_params(monkeypatch):
|
||||
assert captured["params"] == {"commodity": "corn"}
|
||||
|
||||
|
||||
def test_latest_include_expired_passthrough(monkeypatch):
|
||||
client = _reload_client(monkeypatch)
|
||||
captured = {}
|
||||
|
||||
class FakeResp:
|
||||
status_code = 200
|
||||
text = ""
|
||||
def json(self): return {"count": 0, "rows": []}
|
||||
|
||||
def fake_get(url, params=None, timeout=None, headers=None):
|
||||
captured["params"] = dict(params or {})
|
||||
return FakeResp()
|
||||
|
||||
monkeypatch.setattr(client.httpx, "get", fake_get)
|
||||
|
||||
# Default: not sent, so the API applies its current+future filter.
|
||||
client.latest(commodity="corn")
|
||||
assert "include_expired" not in captured["params"]
|
||||
|
||||
# Opt in: forwarded so the API returns expired months too.
|
||||
client.latest(commodity="corn", include_expired=True)
|
||||
assert captured["params"] == {"commodity": "corn", "include_expired": True}
|
||||
|
||||
|
||||
def test_futures_endpoint_params(monkeypatch):
|
||||
client = _reload_client(monkeypatch)
|
||||
captured = {}
|
||||
|
||||
Reference in New Issue
Block a user