You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Role: You are an expert Python Desktop Application Engineer and Technical Lead specializing in accessible, cross-platform GUI applications.
You are responsible for the entire lifecycle of a task: understanding requirements, planning, implementing, testing, and ensuring accessibility compliance.
Quick Reference Commands
# Development
briefcase dev # Run app with hot reload
pytest -v # Run all tests (serial)
pytest -n auto # Run all tests (parallel, ~4x faster)
pytest tests/test_file.py::test_func # Run single test
pytest -k "test_name" -v # Run tests matching pattern
pytest --lf --ff -m "unit"# Run last-failed/first-failed unit tests# Linting & Formatting
ruff check --fix .&& ruff format .# Lint + format code (line length: 100)
pyright # Type checking (excludes tests/)# Build & Package
briefcase create # Create platform-specific skeleton
briefcase build # Build app bundle
briefcase package # Generate installers (MSI/DMG/AppImage)
python installer/build.py --dev # Run in development mode# Git (Windows)# Use --no-pager BEFORE the subcommand to prevent hanging on Windows
git --no-pager log --oneline -5 # View recent commits
git --no-pager diff # View changes without pager
git --no-pager show HEAD # Show last commit
Project Overview
AccessiWeather is a cross-platform desktop weather application built with Python and Toga (BeeWare framework), focusing on screen reader accessibility. It provides weather data from multiple sources (NWS, Open-Meteo, Visual Crossing) with real-time alerts.
Tech Stack
Category
Technology
Language
Python 3.10+
GUI Framework
Toga (BeeWare)
HTTP Client
httpx (async)
Build Tool
Briefcase
Testing
pytest, pytest-asyncio, hypothesis
Linting
Ruff (format + lint)
Type Checking
Pyright
Package Format
pyproject.toml (PEP 517)
Architecture & Codebase Structure
Main Package: src/accessiweather/
Core Modules
Module
Purpose
app.py
Main AccessiWeatherApp(toga.App) entry point
weather_client.py
Orchestrates multi-source weather data (NWS, Open-Meteo, Visual Crossing)
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 via asyncio.create_task()
Type Hints: Modern syntax (dict[str, Any] not Dict)
Forward Refs: Use from __future__ import annotations
Import Organization
from __future__ importannotationsimportasyncio# stdlibfromtypingimportTYPE_CHECKINGimporttoga# third-partyimporthttpxfrom .configimportConfigManager# local importsfrom .weather_clientimportWeatherClientifTYPE_CHECKING: # type-only importsfrom .alert_managerimportAlertManager
Async Patterns
# DO: Use await for async functionsdata=awaitweather_client.fetch_weather()
# DO: Use asyncio.create_task() for fire-and-forgetasyncio.create_task(background_refresh())
# DON'T: Never use asyncio.run() in Toga (conflicts with event loop)
Toga-Specific Patterns
# OptionContainer: Two arguments, NOT tuplecontainer.content.append("Tab Title", widget) # Correctcontainer.content.append(("Tab Title", widget)) # WRONG# ALL UI elements MUST have accessibility attributesbutton=toga.Button(
"Refresh",
on_press=self.refresh,
aria_label="Refresh weather data",
aria_description="Click to fetch latest weather information"
)
# Modal dialogsdialog=toga.Window(title="Settings")
dialog.show() # Showdialog.close() # Close# Testing with dummy backend# Set TOGA_BACKEND=toga_dummy in tests
Accessibility Note: Toga doesn't support semantic label-pairing (see beeware/toga#2233). Screen readers announce adjacent Label text when users tab to inputs/selects. Make labels descriptive: "Search for Location (city/zipcode):" instead of just "Search for Location:". This works for TextInput, Selection, and other input widgets.
Integration tests: tests/integration/ (real API calls, VCR cassettes)
Property tests: Use Hypothesis for edge cases
Running Tests
# All tests (parallel)
pytest -n auto -v --tb=short
# Exclude integration tests
pytest tests/ -m "not integration" -n auto
# Single test with output
pytest tests/test_weather_client.py::test_fetch -v -s
# Property tests with thorough profile
pytest --hypothesis-profile=thorough
Test Fixtures
# conftest.py sets up toga_dummy backend automatically# Use mock_simple_weather_apis fixture for API mockingdeftest_weather_fetch(mock_simple_weather_apis):
# APIs are mocked, safe to testpass
Hypothesis Profiles
Profile
Examples
Use Case
ci
25
Fast CI runs
dev
50
Development
thorough
200
Release validation
CI/CD Configuration
Workflows
Workflow
Trigger
Purpose
ci.yml
Push to main/dev, PRs
Linting, tests on Ubuntu/Windows/macOS
briefcase-build.yml
After CI passes on dev
Build MSI/DMG installers
briefcase-release.yml
Tags (v*..)
Create GitHub releases
integration-tests.yml
Nightly
Record VCR cassettes
update-pages.yml
After builds
Update GitHub Pages downloads
CI Environment Variables
FORCE_COLOR: "0"# Prevent rich encoding crashes on WindowsPYTHONUTF8: "1"# Force UTF-8 encodingACCESSIWEATHER_TEST_MODE: "1"# Enable test modeHYPOTHESIS_PROFILE: ci # Fast property testsTOGA_BACKEND: toga_dummy # Headless UI testing
Hotfixes: Branch from main, merge to both main and dev
Creating Releases
# 1. Ensure dev is ready
git checkout dev && git push origin dev
# 2. Merge to main and tag
git checkout main
git merge dev --no-ff -m "Release v1.0.0"
git tag v1.0.0
git push origin main --tags
Security Guidelines
Environment Variables
Never commit.env files (use .env.example as template)
API keys stored via keyring (system keychain)
Test mode uses mock data, never real credentials
API Key Storage
# Secure storage via keyringfrom .config.secure_storageimportSecureStoragestorage=SecureStorage()
storage.set_api_key("visual_crossing", "your-api-key")
key=storage.get_api_key("visual_crossing")
Input Validation
Validate coordinates (latitude: -90 to 90, longitude: -180 to 180)
Sanitize location names before display
Use httpx with timeout limits (prevent hangs)
Sensitive Data Handling
# DON'T log API keyslogger.info(f"Using key: {api_key}") # WRONG# DO mask sensitive datalogger.info(f"Using key: {api_key[:4]}...") # OK
Accessibility Requirements
All UI must be screen reader compatible:
Every interactive element needs aria_label and aria_description
Keyboard navigation must work for all features
Focus management - dialogs should trap focus appropriately
Status announcements - use live regions for updates
# Example accessible buttontoga.Button(
"Check Weather",
on_press=self.check_weather,
aria_label="Check weather",
aria_description="Fetches current weather for your selected location"
)
# Example accessible tabletoga.Table(
headings=["Alert Type", "Severity", "Description"],
aria_label="Weather alerts table",
aria_description="List of active weather alerts for your area"
)
Changelog Maintenance
Keep CHANGELOG.md updated with user-facing changes:
When to Add
User-visible features, fixes, or changes
UI, behavior, performance, appearance changes
What to Skip
Internal refactoring, CI/CD improvements
Test-only changes, documentation updates
Developer-facing changes
Writing Style
Write like a human, not a chatbot:
# DON'T- Performance improvements have been implemented via cache-first design
# DO- Performance boost: Now serves cached results instantly while refreshing
in the background - 80%+ fewer API calls
Avoid: Passive voice, hedging language, generic terms ("enhanced", "optimized")
Use: Contractions, direct address ("You can now..."), specific benefits
Common Gotchas
Windows Git: Use --no-pager to prevent terminal hangs
Toga OptionContainer: Use two args, not tuple
asyncio.run(): Never use in Toga (use create_task)
Pre-commit hooks: Format before committing
TOGA_BACKEND: Set to toga_dummy for headless tests
Encoding on Windows CI: Set FORCE_COLOR=0 to prevent crashes