2025-06-03_coordinate_management_workflow#
graph TD
subgraph Configuration
Env[.env: DB_URL, other config]
Config[config.py]
end
Env --> Config
Config --> DB[SQLAlchemy Engine]
DB --> CTable[Coordinates Table]
CTable --> CoordMgr[coordinates_manager.py]
CoordMgr -->|get_coordinates()| WF[weather_ingest.py]
CoordMgr -->|get_coordinates()| ML[ml.py / other modules]
1. Rationale#
Single source of truth for all coordinate points.
Dynamic generation and seeding based on central coordinates.
Persistence and consistency across modules.
Clear detection and handling of coordinate changes.
2. High-Level Workflow#
Read
MY_LATandMY_LONGfrom.env.Initialize DB and create
coordinatestable if missing.On first run (empty table), generate and seed 33 points.
On subsequent runs, verify stored central coordinates match
.env.If mismatch, exit with clear message and backup instructions.
Provide
set_coordinateandget_coordinatesviacoordinates_manager.py.Replace all static coordinate lists with
get_coordinates().Remove hardcoded
MY_LAT,MY_LONGusage elsewhere.
3. File-by-File Migration Steps#
Step |
File(s) |
Change |
|---|---|---|
1 |
Add |
|
2 |
Call |
|
3 |
Create module with |
|
4 |
On startup event, seed defaults or verify central coords. |
|
5 |
Remove static |
|
6 |
Coordinates Setup |
Remove hardcoded logic; optionally use for generation helper. |
7 |
Environment Config |
Keep |
8 |
Update documentation. |
4. Advanced Coordinate Change Detection#
Compare
.envcentral coords with DB on startup.On mismatch, exit and prompt user to backup:
Data in
weather.dbor other storage.ML model artifacts.
Provide instructions to re-run seeding.
5. Next Steps#
Switch to
💻 Codemode to implement the migration.Write
coordinates_manager.pyand update models.Refactor modules to use
get_coordinates().Test end-to-end.
Document release notes.
6. Data Ingestion & Storage Workflow#
graph TD
subgraph Configuration
Env[.env: DATABASE_PATH, POLLING_INTERVAL_MINUTES, DATA_INGEST_INTERVAL_MINUTES, USER_AGENT]
Config[config.py]
end
Env --> Config
subgraph Database
DBEngine[SQLite Engine] -->|WAL & busy timeout| DBFile[weather.db]
end
Config --> DBEngine
subgraph Ingestion
CLI[CLI script (coordinates_setup.py)] -->|calls| Ingest[ingest_weather_for_all_coordinates in weather_ingest.py]
BG[FastAPI background job] -->|calls| Ingest
Ingest --> HTTP[aiohttp.ClientSession]
Ingest --> Conn[aiosqlite.Connection]
Ingest --> DBEngine
end
6.1 Unified Ingestion Logic#
The async function ingest_weather_for_all_coordinates in weather_ingest.py is the single entry point for fetching and storing weather data. It is invoked by both:
A CLI script that opens an
aiosqlite.Connectionandaiohttp.ClientSession. Example:python -m src.app.coordinates_setup
FastAPI background jobs via APScheduler job
trigger_weather_ingestion_cycle, scheduled frommain.py.
6.2 Configuration Centralization#
All operational settings live in config.py:
DATABASE_PATH(env varDATABASE_PATH, defaultweather.db)POLLING_INTERVAL_MINUTES(env varPOLLING_INTERVAL_MINUTES, default10)DATA_INGEST_INTERVAL_MINUTES(env varDATA_INGEST_INTERVAL_MINUTES, default1)USER_AGENT(env varUSER_AGENT, defaultSkolDataApp/1.0 (kontakt@skoldata.se))
Environment variables override defaults, allowing customization without code changes.
6.3 SQLite Concurrency#
SQLite is configured in database.py:
PRAGMA journal_mode=WALenables Write-Ahead Logging for better concurrency reads and writes.PRAGMA busy_timeout=60000(60 s) makes write attempts wait on locks before erroring.
Caveats:
Long-running transactions can block writers.
Frequent writes may cause busy timeouts; monitor logs for
OperationalError: database is locked.
6.4 Operational Recommendations#
Manual Runs
DATABASE_PATH=weather.db DATA_INGEST_INTERVAL_MINUTES=5 python -m src.app.coordinates_setup
Debugging
LOG_LEVEL=DEBUG python -m src.app.coordinates_setup
Or configure logging in
main.py/__init__.py:import logging logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(levelname)s %(message)s")
Production
Use a dedicated background worker (e.g., systemd timer or Kubernetes CronJob).
Monitor for busy-locks and error logs.
Plan for migration to a client/server database (e.g., PostgreSQL) once data volume and concurrency demands exceed SQLite’s capabilities.
End of document.