Autogenerated type safety parameterisation of all methods

This commit is contained in:
Ian Renton
2026-09-20 20:02:19 +01:00
parent 6037e742cc
commit 324dd1414b
132 changed files with 1228 additions and 706 deletions
+17 -12
View File
@@ -1,6 +1,11 @@
from __future__ import annotations
import logging
import re
from datetime import datetime, timezone
from datetime import date, datetime, timezone
from typing import Any
import requests
from providers.solarconditions.http_solar_conditions_provider import (
HTTPSolarConditionsProvider,
@@ -16,11 +21,11 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider):
"""Solar conditions provider using the NOAA 3-day forecast text file. Parses the NOAA forecast and populates
corresponding fields in the solar conditions object.."""
def __init__(self, provider_config):
def __init__(self, provider_config: dict[str, Any]) -> None:
super().__init__("NOAA 3-day Forecast", provider_config, URL, POLL_INTERVAL)
@staticmethod
def _parse_percentage_table(lines, section_header, year):
def _parse_percentage_table(lines: list[str], section_header: str, year: int) -> dict[str, dict[float, int]] | None:
"""Find and parse a forecast table using percentages, identified by section_header. This is common to the lookup
of the solar storm and radio blackout forecast parsing."""
@@ -48,7 +53,7 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider):
return None
# Figure out the date based on the line found
column_timestamps = []
column_timestamps: list[float] = []
for month_str, day_str in date_matches:
try:
dt = datetime.strptime(f"{day_str} {month_str} {year}", "%d %b %Y").replace(tzinfo=timezone.utc)
@@ -58,7 +63,7 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider):
return None
# Parse data rows. Each non-empty line should have a text label followed by percentage values
result = {}
result: dict[str, dict[float, int]] = {}
for line in lines[date_header_idx + 1 :]:
line_stripped = line.strip()
if not line_stripped:
@@ -73,7 +78,7 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider):
# Row label is everything before the first percentage value
row_label = line_stripped[: line_stripped.index(pct_matches[0].group())].strip()
row_data = {}
row_data: dict[float, int] = {}
for j, match in enumerate(pct_matches):
if j >= len(column_timestamps):
break
@@ -83,7 +88,7 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider):
return result if result else None
def _http_response_to_solar_conditions(self, http_response):
def _http_response_to_solar_conditions(self, http_response: requests.Response) -> dict[str, Any] | None:
lines = http_response.text.splitlines()
# Find the "NOAA Kp index breakdown" section header
@@ -115,7 +120,7 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider):
logger.warning(f"NOAA K-index forecast: could not parse date headers from: {date_header_line}")
return None
column_dates = []
column_dates: list[date] = []
for month_str, day_str in date_matches:
try:
column_dates.append(
@@ -126,7 +131,7 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider):
return None
# Parse each data row, e.g. "00-03UT 2.00 3.00 2.00"
k_index_forecast = {}
k_index_forecast: dict[float, float] = {}
for line in lines[start_idx + 3 :]:
time_match = re.match(r"^(\d{2})-(\d{2})UT\s+(.*)", line.strip())
if not time_match:
@@ -167,14 +172,14 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider):
return None
# Parse Solar Radiation Storm Forecast (single row: "S1 or greater")
solar_storm_forecast = None
solar_storm_forecast: dict[float, int] | None = None
radiation_table = self._parse_percentage_table(lines, "Solar Radiation Storm Forecast", year)
if radiation_table:
solar_storm_forecast = radiation_table.get("S1 or greater")
# Parse Radio Blackout Forecast (two rows: "R1-R2" and "R3 or greater")
blackout_forecast_r1r2 = None
blackout_forecast_r3_or_greater = None
blackout_forecast_r1r2: dict[float, int] | None = None
blackout_forecast_r3_or_greater: dict[float, int] | None = None
blackout_table = self._parse_percentage_table(lines, "Radio Blackout Forecast", year)
if blackout_table:
blackout_forecast_r1r2 = blackout_table.get("R1-R2")