Personal fork of python-metar/python-metar with pilot-friendly extensions and Slack-bot scaffolding.
The upstream parser is unchanged in spirit — it still decodes METAR/SPECI weather reports. This fork adds:
- Flight category classifier — VFR / MVFR / IFR / LIFR per FAA thresholds
- Plain-English output layer — human-readable summary for non-pilots
- Crosswind / headwind helper — pure math for runway planning
- Expanded remarks coverage —
TSNO,PWINO,FZRANO,RVRNO,$,VIRGA,FROPA,PRESRR,PRESFR, variable ceiling, variable visibility, surface and tower visibility - Slack-bot scaffolding — fetch / airports / Block Kit formatter / AWS Lambda handler
The historical from metar import Metar and from metar import Station imports still work via aliases in metar/__init__.py.
from metar.parser import Metar
from metar.airports import lookup
from metar.format import to_plain_english
m = Metar("METAR KOAK 050153Z 26008KT 10SM CLR 17/11 A2989 RMK AO2 SLP121")
print(m.flight_category()) # VFR
print(m.ceiling()) # None (CLR = no ceiling)
print(to_plain_english(m, station_name=lookup("KOAK").name))🟢 VFR | KOAK — Oakland Int'l | observed 01:53Z
Winds west at 8 knots. Visibility 10 miles. Clear skies, no ceiling.
Temperature 63°F (17°C), dewpoint 51°F (11°C), humidity 65%.
Altimeter 29.89 inHg. Sea level pressure 1012.1 hPa.
Station is automated (AO2).
End goal is a Lambda-backed /metar KOAK slash command. The pieces:
from metar.fetch import fetch_metar
from metar.slack import to_slack_blocks
from metar.airports import lookup
m = fetch_metar("KOAK")
payload = to_slack_blocks(m, station_name=lookup("KOAK").name)
# payload is now a dict; json.dumps() it into a Slack response body.lambda_handler.py ties this to API Gateway + Slack signature verification. Set SLACK_SIGNING_SECRET in the Lambda environment before deploying.
python3 -m venv .venv
.venv/bin/pip install -e .[tests]
.venv/bin/python -m pytest -qCurrently 147 tests, all passing.
BSD 2-Clause, inherited from upstream. See LICENSE.
