diff --git a/src/accessisky/api/briefing.py b/src/accessisky/api/briefing.py index a4b4dcb..f54fe61 100644 --- a/src/accessisky/api/briefing.py +++ b/src/accessisky/api/briefing.py @@ -10,6 +10,7 @@ from __future__ import annotations +import asyncio import logging from dataclasses import dataclass, field from datetime import date @@ -522,60 +523,60 @@ async def get_briefing( data = DailyBriefingData(date=target_date) - # Fetch all data, handling failures gracefully - try: - sunrise, sunset, day_length = await self._get_sun_data( - latitude=latitude, - longitude=longitude, - target_date=target_date, - ) - data.sunrise = sunrise - data.sunset = sunset - data.day_length = day_length - except Exception as e: - logger.error(f"Sun data fetch failed: {e}") + # Fetch all data concurrently; each helper already handles its own errors + results = await asyncio.gather( + self._get_sun_data(latitude, longitude, target_date), + self._get_moon_data(target_date, latitude, longitude), + self._get_iss_data(latitude, longitude, target_date), + self._get_planets_data(target_date), + self._get_meteor_data(target_date), + self._get_eclipse_data(target_date), + self._get_space_weather_data(), + return_exceptions=True, + ) + + # Unpack results, treating exceptions as missing data + sun_result = results[0] + if not isinstance(sun_result, BaseException): + data.sunrise, data.sunset, data.day_length = sun_result + else: + logger.error(f"Sun data fetch failed: {sun_result}") - try: - moon_phase, moon_illum, moon_rise, moon_set = await self._get_moon_data( - target_date=target_date, - latitude=latitude, - longitude=longitude, - ) - data.moon_phase = moon_phase - data.moon_illumination = moon_illum - data.moon_rise = moon_rise - data.moon_set = moon_set - except Exception as e: - logger.error(f"Moon data fetch failed: {e}") + moon_result = results[1] + if not isinstance(moon_result, BaseException): + data.moon_phase, data.moon_illumination, data.moon_rise, data.moon_set = moon_result + else: + logger.error(f"Moon data fetch failed: {moon_result}") - try: - data.iss_passes = await self._get_iss_data( - latitude=latitude, - longitude=longitude, - target_date=target_date, - ) - except Exception as e: - logger.error(f"ISS data fetch failed: {e}") + iss_result = results[2] + if not isinstance(iss_result, BaseException): + data.iss_passes = iss_result + else: + logger.error(f"ISS data fetch failed: {iss_result}") - try: - data.visible_planets = await self._get_planets_data(target_date=target_date) - except Exception as e: - logger.error(f"Planet data fetch failed: {e}") + planets_result = results[3] + if not isinstance(planets_result, BaseException): + data.visible_planets = planets_result + else: + logger.error(f"Planet data fetch failed: {planets_result}") - try: - data.active_meteor_showers = await self._get_meteor_data(target_date=target_date) - except Exception as e: - logger.error(f"Meteor data fetch failed: {e}") + meteor_result = results[4] + if not isinstance(meteor_result, BaseException): + data.active_meteor_showers = meteor_result + else: + logger.error(f"Meteor data fetch failed: {meteor_result}") - try: - data.eclipse_today = await self._get_eclipse_data(target_date=target_date) - except Exception as e: - logger.error(f"Eclipse data fetch failed: {e}") + eclipse_result = results[5] + if not isinstance(eclipse_result, BaseException): + data.eclipse_today = eclipse_result + else: + logger.error(f"Eclipse data fetch failed: {eclipse_result}") - try: - data.space_weather = await self._get_space_weather_data() - except Exception as e: - logger.error(f"Space weather fetch failed: {e}") + weather_result = results[6] + if not isinstance(weather_result, BaseException): + data.space_weather = weather_result + else: + logger.error(f"Space weather fetch failed: {weather_result}") # Generate summary text data.summary_text = generate_briefing_text(data) diff --git a/src/accessisky/api/tonight.py b/src/accessisky/api/tonight.py index 7babc22..7486d33 100644 --- a/src/accessisky/api/tonight.py +++ b/src/accessisky/api/tonight.py @@ -6,6 +6,7 @@ from __future__ import annotations +import asyncio import logging from dataclasses import dataclass, field from datetime import date @@ -381,56 +382,55 @@ async def get_summary( data = TonightData() - # Fetch all data, handling failures gracefully - try: - moon_phase, moon_illum, moon_rise, moon_set = await self._get_moon_data( - target_date=target_date, - latitude=latitude, - longitude=longitude, + # Fetch all data concurrently; each helper already handles its own errors + results = await asyncio.gather( + self._get_moon_data(target_date, latitude, longitude), + self._get_iss_data(latitude, longitude), + self._get_planets_data(target_date), + self._get_meteor_data(target_date), + self._get_aurora_data(), + self._get_viewing_data(latitude, longitude, target_date), + return_exceptions=True, + ) + + # Unpack results, treating exceptions as missing data + moon_result = results[0] + if not isinstance(moon_result, BaseException): + data.moon_phase, data.moon_illumination, data.moon_rise_time, data.moon_set_time = ( + moon_result ) - data.moon_phase = moon_phase - data.moon_illumination = moon_illum - data.moon_rise_time = moon_rise - data.moon_set_time = moon_set - except Exception as e: - logger.error(f"Moon data fetch failed: {e}") + else: + logger.error(f"Moon data fetch failed: {moon_result}") - try: - data.iss_passes = await self._get_iss_data( - latitude=latitude, - longitude=longitude, - ) - except Exception as e: - logger.error(f"ISS data fetch failed: {e}") + iss_result = results[1] + if not isinstance(iss_result, BaseException): + data.iss_passes = iss_result + else: + logger.error(f"ISS data fetch failed: {iss_result}") - try: - data.visible_planets = await self._get_planets_data(target_date=target_date) - except Exception as e: - logger.error(f"Planet data fetch failed: {e}") + planets_result = results[2] + if not isinstance(planets_result, BaseException): + data.visible_planets = planets_result + else: + logger.error(f"Planet data fetch failed: {planets_result}") - try: - data.active_meteor_showers = await self._get_meteor_data(target_date=target_date) - except Exception as e: - logger.error(f"Meteor data fetch failed: {e}") + meteor_result = results[3] + if not isinstance(meteor_result, BaseException): + data.active_meteor_showers = meteor_result + else: + logger.error(f"Meteor data fetch failed: {meteor_result}") - try: - aurora_kp, aurora_activity = await self._get_aurora_data() - data.aurora_kp = aurora_kp - data.aurora_activity = aurora_activity - except Exception as e: - logger.error(f"Aurora data fetch failed: {e}") + aurora_result = results[4] + if not isinstance(aurora_result, BaseException): + data.aurora_kp, data.aurora_activity = aurora_result + else: + logger.error(f"Aurora data fetch failed: {aurora_result}") - try: - score, cloud_cover, description = await self._get_viewing_data( - latitude=latitude, - longitude=longitude, - target_date=target_date, - ) - data.viewing_score = score - data.cloud_cover_percent = cloud_cover - data.viewing_description = description - except Exception as e: - logger.error(f"Viewing data fetch failed: {e}") + viewing_result = results[5] + if not isinstance(viewing_result, BaseException): + data.viewing_score, data.cloud_cover_percent, data.viewing_description = viewing_result + else: + logger.error(f"Viewing data fetch failed: {viewing_result}") # Generate summary text data.summary_text = generate_summary_text(data)