A terminal-first weather console for PAGASA's official forecasts, typhoon bulletins, and advisory archive. It answers the practical questions the PAGASA site makes hard: what is the forecast for my town, which station is it really for, what is the storm doing now, and can I keep the official advisory for when the connection drops?
This is an unofficial tool, not affiliated with PAGASA. For emergencies, follow official PAGASA bulletins and local authorities.
uv sync
uv run pagasaThe pagasa command opens Today for the configured Home place. Python 3.12 or newer is
required; the project environment is managed with uv.
| Command | What it does |
|---|---|
uv run pagasa |
Open Today for Home. |
uv run pagasa --screen storm |
Open Storm, Search, Archive, or Today directly. |
uv run pagasa --offline |
Read only cached payloads and the local archive. No PAGASA request is made. |
uv run pagasa --refresh |
Fetch fresh PAGASA data once before opening the UI. A failed refresh is reported and cached data is still shown. |
uv run pagasa --version |
Print the installed package version. |
--screen accepts today, storm, search, and archive. The module form
python -m pagasa_console takes the same flags.
- Today: the selected place, its nearest PAGASA station and distance, the current observation, the next 12 hours from the WRF meteogram, the extended outlook, the official forecast text, active warnings, saved places, and a source and age rail.
- Storm: the active storm header, before/now/after timeline, forecast positions, local impact for saved places, and the bulletins, advisories, and warnings published for the storm.
- Search: local search over PAGASA's municipality and station index, with a preview of the nearest station and its latest observation.
- Archive: downloaded PDFs with issue time, type, storm, number, filename, status, SHA256, extracted text, and offline availability.
PAGASA HTTP
PagasaClient
|
+--> parsers: models.py, stations.py, discovery.py
|
+--> Cache (JSON payloads with fetched_at)
|
+--> WeatherService (freshness, cache fallback, snapshots)
|
+--> PagasaApp and Textual screens: today, storm, search, archive
|
+--> ArchiveService (PDF download, SHA256, extracted text)
cli.py builds the production graph: config, client, cache, archive, and service. The
screens render snapshots and emit actions; they do not fetch PAGASA on their own. A fake
service and fake archive keep the UI tests offline.
The app uses platformdirs and the application name pagasa-console.
- Config:
user_config_dir("pagasa-console")/config.toml(on Linux,~/.config/pagasa-console/config.toml) - Data:
user_data_dir("pagasa-console")/(on Linux,~/.local/share/pagasa-console/) - Payload cache:
cache/under the data directory - Archived PDFs and extracted text:
archive/ - Archive index:
archive.json
The first run writes the default config and never overwrites an existing one:
[places]
Home = "cainta"
[refresh]
minutes = 5
[archive]
keep_forecasts_days = 30Place values are PAGASA municipality or station identifiers. The config stores labels and identifiers, not coordinates that can drift.
The target layout is 120x35. The supported floor is 80x24: the side rails collapse, the
main content becomes one scrollable column, and the keybar keeps the essential bindings.
Wide tables scroll instead of silently clipping labels. NO_COLOR is honored.
| Key | Action |
|---|---|
1 |
Today |
2 |
Storm |
3 |
Search |
4 |
Archive |
/ |
Search |
d |
Fetch the selected document |
o |
Open a saved document |
a |
Save the selected document |
r |
Refresh PAGASA data |
s |
Sync the archive |
? |
Show the key map |
q |
Quit |
- Every weather value comes from PAGASA. The app does not generate forecasts, advice, rainfall, or safety recommendations.
- A forecast belongs to a station. The station name and distance from the selected town are always visible.
- AWS observations, human-issued bulletins, and WRF model output are labeled differently and carry their own time and age.
- Cached, stale, and offline data never look live. The shell says offline and shows the cache time. A failed refresh keeps the previous data with its true age.
- Missing is a visible state. No observation, no signal, no document, and no connection are shown explicitly; the app never substitutes a zero or a neighboring station.
- "No signal" is not converted into "safe". The app states the official signal status and points to the official bulletin.
- Archived PDFs are verified with SHA256. A partial or failed download stays missing.
- The footer always says the tool is unofficial and not affiliated with PAGASA.
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run mypy
uv buildThe default test suite does not touch the live network. A live marker is reserved for
opt-in network checks.
src/pagasa_console/ application package
tests/ unit, client, cache, service, and Textual tests
CONTEXT.md durable project knowledge
docs/spec.md product and technical design
docs/prototype/ frozen visual reference
docs/superpowers/ implementation plan
MIT. See LICENSE.