Improve launch status UI and alert on SpaceDevs payload errors
This commit is contained in:
parent
458dfc5136
commit
7a50ea6016
3 changed files with 78 additions and 7 deletions
65
update.py
65
update.py
|
|
@ -247,9 +247,52 @@ def is_test_flight(launch: StrDict) -> bool:
|
|||
|
||||
def get_launch_by_slug(data: StrDict, slug: str) -> StrDict | None:
|
||||
"""Find last update for space launch."""
|
||||
return {item["slug"]: typing.cast(StrDict, item) for item in data["results"]}.get(
|
||||
slug
|
||||
results = data.get("results")
|
||||
if not isinstance(results, list):
|
||||
return None
|
||||
|
||||
by_slug: dict[str, StrDict] = {}
|
||||
for item in results:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
item_slug = item.get("slug")
|
||||
if isinstance(item_slug, str):
|
||||
by_slug[item_slug] = typing.cast(StrDict, item)
|
||||
|
||||
return by_slug.get(slug)
|
||||
|
||||
|
||||
def send_thespacedevs_payload_alert(
|
||||
config: flask.config.Config,
|
||||
reason: str,
|
||||
data: StrDict | None,
|
||||
) -> None:
|
||||
"""Alert admin when SpaceDevs update payload is missing expected fields."""
|
||||
payload = data or {}
|
||||
detail = payload.get("detail")
|
||||
status_code = payload.get("status_code", payload.get("status"))
|
||||
|
||||
detail_text = detail if isinstance(detail, str) else ""
|
||||
is_rate_limited = (
|
||||
status_code == 429
|
||||
or "rate" in detail_text.lower()
|
||||
or "thrott" in detail_text.lower()
|
||||
)
|
||||
alert_type = "rate-limit" if is_rate_limited else "error"
|
||||
|
||||
subject = f"⚠️ SpaceDevs {alert_type}: {reason}"
|
||||
body = f"""SpaceDevs update returned an unexpected payload.
|
||||
|
||||
Reason: {reason}
|
||||
Type: {alert_type}
|
||||
Status: {status_code!r}
|
||||
Detail: {detail!r}
|
||||
Payload keys: {sorted(payload.keys())}
|
||||
|
||||
Expected payload shape includes a top-level 'results' list.
|
||||
Updater: /home/edward/src/agenda/update.py
|
||||
"""
|
||||
agenda.mail.send_mail(config, subject, body)
|
||||
|
||||
|
||||
def update_thespacedevs(config: flask.config.Config) -> None:
|
||||
|
|
@ -283,12 +326,26 @@ def update_thespacedevs(config: flask.config.Config) -> None:
|
|||
t0 = time()
|
||||
data = agenda.thespacedevs.next_launch_api_data(rocket_dir)
|
||||
if not data:
|
||||
send_thespacedevs_payload_alert(
|
||||
config,
|
||||
reason="API request failed or returned invalid JSON",
|
||||
data=None,
|
||||
)
|
||||
return # thespacedevs API call failed
|
||||
|
||||
data_results = data.get("results")
|
||||
if not isinstance(data_results, list):
|
||||
send_thespacedevs_payload_alert(
|
||||
config,
|
||||
reason="response missing top-level results list",
|
||||
data=data,
|
||||
)
|
||||
return
|
||||
|
||||
# Identify test-flight slugs present in the current data
|
||||
cur_test_slugs: set[str] = {
|
||||
typing.cast(str, item["slug"])
|
||||
for item in data.get("results", [])
|
||||
for item in data_results
|
||||
if is_test_flight(typing.cast(StrDict, item))
|
||||
}
|
||||
|
||||
|
|
@ -317,7 +374,7 @@ def update_thespacedevs(config: flask.config.Config) -> None:
|
|||
time_taken = time() - t0
|
||||
if not sys.stdin.isatty():
|
||||
return
|
||||
rockets = [agenda.thespacedevs.summarize_launch(item) for item in data["results"]]
|
||||
rockets = [agenda.thespacedevs.summarize_launch(item) for item in data_results]
|
||||
print(len(rockets), "launches")
|
||||
print(len(active_crewed or []), "active crewed missions")
|
||||
print(f"took {time_taken:.1f} seconds")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue