add REST API endpoint for image retrieval; implement error handling and response formatting
All checks were successful
Build Backend Application and Docker Image / build-docker (push) Successful in 8m48s

This commit is contained in:
Siwat Sirichai 2025-07-06 21:27:17 +07:00
parent b5ae2801c1
commit 22370e2040
2 changed files with 41 additions and 367 deletions

42
app.py
View file

@ -14,8 +14,9 @@ import asyncio
import psutil
import zipfile
from urllib.parse import urlparse
from fastapi import FastAPI, WebSocket
from fastapi import FastAPI, WebSocket, HTTPException
from fastapi.websockets import WebSocketDisconnect
from fastapi.responses import Response
from websockets.exceptions import ConnectionClosedError
from ultralytics import YOLO
@ -121,6 +122,45 @@ def fetch_snapshot(url: str):
logger.error(f"Exception fetching snapshot from {url}: {str(e)}")
return None
####################################################
# REST API endpoint for image retrieval
####################################################
@app.get("/camera/{camera_id}/image")
async def get_camera_image(camera_id: str):
"""
Get the current frame from a camera as JPEG image
"""
try:
with streams_lock:
if camera_id not in streams:
raise HTTPException(status_code=404, detail=f"Camera {camera_id} not found or not active")
stream = streams[camera_id]
buffer = stream["buffer"]
if buffer.empty():
raise HTTPException(status_code=404, detail=f"No frame available for camera {camera_id}")
# Get the latest frame (non-blocking)
try:
frame = buffer.queue[-1] # Get the most recent frame without removing it
except IndexError:
raise HTTPException(status_code=404, detail=f"No frame available for camera {camera_id}")
# Encode frame as JPEG
success, buffer_img = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 85])
if not success:
raise HTTPException(status_code=500, detail="Failed to encode image as JPEG")
# Return image as binary response
return Response(content=buffer_img.tobytes(), media_type="image/jpeg")
except HTTPException:
raise
except Exception as e:
logger.error(f"Error retrieving image for camera {camera_id}: {str(e)}", exc_info=True)
raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
####################################################
# Detection and frame processing functions
####################################################