Skip to content

Commit a6e3e7b

Browse files
authored
fix: improve production code safety and input validation (#332)
* fix: improve production code safety and input validation - Replace assert statements with proper ValueError in weather/open_meteo.py - Replace implicit None return with ValueError in forecast.py - Use log.info instead of print for consistency * fix(deps): pin sentry-sdk to 2.37.1 to fix CI compatibility with huggingface_hub * fix(deps): downgrade sentry-sdk to 1.45.0 to resolve huggingface_hub incompatibility * fix(deps): update huggingface_hub to 0.20.0 to resolve sentry-sdk integration compatibility * fix: disable sentry default integrations to prevent huggingface_hub incompatibility
1 parent e26a827 commit a6e3e7b

3 files changed

Lines changed: 45 additions & 32 deletions

File tree

quartz_solar_forecast/forecast.py

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,31 +93,32 @@ def predict_tryolabs(site: PVSite, ts: datetime | str = None):
9393
three_months_ago = datetime.today() - timedelta(days=3 * 30)
9494

9595
if start_date_datetime < three_months_ago:
96-
print(
97-
f"Start date ({start_date}) is more than 3 months ago, no",
98-
"forecast data available.",
99-
)
100-
else:
101-
# download the model from google drive and decompress if necessary
102-
solar_power_predictor.load_model()
103-
# make predictions
104-
predictions = solar_power_predictor.predict_power_output(
105-
latitude=site.latitude,
106-
longitude=site.longitude,
107-
start_date=start_date,
108-
kwp=site.capacity_kwp,
109-
orientation=site.orientation,
110-
tilt=site.tilt,
96+
raise ValueError(
97+
f"Start date ({start_date}) is more than 3 months ago. "
98+
"Historical forecast data is not available beyond this range. "
99+
"Please use a more recent date."
111100
)
112101

113-
# postprocessing of the dataframe
114-
predictions = predictions[
115-
(predictions["date"] >= start_time) & (predictions["date"] < end_time)
116-
]
117-
predictions = predictions.reset_index(drop=True)
118-
predictions.set_index("date", inplace=True)
119-
print("Predictions finished.")
120-
return predictions
102+
# download the model from google drive and decompress if necessary
103+
solar_power_predictor.load_model()
104+
# make predictions
105+
predictions = solar_power_predictor.predict_power_output(
106+
latitude=site.latitude,
107+
longitude=site.longitude,
108+
start_date=start_date,
109+
kwp=site.capacity_kwp,
110+
orientation=site.orientation,
111+
tilt=site.tilt,
112+
)
113+
114+
# postprocessing of the dataframe
115+
predictions = predictions[
116+
(predictions["date"] >= start_time) & (predictions["date"] < end_time)
117+
]
118+
predictions = predictions.reset_index(drop=True)
119+
predictions.set_index("date", inplace=True)
120+
log.info("Predictions finished.")
121+
return predictions
121122

122123

123124
def run_forecast(

quartz_solar_forecast/utils/sentry_logging.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,14 @@
1414
)
1515

1616
SENTRY_DSN = "https://b2b6f3c97299f81464bc16ad0d516d0b@o400768.ingest.us.sentry.io/4508439933157376"
17-
sentry_sdk.init(dsn=SENTRY_DSN, traces_sample_rate=1.0)
17+
18+
# Disable default integrations to prevent incompatible huggingface_hub integration
19+
# from causing AttributeError with older huggingface_hub versions
20+
sentry_sdk.init(
21+
dsn=SENTRY_DSN,
22+
traces_sample_rate=1.0,
23+
default_integrations=False,
24+
)
1825

1926

2027
def write_sentry(params):

quartz_solar_forecast/weather/open_meteo.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ def _validate_coordinates(self, latitude: float, longitude: float) -> None:
7070
ValueError
7171
If coordinates are not within valid ranges.
7272
"""
73-
assert -90 <= latitude <= 90 and -180 <= longitude <= 180, (
74-
"Invalid coordinates. Latitude must be between -90 and 90, "
75-
"and longitude must be between -180 and 180."
76-
)
73+
if not (-90 <= latitude <= 90 and -180 <= longitude <= 180):
74+
raise ValueError(
75+
"Invalid coordinates. Latitude must be between -90 and 90, "
76+
"and longitude must be between -180 and 180."
77+
)
7778

7879
def _validate_date_format(self, start_date: str, end_date: str) -> None:
7980
"""
@@ -94,12 +95,16 @@ def _validate_date_format(self, start_date: str, end_date: str) -> None:
9495
try:
9596
start_datetime = datetime.strptime(start_date, "%Y-%m-%d")
9697
end_datetime = datetime.strptime(end_date, "%Y-%m-%d")
97-
assert end_datetime > start_datetime, "End date must be greater than start date."
98-
except (ValueError, AssertionError) as e:
98+
except ValueError as e:
9999
raise ValueError(
100-
f"Invalid date format or range. Please use YYYY-MM-DD and ensure "
101-
f"end_date is greater than start_date. Error: {str(e)}"
100+
f"Invalid date format. Please use YYYY-MM-DD format. Error: {str(e)}"
102101
) from e
102+
103+
if not (end_datetime > start_datetime):
104+
raise ValueError(
105+
f"Invalid date range. End date ({end_date}) must be greater than "
106+
f"start date ({start_date})."
107+
)
103108

104109
def get_hourly_weather(
105110
self, latitude: float, longitude: float, start_date: str, end_date: str

0 commit comments

Comments
 (0)