mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-03-15 20:34:31 +00:00
Bulk convert comments above classes/functions/methods into proper docstrings
This commit is contained in:
@@ -16,8 +16,9 @@ from data.sig_ref import SIGRef
|
||||
from data.spot import Spot
|
||||
|
||||
|
||||
# API request handler for /api/v1/spot (POST)
|
||||
class APISpotHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/spot (POST)"""
|
||||
|
||||
def initialize(self, spots, web_server_metrics):
|
||||
self.spots = spots
|
||||
self.web_server_metrics = web_server_metrics
|
||||
@@ -34,15 +35,17 @@ class APISpotHandler(tornado.web.RequestHandler):
|
||||
if not ALLOW_SPOTTING:
|
||||
self.set_status(401)
|
||||
self.write(json.dumps("Error - this server does not allow new spots to be added via the API.",
|
||||
default=serialize_everything))
|
||||
default=serialize_everything))
|
||||
self.set_header("Cache-Control", "no-store")
|
||||
self.set_header("Content-Type", "application/json")
|
||||
return
|
||||
|
||||
# Reject if format not json
|
||||
if 'Content-Type' not in self.request.headers or self.request.headers.get('Content-Type') != "application/json":
|
||||
if 'Content-Type' not in self.request.headers or self.request.headers.get(
|
||||
'Content-Type') != "application/json":
|
||||
self.set_status(415)
|
||||
self.write(json.dumps("Error - request Content-Type must be application/json", default=serialize_everything))
|
||||
self.write(
|
||||
json.dumps("Error - request Content-Type must be application/json", default=serialize_everything))
|
||||
self.set_header("Cache-Control", "no-store")
|
||||
self.set_header("Content-Type", "application/json")
|
||||
return
|
||||
@@ -72,7 +75,7 @@ class APISpotHandler(tornado.web.RequestHandler):
|
||||
if not spot.time or not spot.dx_call or not spot.freq or not spot.de_call:
|
||||
self.set_status(422)
|
||||
self.write(json.dumps("Error - 'time', 'dx_call', 'freq' and 'de_call' must be provided as a minimum.",
|
||||
default=serialize_everything))
|
||||
default=serialize_everything))
|
||||
self.set_header("Cache-Control", "no-store")
|
||||
self.set_header("Content-Type", "application/json")
|
||||
return
|
||||
@@ -81,14 +84,14 @@ class APISpotHandler(tornado.web.RequestHandler):
|
||||
if not re.match(r"^[A-Za-z0-9/\-]*$", spot.dx_call):
|
||||
self.set_status(422)
|
||||
self.write(json.dumps("Error - '" + spot.dx_call + "' does not look like a valid callsign.",
|
||||
default=serialize_everything))
|
||||
default=serialize_everything))
|
||||
self.set_header("Cache-Control", "no-store")
|
||||
self.set_header("Content-Type", "application/json")
|
||||
return
|
||||
if not re.match(r"^[A-Za-z0-9/\-]*$", spot.de_call):
|
||||
self.set_status(422)
|
||||
self.write(json.dumps("Error - '" + spot.de_call + "' does not look like a valid callsign.",
|
||||
default=serialize_everything))
|
||||
default=serialize_everything))
|
||||
self.set_header("Cache-Control", "no-store")
|
||||
self.set_header("Content-Type", "application/json")
|
||||
return
|
||||
@@ -97,7 +100,7 @@ class APISpotHandler(tornado.web.RequestHandler):
|
||||
if lookup_helper.infer_band_from_freq(spot.freq) == UNKNOWN_BAND:
|
||||
self.set_status(422)
|
||||
self.write(json.dumps("Error - Frequency of " + str(spot.freq / 1000.0) + "kHz is not in a known band.",
|
||||
default=serialize_everything))
|
||||
default=serialize_everything))
|
||||
self.set_header("Cache-Control", "no-store")
|
||||
self.set_header("Content-Type", "application/json")
|
||||
return
|
||||
@@ -108,7 +111,7 @@ class APISpotHandler(tornado.web.RequestHandler):
|
||||
spot.dx_grid.upper()):
|
||||
self.set_status(422)
|
||||
self.write(json.dumps("Error - '" + spot.dx_grid + "' does not look like a valid Maidenhead grid.",
|
||||
default=serialize_everything))
|
||||
default=serialize_everything))
|
||||
self.set_header("Cache-Control", "no-store")
|
||||
self.set_header("Content-Type", "application/json")
|
||||
return
|
||||
|
||||
@@ -14,8 +14,9 @@ SSE_HANDLER_MAX_QUEUE_SIZE = 100
|
||||
SSE_HANDLER_QUEUE_CHECK_INTERVAL = 5000
|
||||
|
||||
|
||||
# API request handler for /api/v1/alerts
|
||||
class APIAlertsHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/alerts"""
|
||||
|
||||
def initialize(self, alerts, web_server_metrics):
|
||||
self.alerts = alerts
|
||||
self.web_server_metrics = web_server_metrics
|
||||
@@ -47,14 +48,17 @@ class APIAlertsHandler(tornado.web.RequestHandler):
|
||||
self.set_header("Cache-Control", "no-store")
|
||||
self.set_header("Content-Type", "application/json")
|
||||
|
||||
# API request handler for /api/v1/alerts/stream
|
||||
|
||||
class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
"""API request handler for /api/v1/alerts/stream"""
|
||||
|
||||
def initialize(self, sse_alert_queues, web_server_metrics):
|
||||
self.sse_alert_queues = sse_alert_queues
|
||||
self.web_server_metrics = web_server_metrics
|
||||
|
||||
# Custom headers to avoid e.g. nginx reverse proxy from buffering SSE data
|
||||
def custom_headers(self):
|
||||
"""Custom headers to avoid e.g. nginx reverse proxy from buffering SSE data"""
|
||||
|
||||
return {"Cache-Control": "no-store",
|
||||
"X-Accel-Buffering": "no"}
|
||||
|
||||
@@ -81,8 +85,9 @@ class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
except Exception as e:
|
||||
logging.warn("Exception when serving SSE socket", e)
|
||||
|
||||
# When the user closes the socket, empty our queue and remove it from the list so the server no longer fills it
|
||||
def close(self):
|
||||
"""When the user closes the socket, empty our queue and remove it from the list so the server no longer fills it"""
|
||||
|
||||
try:
|
||||
if self.alert_queue in self.sse_alert_queues:
|
||||
self.sse_alert_queues.remove(self.alert_queue)
|
||||
@@ -96,8 +101,9 @@ class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
self.alert_queue = None
|
||||
super().close()
|
||||
|
||||
# Callback to check if anything has arrived in the queue, and if so send it to the client
|
||||
def _callback(self):
|
||||
"""Callback to check if anything has arrived in the queue, and if so send it to the client"""
|
||||
|
||||
try:
|
||||
if self.alert_queue:
|
||||
while not self.alert_queue.empty():
|
||||
@@ -114,11 +120,10 @@ class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
self.close()
|
||||
|
||||
|
||||
|
||||
|
||||
# Utility method to apply filters to the overall alert list and return only a subset. Enables query parameters in
|
||||
# the main "alerts" GET call.
|
||||
def get_alert_list_with_filters(all_alerts, query):
|
||||
"""Utility method to apply filters to the overall alert list and return only a subset. Enables query parameters in
|
||||
the main "alerts" GET call."""
|
||||
|
||||
# Create a shallow copy of the alert list ordered by start time, then filter the list to reduce it only to alerts
|
||||
# that match the filter parameters in the query string. Finally, apply a limit to the number of alerts returned.
|
||||
# The list of query string filters is defined in the API docs.
|
||||
@@ -134,9 +139,11 @@ def get_alert_list_with_filters(all_alerts, query):
|
||||
alerts = alerts[:int(query.get("limit"))]
|
||||
return alerts
|
||||
|
||||
# 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.
|
||||
|
||||
def alert_allowed_by_query(alert, query):
|
||||
"""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."""
|
||||
|
||||
for k in query.keys():
|
||||
match k:
|
||||
case "received_since":
|
||||
|
||||
@@ -16,8 +16,9 @@ from data.sig_ref import SIGRef
|
||||
from data.spot import Spot
|
||||
|
||||
|
||||
# API request handler for /api/v1/lookup/call
|
||||
class APILookupCallHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/lookup/call"""
|
||||
|
||||
def initialize(self, web_server_metrics):
|
||||
self.web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -75,8 +76,9 @@ class APILookupCallHandler(tornado.web.RequestHandler):
|
||||
self.set_header("Content-Type", "application/json")
|
||||
|
||||
|
||||
# API request handler for /api/v1/lookup/sigref
|
||||
class APILookupSIGRefHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/lookup/sigref"""
|
||||
|
||||
def initialize(self, web_server_metrics):
|
||||
self.web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -123,9 +125,9 @@ class APILookupSIGRefHandler(tornado.web.RequestHandler):
|
||||
self.set_header("Content-Type", "application/json")
|
||||
|
||||
|
||||
|
||||
# API request handler for /api/v1/lookup/grid
|
||||
class APILookupGridHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/lookup/grid"""
|
||||
|
||||
def initialize(self, web_server_metrics):
|
||||
self.web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -152,17 +154,17 @@ class APILookupGridHandler(tornado.web.RequestHandler):
|
||||
center_itu_zone = lat_lon_to_itu_zone(center_lat, center_lon)
|
||||
|
||||
response = {
|
||||
"center" : {
|
||||
"center": {
|
||||
"latitude": center_lat,
|
||||
"longitude": center_lon,
|
||||
"cq_zone": center_cq_zone,
|
||||
"itu_zone": center_itu_zone
|
||||
},
|
||||
"southwest" : {
|
||||
"southwest": {
|
||||
"latitude": lat,
|
||||
"longitude": lon,
|
||||
},
|
||||
"northeast" : {
|
||||
"northeast": {
|
||||
"latitude": lat + lat_cell_size,
|
||||
"longitude": lon + lon_cell_size,
|
||||
}}
|
||||
|
||||
@@ -10,8 +10,9 @@ from core.prometheus_metrics_handler import api_requests_counter
|
||||
from core.utils import serialize_everything
|
||||
|
||||
|
||||
# API request handler for /api/v1/options
|
||||
class APIOptionsHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/options"""
|
||||
|
||||
def initialize(self, status_data, web_server_metrics):
|
||||
self.status_data = status_data
|
||||
self.web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -14,8 +14,9 @@ SSE_HANDLER_MAX_QUEUE_SIZE = 1000
|
||||
SSE_HANDLER_QUEUE_CHECK_INTERVAL = 5000
|
||||
|
||||
|
||||
# API request handler for /api/v1/spots
|
||||
class APISpotsHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/spots"""
|
||||
|
||||
def initialize(self, spots, web_server_metrics):
|
||||
self.spots = spots
|
||||
self.web_server_metrics = web_server_metrics
|
||||
@@ -48,19 +49,22 @@ class APISpotsHandler(tornado.web.RequestHandler):
|
||||
self.set_header("Content-Type", "application/json")
|
||||
|
||||
|
||||
# API request handler for /api/v1/spots/stream
|
||||
class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
"""API request handler for /api/v1/spots/stream"""
|
||||
|
||||
def initialize(self, sse_spot_queues, web_server_metrics):
|
||||
self.sse_spot_queues = sse_spot_queues
|
||||
self.web_server_metrics = web_server_metrics
|
||||
|
||||
# Custom headers to avoid e.g. nginx reverse proxy from buffering SSE data
|
||||
def custom_headers(self):
|
||||
"""Custom headers to avoid e.g. nginx reverse proxy from buffering SSE data"""
|
||||
|
||||
return {"Cache-Control": "no-store",
|
||||
"X-Accel-Buffering": "no"}
|
||||
|
||||
# Called once on the client opening a connection, set things up
|
||||
def open(self):
|
||||
"""Called once on the client opening a connection, set things up"""
|
||||
|
||||
try:
|
||||
# Metrics
|
||||
self.web_server_metrics["last_api_access_time"] = datetime.now(pytz.UTC)
|
||||
@@ -83,8 +87,9 @@ class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
except Exception as e:
|
||||
logging.warn("Exception when serving SSE socket", e)
|
||||
|
||||
# When the user closes the socket, empty our queue and remove it from the list so the server no longer fills it
|
||||
def close(self):
|
||||
"""When the user closes the socket, empty our queue and remove it from the list so the server no longer fills it"""
|
||||
|
||||
try:
|
||||
if self.spot_queue in self.sse_spot_queues:
|
||||
self.sse_spot_queues.remove(self.spot_queue)
|
||||
@@ -98,8 +103,9 @@ class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
self.spot_queue = None
|
||||
super().close()
|
||||
|
||||
# Callback to check if anything has arrived in the queue, and if so send it to the client
|
||||
def _callback(self):
|
||||
"""Callback to check if anything has arrived in the queue, and if so send it to the client"""
|
||||
|
||||
try:
|
||||
if self.spot_queue:
|
||||
while not self.spot_queue.empty():
|
||||
@@ -116,10 +122,10 @@ class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
self.close()
|
||||
|
||||
|
||||
|
||||
# Utility method to apply filters to the overall spot list and return only a subset. Enables query parameters in
|
||||
# the main "spots" GET call.
|
||||
def get_spot_list_with_filters(all_spots, query):
|
||||
"""Utility method to apply filters to the overall spot list and return only a subset. Enables query parameters in
|
||||
the main "spots" GET call."""
|
||||
|
||||
# Create a shallow copy of the spot list, ordered by spot time, then filter the list to reduce it only to spots
|
||||
# that match the filter parameters in the query string. Finally, apply a limit to the number of spots returned.
|
||||
# The list of query string filters is defined in the API docs.
|
||||
@@ -142,22 +148,24 @@ def get_spot_list_with_filters(all_spots, query):
|
||||
# duplicates are fine in the main spot list (e.g. different cluster spots of the same DX) this doesn't
|
||||
# work well for the other views.
|
||||
if "dedupe" in query.keys():
|
||||
dedupe = query.get("dedupe").upper() == "TRUE"
|
||||
if dedupe:
|
||||
spots_temp = []
|
||||
already_seen = []
|
||||
for s in spots:
|
||||
call_plus_ssid = s.dx_call + (s.dx_ssid if s.dx_ssid else "")
|
||||
if call_plus_ssid not in already_seen:
|
||||
spots_temp.append(s)
|
||||
already_seen.append(call_plus_ssid)
|
||||
spots = spots_temp
|
||||
dedupe = query.get("dedupe").upper() == "TRUE"
|
||||
if dedupe:
|
||||
spots_temp = []
|
||||
already_seen = []
|
||||
for s in spots:
|
||||
call_plus_ssid = s.dx_call + (s.dx_ssid if s.dx_ssid else "")
|
||||
if call_plus_ssid not in already_seen:
|
||||
spots_temp.append(s)
|
||||
already_seen.append(call_plus_ssid)
|
||||
spots = spots_temp
|
||||
|
||||
return spots
|
||||
|
||||
# Given URL query params and a spot, figure out if the spot "passes" the requested filters or is rejected. The list
|
||||
# of query parameters and their function is defined in the API docs.
|
||||
|
||||
def spot_allowed_by_query(spot, query):
|
||||
"""Given URL query params and a spot, figure out if the spot "passes" the requested filters or is rejected. The list
|
||||
of query parameters and their function is defined in the API docs."""
|
||||
|
||||
for k in query.keys():
|
||||
match k:
|
||||
case "since":
|
||||
@@ -240,4 +248,4 @@ def spot_allowed_by_query(spot, query):
|
||||
needs_good_location = query.get(k).upper() == "TRUE"
|
||||
if needs_good_location and not spot.dx_location_good:
|
||||
return False
|
||||
return True
|
||||
return True
|
||||
|
||||
@@ -8,8 +8,9 @@ from core.prometheus_metrics_handler import api_requests_counter
|
||||
from core.utils import serialize_everything
|
||||
|
||||
|
||||
# API request handler for /api/v1/status
|
||||
class APIStatusHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/status"""
|
||||
|
||||
def initialize(self, status_data, web_server_metrics):
|
||||
self.status_data = status_data
|
||||
self.web_server_metrics = web_server_metrics
|
||||
|
||||
Reference in New Issue
Block a user