Thermograph monorepo: graded-climate API + SSR frontend + infra, domain-specific containerized deploys
Find a file
Emi Griffith c3bacdce0c Migrate backend dataframe layer from pandas to polars (#90)
* Migrate backend dataframe layer from pandas to polars

Replace pandas with polars across the backend, dropping both pandas and its
pyarrow parquet engine from the dependency set. numpy stays (the grading
percentile math is unchanged).

- climate.py: parquet IO, source→frame mappings, cache read/topup on polars.
  New _normalize_read casts the cached `date` column to pl.Date (older files
  were written by pandas as datetime64[ns]); frames now unify missing values as
  null so the grading boundary drops them consistently across sources.
- grading.py: keep the numpy percentile core; swap the frame→numpy bridge to
  .to_numpy()/.drop_nulls(), day-of-year/year to polars dt expressions, and the
  per-row loop to iter_rows(named=True).
- views.py: filter/anti-join/concat replace boolean-mask, isin and pd.concat;
  scalar dates are stdlib datetime.date; a local _months_before helper replaces
  DateOffset(months=) for the calendar-range default.
- app.py, migrate.py: request-date parsing uses datetime.date, removing pandas
  from the endpoint and migrate layers entirely.
- The date column is pl.Date end to end, eliminating the pandas normalize() calls
  and comparing cleanly against stdlib dates.

Payloads are unchanged: calendar, day, grade and forecast responses are
byte-for-byte identical to the pandas implementation on the same cached record.

Tests ported to polars fixtures, with added coverage for the combined feels-like
fallback, calendar month-offset (month-end/leap), and the concat/dedup
"fresher source wins" rule.

* Port notify.py to polars after merging dev's account system

Merge origin/dev (accounts + notification subscriptions) and carry the pandas→
polars migration into the newly added notify.py, which the merge brought in still
using pandas — with pandas removed from requirements this broke its import.

- notify.py: _candidate_rows filters/sorts the recent bundle with polars
  expressions and returns iter_rows dicts; date scalars are datetime.date;
  history/recent emptiness via is_empty().
- test_notify.py: synthetic history/rows built with polars + datetime.
2026-07-15 19:07:38 +00:00
tests Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
api_accounts.py Account system with weather-notification subscriptions (#89) 2026-07-15 18:46:46 +00:00
app.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
audit.py Initial commit: app + 2026-07-10 17:29:47 -07:00
climate.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
db.py Account system with weather-notification subscriptions (#89) 2026-07-15 18:46:46 +00:00
grading.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
grid.py Warm neighbor cells server-side (/cell?neighbors=1) (#51) 2026-07-11 20:47:31 +00:00
migrate.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
models.py Account system with weather-notification subscriptions (#89) 2026-07-15 18:46:46 +00:00
notify.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
places.py Move the suggestion policy into places.py (#45) 2026-07-11 20:00:24 +00:00
requirements-dev.txt Add backend test suite; gate direct pushes; serialize LAN deploys (#41) 2026-07-11 19:37:49 +00:00
requirements.txt Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00
schemas.py Account system with weather-notification subscriptions (#89) 2026-07-15 18:46:46 +00:00
store.py Compare/calendar mobile polish: overflow fix, sheet load button, 6-yr default, country in names (#80) 2026-07-12 06:32:10 +00:00
users.py Account system with weather-notification subscriptions (#89) 2026-07-15 18:46:46 +00:00
views.py Migrate backend dataframe layer from pandas to polars (#90) 2026-07-15 19:07:38 +00:00