Update Contec monitor service, parser, dashboard and tunneling
This commit is contained in:
+38
-20
@@ -6,6 +6,17 @@ from config import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_http_client: Optional[httpx.AsyncClient] = None
|
||||
|
||||
def get_http_client() -> httpx.AsyncClient:
|
||||
global _http_client
|
||||
if _http_client is None or _http_client.is_closed:
|
||||
_http_client = httpx.AsyncClient(
|
||||
timeout=httpx.Timeout(connect=3.0, read=5.0, write=3.0, pool=3.0),
|
||||
limits=httpx.Limits(max_keepalive_connections=5, max_connections=10)
|
||||
)
|
||||
return _http_client
|
||||
|
||||
async def forward_vitals_to_api(vitals: NormalizedVitals) -> bool:
|
||||
"""
|
||||
Attempts to POST the normalized vitals to the configured target API
|
||||
@@ -15,6 +26,13 @@ async def forward_vitals_to_api(vitals: NormalizedVitals) -> bool:
|
||||
import os
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
# Strip heavy wave sample arrays before REST transmission (cloud APIs only ingest vital signs)
|
||||
payload = vitals.model_dump(mode="json")
|
||||
payload.pop("ecg_wave", None)
|
||||
payload.pop("pleth_wave", None)
|
||||
|
||||
client = get_http_client()
|
||||
|
||||
# 1. Forward to primary target API (e.g. Injomo Dev Workflow)
|
||||
primary_url = settings.target_api_url
|
||||
primary_success = False
|
||||
@@ -23,17 +41,17 @@ async def forward_vitals_to_api(vitals: NormalizedVitals) -> bool:
|
||||
primary_headers = headers.copy()
|
||||
if settings.api_token:
|
||||
primary_headers["Authorization"] = f"Bearer {settings.api_token}"
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
response = await client.post(
|
||||
primary_url,
|
||||
json=vitals.model_dump(mode="json"),
|
||||
headers=primary_headers
|
||||
)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Successfully forwarded vitals to primary API for device {vitals.device_id}")
|
||||
primary_success = True
|
||||
response = await client.post(
|
||||
primary_url,
|
||||
json=payload,
|
||||
headers=primary_headers
|
||||
)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Successfully forwarded vitals to primary API for device {vitals.device_id}")
|
||||
primary_success = True
|
||||
except Exception as e:
|
||||
logger.error(f"Error forwarding to primary API: {e}")
|
||||
err_msg = str(e).strip() or "timeout / connection reset"
|
||||
logger.warning(f"Error forwarding to primary API: {type(e).__name__} ({err_msg})")
|
||||
|
||||
# 2. Forward to Render Cloud Server
|
||||
render_url = "https://contectfiveparamonitor.onrender.com/api/push-vitals"
|
||||
@@ -48,16 +66,16 @@ async def forward_vitals_to_api(vitals: NormalizedVitals) -> bool:
|
||||
if settings.api_token:
|
||||
url_with_key = f"{render_url}?api_key={settings.api_token}"
|
||||
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
response = await client.post(
|
||||
url_with_key,
|
||||
json=vitals.model_dump(mode="json"),
|
||||
headers=headers
|
||||
)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Successfully forwarded vitals to Render Cloud for device {vitals.device_id}")
|
||||
render_success = True
|
||||
response = await client.post(
|
||||
url_with_key,
|
||||
json=payload,
|
||||
headers=headers
|
||||
)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Successfully forwarded vitals to Render Cloud for device {vitals.device_id}")
|
||||
render_success = True
|
||||
except Exception as e:
|
||||
logger.error(f"Error forwarding to Render Cloud: {e}")
|
||||
err_msg = str(e).strip() or "timeout / connection reset"
|
||||
logger.warning(f"Error forwarding to Render Cloud: {type(e).__name__} ({err_msg})")
|
||||
|
||||
return primary_success or render_success
|
||||
|
||||
Reference in New Issue
Block a user