You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.6 KiB
82 lines
2.6 KiB
"""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()
|
|
|