Why I built it
Feed that to an LLM and you get creative confabulation. The Q-code alone encodes five dimensions — FIR, subject, condition, traffic, purpose, scope — and there are 400+ valid subject/condition combinations in FAA Order 7930.2 Appendix B. Aviation adds ~300 further abbreviations (RWY, TWY, APCH, WEF, UFN) that the model will guess at.
The model doesn't need to learn Q-codes. The FAA already wrote the rulebook.
How it works
- Full Q-code lookup covering every subject and condition code in Appendix B.
- Abbreviation expansion dictionary (~300 terms), scoped so it doesn't mangle acronyms that also appear as words.
- Two parsers — ICAO format (the Q-code variant above) and FAA domestic format.
- Structured JSON output, so the decoder sits in front of any downstream LLM or API consumer.
Under the hood
Three core modules, no external dependencies:
parser.py— format-aware parser that extracts Q-code fields, times, locations, and the E-field body text.qcodes.py— lookup tables (subject codes, condition codes, traffic codes) as straightforward dicts.abbreviations.py— abbreviation expansion with contextual guards.
Plus a cli.py wrapper for standalone use. Public API: NOTAMParser, decode_qcode, expand_abbreviations_clean.
Where it stands
Shipping. Zero external dependencies — pure stdlib with a pytest suite. Integrated as a submodule inside Travel Alerts MCP, where it preprocesses FAA feeds before they reach the downstream LLM.