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
+25 -20
View File
@@ -1,3 +1,5 @@
from __future__ import annotations
import copy
import logging
from datetime import datetime
@@ -10,8 +12,11 @@ from tornado import httputil
from tornado.web import Application
from core.enums import ActivityName
from core.live_data_cache import LiveDataCache
from core.utils import safe_json_dumps
from data.lookup_credentials import extract_credentials
from data.alert import Alert
from data.lookup_credentials import LookupCredentials, extract_credentials
from webserver.sse_broadcaster import SSEBroadcaster
logger = logging.getLogger(__name__)
@@ -21,18 +26,18 @@ class APIAlertsHandler(tornado.web.RequestHandler):
def __init__(
self,
application: "Application",
application: Application,
request: httputil.HTTPServerRequest,
**kwargs: Any,
):
self._alerts = None
) -> None:
self._alerts: LiveDataCache | None = None
super().__init__(application, request, **kwargs)
def initialize(self, alerts):
def initialize(self, alerts: LiveDataCache) -> None:
self._alerts = alerts
@staticmethod
def _enrich(alerts, credentials):
def _enrich(alerts: list[Alert], credentials: LookupCredentials) -> list[Alert]:
enriched = []
for alert in alerts:
alert_copy = copy.deepcopy(alert)
@@ -40,7 +45,7 @@ class APIAlertsHandler(tornado.web.RequestHandler):
enriched.append(alert_copy)
return enriched
def get(self):
def get(self) -> None:
try:
# request.arguments contains lists for each param key because technically the client can supply multiple,
# reduce that to just the first entry, and convert bytes to string
@@ -71,22 +76,22 @@ class APIAlertsHandler(tornado.web.RequestHandler):
class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
"""API request handler for /api/v2/alerts/stream"""
def __init__(self, application, request, **kwargs: Any):
self._sse_alert_broadcaster = None
self._query_params = None
self._credentials = None
self._fields = None
def __init__(self, application: Application, request: httputil.HTTPServerRequest, **kwargs: Any) -> None:
self._sse_alert_broadcaster: SSEBroadcaster | None = None
self._query_params: dict[str, str] | None = None
self._credentials: LookupCredentials | None = None
self._fields: list[str] | None = None
super().__init__(application, request, **kwargs)
def initialize(self, sse_alert_broadcaster):
def initialize(self, sse_alert_broadcaster: SSEBroadcaster) -> None:
self._sse_alert_broadcaster = sse_alert_broadcaster
def custom_headers(self):
def custom_headers(self) -> dict[str, str]:
"""Custom headers to avoid e.g. nginx reverse proxy from buffering SSE data"""
return {"Cache-Control": "no-store", "X-Accel-Buffering": "no"}
def open(self):
def open(self) -> None:
try:
# request.arguments contains lists for each param key because technically the client can supply multiple,
# reduce that to just the first entry, and convert bytes to string
@@ -107,13 +112,13 @@ class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
logger.exception("Exception when serving SSE socket")
self.close()
def close(self):
def close(self) -> None:
"""When the user closes the socket, deregister ourselves from the alert broadcaster"""
self._sse_alert_broadcaster.unregister(self)
super().close()
def callback(self, alert):
def callback(self, alert: Alert) -> None:
"""Callback when a new alert arrives"""
try:
@@ -132,7 +137,7 @@ class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
self.close()
def get_alert_list_with_filters(all_alerts, query):
def get_alert_list_with_filters(all_alerts: LiveDataCache, query: dict[str, str]) -> list[Alert]:
"""Utility method to apply filters to the overall alert list and return only a subset. Enables query parameters in
the main "alerts" GET call."""
@@ -152,7 +157,7 @@ def get_alert_list_with_filters(all_alerts, query):
return alerts
def alert_allowed_by_query(alert, query):
def alert_allowed_by_query(alert: Alert, query: dict[str, str]) -> bool:
"""Given URL query params and an alert, figure out if the alert "passes" the requested filters or is rejected. The list
of query parameters and their function is defined in the API docs."""
@@ -214,7 +219,7 @@ def alert_allowed_by_query(alert, query):
return True
def filter_fields(alerts, fields):
def filter_fields(alerts: list[Alert], fields: list[str]) -> list[dict[str, Any]]:
"""Given a list of alert objects, return copies containing only the named fields."""
return [{k: v for k, v in alert.__dict__.items() if k in fields} for alert in alerts]