barebone app with django and react, sse, jwt token, comport reader, test comport writer, requires com0com, users with groups, sample table vehicles, tokens for access and refresh
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
"""
|
||||
Backend API Client
|
||||
Handles communication with Django backend
|
||||
"""
|
||||
import requests
|
||||
import logging
|
||||
from typing import Optional, Dict, Any
|
||||
from requests.adapters import HTTPAdapter
|
||||
from urllib3.util.retry import Retry
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class BackendClient:
|
||||
def __init__(self, base_url: str, timeout: int = 5, max_retries: int = 3):
|
||||
self.base_url = base_url
|
||||
self.timeout = timeout
|
||||
self.max_retries = max_retries
|
||||
self.session = self._create_session()
|
||||
|
||||
def _create_session(self) -> requests.Session:
|
||||
"""Create a requests session with retry logic"""
|
||||
session = requests.Session()
|
||||
|
||||
retry_strategy = Retry(
|
||||
total=self.max_retries,
|
||||
backoff_factor=1,
|
||||
status_forcelist=[429, 500, 502, 503, 504],
|
||||
allowed_methods=["HEAD", "GET", "OPTIONS", "POST"]
|
||||
)
|
||||
|
||||
adapter = HTTPAdapter(max_retries=retry_strategy)
|
||||
session.mount("http://", adapter)
|
||||
session.mount("https://", adapter)
|
||||
|
||||
return session
|
||||
|
||||
def post_reading(self, port: str, data: str) -> bool:
|
||||
"""Post a serial port reading to the backend"""
|
||||
try:
|
||||
url = f"{self.base_url}/api/readings/"
|
||||
payload = {
|
||||
'port': port,
|
||||
'data': data
|
||||
}
|
||||
|
||||
response = self.session.post(
|
||||
url,
|
||||
json=payload,
|
||||
timeout=self.timeout
|
||||
)
|
||||
|
||||
if response.status_code in [200, 201]:
|
||||
logger.info(f"Successfully posted reading to backend")
|
||||
return True
|
||||
else:
|
||||
logger.warning(f"Backend returned status {response.status_code}")
|
||||
return False
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Error posting reading to backend: {e}")
|
||||
return False
|
||||
|
||||
def get_latest_reading(self, port: Optional[str] = None) -> Optional[Dict[str, Any]]:
|
||||
"""Get the latest reading from backend"""
|
||||
try:
|
||||
url = f"{self.base_url}/api/readings/latest/"
|
||||
params = {'port': port} if port else {}
|
||||
|
||||
response = self.session.get(
|
||||
url,
|
||||
params=params,
|
||||
timeout=self.timeout
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
logger.warning(f"Backend returned status {response.status_code}")
|
||||
return None
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Error getting latest reading: {e}")
|
||||
return None
|
||||
|
||||
def get_readings(self, port: Optional[str] = None, limit: int = 10) -> Optional[list]:
|
||||
"""Get readings from backend"""
|
||||
try:
|
||||
url = f"{self.base_url}/api/readings/"
|
||||
params = {'limit': limit}
|
||||
if port:
|
||||
params['port'] = port
|
||||
|
||||
response = self.session.get(
|
||||
url,
|
||||
params=params,
|
||||
timeout=self.timeout
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
logger.warning(f"Backend returned status {response.status_code}")
|
||||
return None
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
logger.error(f"Error getting readings: {e}")
|
||||
return None
|
||||
|
||||
def health_check(self) -> bool:
|
||||
"""Check if backend is available"""
|
||||
try:
|
||||
url = f"{self.base_url}/api/health/"
|
||||
response = self.session.get(url, timeout=self.timeout)
|
||||
return response.status_code == 200
|
||||
except Exception as e:
|
||||
logger.error(f"Backend health check failed: {e}")
|
||||
return False
|
||||
Reference in New Issue
Block a user