Remove the serial bridge's unused Django client
The bridge reads the COM port and streams SSE to the frontend; it never talks to Django. backend_client.py (a Django API client) and config.py (which held BACKEND_URL / API_ENDPOINT) were imported by nothing - app.py calls load_dotenv() and reads os.getenv directly, and the PyInstaller spec builds from app.py alone. Their presence implied a coupling that does not exist, and the stale BACKEND_URL=8000 in .env read as a misconfiguration rather than an inert value. Also drops the matching backend settings from .env.example, the now unnecessary 'requests' hidden import from the spec, and the two files from the SETUP.md tree. requests and urllib3 remain in requirements.txt - no bridge module uses them now, but pruning dependencies is a build concern left for a separate change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,9 +20,7 @@ ScalesApp/
|
|||||||
├── serial_bridge/ # Python serial reader (system tray)
|
├── serial_bridge/ # Python serial reader (system tray)
|
||||||
│ ├── app.py
|
│ ├── app.py
|
||||||
│ ├── serial_reader.py
|
│ ├── serial_reader.py
|
||||||
│ ├── backend_client.py
|
|
||||||
│ ├── tray_icon.py
|
│ ├── tray_icon.py
|
||||||
│ ├── config.py
|
|
||||||
│ ├── requirements.txt
|
│ ├── requirements.txt
|
||||||
│ ├── serial_bridge.spec
|
│ ├── serial_bridge.spec
|
||||||
│ └── .env.example
|
│ └── .env.example
|
||||||
|
|||||||
@@ -4,11 +4,6 @@ BAUD_RATE=9600
|
|||||||
TIMEOUT=1
|
TIMEOUT=1
|
||||||
READ_INTERVAL=0.5
|
READ_INTERVAL=0.5
|
||||||
|
|
||||||
# Backend Server Settings
|
|
||||||
BACKEND_URL=http://localhost:8000
|
|
||||||
API_ENDPOINT=/api/readings/
|
|
||||||
REQUEST_TIMEOUT=5
|
|
||||||
|
|
||||||
# Application Settings
|
# Application Settings
|
||||||
DEBUG=False
|
DEBUG=False
|
||||||
LOG_LEVEL=INFO
|
LOG_LEVEL=INFO
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
"""
|
|
||||||
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
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
"""
|
|
||||||
Configuration for Serial Bridge
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
|
|
||||||
load_dotenv()
|
|
||||||
|
|
||||||
# COM Port Settings
|
|
||||||
COM_PORT = os.getenv('COM_PORT', 'COM1')
|
|
||||||
BAUD_RATE = int(os.getenv('BAUD_RATE', 9600))
|
|
||||||
TIMEOUT = int(os.getenv('TIMEOUT', 1))
|
|
||||||
READ_INTERVAL = float(os.getenv('READ_INTERVAL', 0.5)) # seconds
|
|
||||||
|
|
||||||
# Backend Server Settings
|
|
||||||
BACKEND_URL = os.getenv('BACKEND_URL', 'http://localhost:8000')
|
|
||||||
API_ENDPOINT = os.getenv('API_ENDPOINT', '/api/readings/')
|
|
||||||
REQUEST_TIMEOUT = int(os.getenv('REQUEST_TIMEOUT', 5))
|
|
||||||
|
|
||||||
# Application Settings
|
|
||||||
APP_NAME = 'ScalesApp Serial Bridge'
|
|
||||||
DEBUG = os.getenv('DEBUG', 'False') == 'True'
|
|
||||||
LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO')
|
|
||||||
|
|
||||||
# System Tray Settings
|
|
||||||
SHOW_WINDOW_ON_START = os.getenv('SHOW_WINDOW_ON_START', 'False') == 'True'
|
|
||||||
AUTO_CONNECT = os.getenv('AUTO_CONNECT', 'True') == 'True'
|
|
||||||
|
|
||||||
# Retry Settings
|
|
||||||
MAX_RETRIES = int(os.getenv('MAX_RETRIES', 3))
|
|
||||||
RETRY_DELAY = int(os.getenv('RETRY_DELAY', 5)) # seconds
|
|
||||||
@@ -11,7 +11,7 @@ a = Analysis(
|
|||||||
pathex=[],
|
pathex=[],
|
||||||
binaries=[],
|
binaries=[],
|
||||||
datas=[],
|
datas=[],
|
||||||
hiddenimports=['serial', 'requests', 'pystray', 'PIL'],
|
hiddenimports=['serial', 'pystray', 'PIL'],
|
||||||
hookspath=[],
|
hookspath=[],
|
||||||
hooksconfig={},
|
hooksconfig={},
|
||||||
runtime_hooks=[],
|
runtime_hooks=[],
|
||||||
|
|||||||
Reference in New Issue
Block a user