● Zion Boggan
repos/Sightline/backend/app/api/routes/livealpr.py
zionboggan.com ↗
37 lines · python
History for this file →
1
"""Live-camera ALPR scan API: run the recognition engine over live DOT snapshot feeds.
2
 
3
  POST /alpr/scan-live   {camera_ids?, state?, limit, min_conf} -> scan a batch, ingest any plates
4
 
5
Runs synchronously (each camera = one HTTP fetch + one inference pass), so a batch can take
6
~10-30s. NOTE: public wide-area traffic cams rarely yield readable plates - 0 results is the
7
normal outcome; recognized plates flow through the standard ingest pipeline as real reads."""
8
from __future__ import annotations
9
 
10
from fastapi import APIRouter, Depends, HTTPException
11
from pydantic import BaseModel
12
from sqlalchemy.orm import Session
13
 
14
from app.api.deps import Perm, get_db, require
15
from app.models import User
16
 
17
router = APIRouter(tags=["live-alpr"])
18
 
19
MAX_LIMIT = 50
20
 
21
 
22
class ScanLiveReq(BaseModel):
23
    camera_ids: list[str] | None = None
24
    state: str | None = None
25
    limit: int = 20
26
    min_conf: float = 0.5
27
 
28
 
29
@router.post("/alpr/scan-live")
30
def scan_live(req: ScanLiveReq, db: Session = Depends(get_db),
31
              user: User = Depends(require(Perm.INGEST))):
32
    """Scan live-feed cameras for plates and ingest anything recognized (synchronous batch)."""
33
    from app.services.live_alpr_scan import scan_live_cameras
34
    if req.limit < 1 or req.limit > MAX_LIMIT:
35
        raise HTTPException(400, f"limit must be between 1 and {MAX_LIMIT}")
36
    return scan_live_cameras(db, camera_ids=req.camera_ids, state=req.state,
37
                             limit=req.limit, min_conf=req.min_conf, created_by=user.id)