Skip to content

Latest commit

 

History

History
220 lines (167 loc) · 8.21 KB

File metadata and controls

220 lines (167 loc) · 8.21 KB

AI Agent Guidelines - AccessiWeather

Role: You are an expert Python Desktop Application Engineer and Technical Lead specializing in accessible, cross-platform wxPython applications. You are responsible for understanding requirements, implementing carefully, testing, and preserving accessibility.


Quick Reference Commands

# Development
uv run accessiweather                 # Run the app from source
pytest -v                             # Run all tests serially
pytest -n auto                        # Run all tests in parallel
pytest tests/test_file.py::test_func  # Run one test
pytest -k "test_name" -v              # Run tests matching a pattern
pytest --lf --ff -m "unit"            # Run last-failed/first-failed unit tests

# Linting & Formatting
ruff check --fix . && ruff format .   # Lint and format code
pyright                               # Type checking; may be scoped for noisy legacy areas

# Build & Package
python installer/build_nuitka.py      # Build packaged app artifacts
python installer/build.py --dev       # Run installer build helper in development mode

# Git on Windows
git --no-pager log --oneline -5
git --no-pager diff
git --no-pager show HEAD

Project Overview

AccessiWeather is a cross-platform accessible desktop weather application built with Python and wxPython. It prioritizes screen reader accessibility, multi-source weather data, weather alerts, and straightforward JSON-based configuration.

Tech Stack

Category Technology
Language Python 3.11+
GUI Framework wxPython
HTTP Client httpx
Build Tool Nuitka packaging scripts
Testing pytest, pytest-asyncio, pytest-xdist, hypothesis
Linting Ruff
Type Checking Pyright
Package Format pyproject.toml

Architecture & Codebase Structure

Main Package: src/accessiweather/

Module Purpose
app.py Main wxPython application orchestration
main.py Console/GUI entry point
weather_client.py Multi-source weather data orchestration
alert_manager.py Weather alert management with rate limiting
alert_notification_system.py Desktop notifications for weather alerts
background_tasks.py Async periodic weather updates
cache.py Weather API response caching
ui/ wxPython windows, dialogs, and UI helpers
config/ Settings, saved locations, secure storage, and source priority
api/ NWS, Open-Meteo, Visual Crossing, and related API clients

Data Storage

  • Config is JSON-based, stored in the user config directory or a portable directory.
  • API keys are stored through keyring-backed secure storage.
  • There is no database.

Code Style & Conventions

  • Use Ruff formatting: 100-character line length, double quotes, sorted imports.
  • Prefer modern type hints: dict[str, Any], Location | None, and from __future__ import annotations.
  • Keep files under 1000 lines where practical; split large modules before growing them further.
  • Preserve unrelated user or agent changes in the working tree.
  • Add focused comments only when they explain non-obvious behavior.

Async Patterns

# DO: await async functions
data = await weather_client.fetch_weather()

# DO: schedule background work through the app's existing scheduler or asyncio task helpers
asyncio.create_task(background_refresh())

# DON'T: call asyncio.run() from GUI code

wxPython Patterns

  • Keep UI work on the wx main thread; use wx.CallAfter when crossing thread boundaries.
  • Prefer existing dialog/window helpers and local UI conventions over introducing new frameworks.
  • All new interactive controls need accessible labels or names, useful descriptions where supported, keyboard access, and sensible focus behavior.
  • Tests normally use the in-repo wx stub from tests/conftest.py; set ACCESSIWEATHER_ALLOW_REAL_WX_IN_TESTS=1 only when a real wxPython smoke test is required.

Testing Guidelines

  • Unit tests live under tests/test_*.py and should mock external services.
  • GUI-focused tests may use the wx stub or live wx under xvfb/Windows only when needed.
  • Integration tests live under tests/integration/ and should avoid live API dependence unless explicitly intended.
  • Use Hypothesis for broad input-space edge cases.
  • Use the Hypothesis testing framework to good effect for bugs involving many combinations of provider data, missing fields, units, priorities, or fallback behavior.

Test Quality Conventions

  • Prefer behavior and user-contract tests over coverage-padding tests.
  • Name regression tests after the behavior or failure mode, not a PR number, coverage gap, or CI failure. If a temporary coverage/CI test is unavoidable, give it a clear follow-up path.
  • Avoid inspect.getsource() and source-string assertions unless there is no practical runtime behavior to assert.
  • If coverage pressure makes a test awkward, first consider whether the code should be refactored, excluded for a reasoned defensive branch, or tested through a public/domain behavior.
  • Large parameterized or matrix tests are fine when they protect real parsing, mapping, provider, accessibility, playback, notification, or user-visible behavior. Avoid duplicating the same contract at multiple layers only for line coverage.
pytest -n auto -v --tb=short
pytest tests/ -m "not integration" -n auto
pytest tests/test_weather_client.py::test_fetch -v -s
pytest --hypothesis-profile=thorough

CI/CD

Workflow Purpose
ci.yml Linting, tests, changelog check, coverage gate
build.yml Nuitka desktop build artifacts
integration-tests.yml Scheduled integration cassette checks
update-pages.yml GitHub Pages/download updates

Important CI environment defaults:

FORCE_COLOR: "0"
PYTHONUTF8: "1"
ACCESSIWEATHER_TEST_MODE: "1"
HYPOTHESIS_PROFILE: ci

Git Workflow

  • Use conventional commits and conventional PR titles.
  • Branch from dev for normal feature/fix work.
  • PRs should normally target dev.
  • Use gh api REST PATCH calls for PR metadata updates instead of gh pr edit.
  • Use git --no-pager for Git inspection commands on Windows.

Security Guidelines

  • Never commit .env files or API keys.
  • Store API keys via SecureStorage.
  • Validate coordinates: latitude -90..90, longitude -180..180.
  • Sanitize user-provided strings before logging.
  • Keep HTTP timeouts on external requests.

Accessibility Requirements

  • Every interactive UI element must be reachable by keyboard.
  • Controls need clear accessible names and useful descriptions/status text.
  • Dialogs should set initial focus intentionally and preserve normal keyboard escape/cancel behavior.
  • Dynamic updates should be announced or reflected in status text when useful to screen reader users.

Changelog Gate

AccessiWeather runs a CI gate (scripts/changelog_tools.py check) that fails when a user-facing change reaches dev/main without a curated CHANGELOG.md bullet under ## [Unreleased].

  • When an entry is required: changes under src/, installer/, or soundpacks/ (plus accessiweather.spec, pyproject.toml dependency changes, and scripts/generate_build_meta.py). Write the bullet as a plain-language, user-facing note; describe the benefit, not the implementation.
  • Already exempt, with no entry or marker needed: .github/, tests/, docs/, most of scripts/, and the generated src/accessiweather/weather_gov_api_client/ client.
  • Exempting an internal change that still touches gated paths such as refactors, CI, tooling, or release plumbing inside src/:
    • On a PR: add the skip-changelog label.
    • On a direct push to dev/main: include Changelog: none or [skip changelog] in the commit message. The gate only passes when every non-merge commit in the range carries the marker, so do not mix a marked internal commit with an unmarked user-facing one in the same push.
  • Do not pad the changelog with technical or internal notes just to satisfy the gate. Use the exemptions above instead.

Write entries like a human:

- Detected current locations outside the US now get an editable place name when reverse geocoding can identify the coordinates.