Skip to content

fix: NOAA SWPC 2026 format changes (SFI/Kp dict rows, RTSW endpoints, NUL bytes) - #5

Closed
AnsgarSchmidt wants to merge 1 commit into
qso-graph:mainfrom
AnsgarSchmidt:fix/noaa-2026-format
Closed

AnsgarSchmidt wants to merge 1 commit into
qso-graph:mainfrom
AnsgarSchmidt:fix/noaa-2026-format

Conversation

@AnsgarSchmidt

Copy link
Copy Markdown
Contributor

Summary

solar-mcp 0.2.1 breaks against the current NOAA SWPC endpoints (verified 2026-08-28 against live services.swpc.noaa.gov). This PR fixes all six data tools:

  • conditions() — products/summary/10cm-flux.json now returns a list of dicts ([{"flux": 122, "time_tag": "..."}], lowercase keys) instead of a single dict with Flux/TimeStamp. products/noaa-planetary-k-index.json now returns dict rows ({"time_tag", "Kp", ...}) instead of list rows. The parser now handles both old and new shapes (backward compatible).
  • solar_wind() — products/solar-wind/{mag,plasma}-5-minute.json are gone (HTTP 404). Switched to json/rtsw/rtsw_mag_1m.json and json/rtsw/rtsw_wind_1m.json (source is DSCOVR or ACE), parsing bz_gsm/bt and proton_density/proton_speed. Bz falls back to bz_gse when bz_gsm carries missing data.
  • _to_float() — new helper: NOAA's -9999 sentinel (and JSON null) become None instead of leaking bogus values into results.
  • _get_json() — strips trailing NUL bytes (\x00) that NOAA's file servers occasionally append (observed live on json/goes/primary/xrays-6-hour.json; broke xray() with a JSONDecodeError).

Testing

  • 55 unit/security tests pass — 7 new (SOLAR-L2-046..052) covering the 2026 formats plus legacy-format backward compatibility
  • 15 live integration tests pass against real NOAA endpoints (pytest tests/test_live.py --live)

Tested with Python 3.12, FastMCP 3.4.7.

- conditions(): handle 10cm-flux.json list-of-dicts and
  noaa-planetary-k-index.json dict rows (both shapes kept)
- solar_wind(): switch to json/rtsw/rtsw_{mag,wind}_1m.json,
  parse bz_gsm/bt and proton_density/proton_speed; bz falls
  back to bz_gse; -9999 sentinels become None via _to_float()
- _get_json(): strip trailing NUL bytes NOAA occasionally appends
- tests: SOLAR-L2-046..052 covering new + legacy formats
@bob-qg

bob-qg Bot commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

Thank you, @AnsgarSchmidt! Your fix shipped in solar-mcp 0.2.4 (https://pypi.org/project/solar-mcp/0.2.4/). Your commit is in main unchanged, merged through #9, and credited in the CHANGELOG.

It had conflicts with 0.2.3, which fixed SFI and Kp separately, so we resolved them in #9. We also added one change on top: the rtsw files list the newest rows first, with one row per spacecraft per minute, so solar_wind() now takes the newest reading from the active spacecraft rather than the last row, which was a day old.

73!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants