Initial commit: digital reception monorepo (M1-M11 + demo extensions)
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""HTTP клиенты к face-service и apps/api для минимального video-ingest."""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import base64
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FaceServiceClient:
|
||||
def __init__(self, base_url: str | None = None) -> None:
|
||||
self.base_url = (base_url or os.getenv("FACE_SERVICE_URL", "http://localhost:8001")).rstrip("/")
|
||||
|
||||
def embed(self, jpeg_bytes: bytes) -> tuple[list[float], float] | None:
|
||||
"""Возвращает (embedding, quality) или None если лицо не найдено."""
|
||||
b64 = base64.b64encode(jpeg_bytes).decode("ascii")
|
||||
r = requests.post(f"{self.base_url}/embed", json={"frame": b64}, timeout=10)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
if data is None:
|
||||
return None
|
||||
return data["embedding"], data["quality"]
|
||||
|
||||
def save_track_embedding(
|
||||
self,
|
||||
jpeg_bytes: bytes,
|
||||
track_id: str,
|
||||
camera_id: str,
|
||||
captured_at: datetime,
|
||||
) -> dict[str, Any] | None:
|
||||
b64 = base64.b64encode(jpeg_bytes).decode("ascii")
|
||||
r = requests.post(
|
||||
f"{self.base_url}/track-embeddings",
|
||||
json={
|
||||
"frame": b64,
|
||||
"track_id": track_id,
|
||||
"camera_id": camera_id,
|
||||
"captured_at": captured_at.isoformat(),
|
||||
},
|
||||
timeout=10,
|
||||
)
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
|
||||
class ReceptionApiClient:
|
||||
def __init__(self, base_url: str | None = None) -> None:
|
||||
self.base_url = (base_url or os.getenv("API_BASE_URL", "http://localhost:4000")).rstrip("/")
|
||||
|
||||
def create_track(self, camera_name: str, first_seen_at: datetime) -> dict[str, Any]:
|
||||
r = requests.post(
|
||||
f"{self.base_url}/ingest/tracks",
|
||||
json={"cameraName": camera_name, "firstSeenAt": first_seen_at.isoformat()},
|
||||
timeout=10,
|
||||
)
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
def add_event(
|
||||
self,
|
||||
track_id: str,
|
||||
event_type: str,
|
||||
camera_name: str,
|
||||
occurred_at: datetime,
|
||||
zone_code: str | None = None,
|
||||
) -> dict[str, Any]:
|
||||
body = {
|
||||
"trackId": track_id,
|
||||
"type": event_type,
|
||||
"cameraName": camera_name,
|
||||
"occurredAt": occurred_at.isoformat(),
|
||||
}
|
||||
if zone_code:
|
||||
body["zoneCode"] = zone_code
|
||||
r = requests.post(f"{self.base_url}/ingest/track-events", json=body, timeout=10)
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
Reference in New Issue
Block a user