mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-21 06:47:42 +00:00
Autogenerated type safety parameterisation of all methods
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from threading import Event, Thread
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import requests
|
||||
from requests.exceptions import ConnectionError, ConnectTimeout, JSONDecodeError, ReadTimeout
|
||||
|
||||
from core.constants import HTTP_HEADERS
|
||||
from data.spot import Spot
|
||||
from providers.spot.spot_provider import SpotProvider
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -16,22 +20,22 @@ class HTTPSpotProvider(SpotProvider):
|
||||
"""Generic spot provider class for providers that request data via HTTP(S). Just for convenience to avoid code
|
||||
duplication. Subclasses of this query the individual APIs for data."""
|
||||
|
||||
def __init__(self, name, provider_config, url, poll_interval):
|
||||
def __init__(self, name: str, provider_config: dict[str, Any], url: str, poll_interval: float) -> None:
|
||||
super().__init__(name, provider_config)
|
||||
self._url = url
|
||||
self._poll_interval = poll_interval
|
||||
self._thread = None
|
||||
self._stop_event = Event()
|
||||
self._wakeup_event = Event()
|
||||
self._url: str = url
|
||||
self._poll_interval: float = poll_interval
|
||||
self._thread: Thread | None = None
|
||||
self._stop_event: Event = Event()
|
||||
self._wakeup_event: Event = Event()
|
||||
|
||||
def start(self):
|
||||
def start(self) -> None:
|
||||
# Fire off the polling thread. It will poll immediately on startup, then sleep for poll_interval between
|
||||
# subsequent polls, so start() returns immediately and the application can continue starting.
|
||||
logger.info(f"Set up query of {self.name} spot API every {self._poll_interval!s} seconds.")
|
||||
self._thread = Thread(target=self._run, name=f"HTTPSpotProvider-{self.name}", daemon=True)
|
||||
self._thread.start()
|
||||
|
||||
def stop(self):
|
||||
def stop(self) -> None:
|
||||
self._stop_event.set()
|
||||
self._wakeup_event.set()
|
||||
if self._thread:
|
||||
@@ -39,12 +43,12 @@ class HTTPSpotProvider(SpotProvider):
|
||||
if self._thread.is_alive():
|
||||
logger.warning(f"{self.name} spot worker thread did not exit on time and will be killed.")
|
||||
|
||||
def force_poll(self):
|
||||
def force_poll(self) -> None:
|
||||
"""Trigger an immediate poll without waiting for the normal interval."""
|
||||
|
||||
self._wakeup_event.set()
|
||||
|
||||
def _run(self):
|
||||
def _run(self) -> None:
|
||||
while True:
|
||||
self._wakeup_event.clear()
|
||||
self._poll()
|
||||
@@ -52,7 +56,7 @@ class HTTPSpotProvider(SpotProvider):
|
||||
if self._stop_event.is_set():
|
||||
break
|
||||
|
||||
def _poll(self):
|
||||
def _poll(self) -> None:
|
||||
try:
|
||||
# Request data from API
|
||||
logger.debug(f"Polling {self.name} spot API...")
|
||||
@@ -86,7 +90,7 @@ class HTTPSpotProvider(SpotProvider):
|
||||
logger.exception(f"Exception in HTTP Spot Provider ({self.name})")
|
||||
self._stop_event.wait(timeout=1)
|
||||
|
||||
def _http_response_to_spots(self, http_response):
|
||||
def _http_response_to_spots(self, http_response: requests.Response) -> list[Spot] | None:
|
||||
"""Convert an HTTP response returned by the API into spot data. The whole response is provided here so the subclass
|
||||
implementations can check for HTTP status codes if necessary, and handle the response as JSON, XML, text, whatever
|
||||
the API actually provides."""
|
||||
|
||||
Reference in New Issue
Block a user