Add endpoint to get camera snapshot url

This commit is contained in:
sosokker 2024-05-12 18:05:54 +07:00
parent 9598e6416b
commit 99f36b10b8
3 changed files with 62 additions and 1 deletions

View File

@ -2,7 +2,7 @@ import uvicorn
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from routers import video, weather, prediction from routers import video, weather, prediction, camera
app = FastAPI( app = FastAPI(
@ -32,6 +32,7 @@ app.add_middleware(
app.include_router(video.router, prefix="/camera") app.include_router(video.router, prefix="/camera")
app.include_router(weather.router, prefix="/weather") app.include_router(weather.router, prefix="/weather")
app.include_router(prediction.router, prefix="/weather") app.include_router(prediction.router, prefix="/weather")
app.include_router(camera.router, prefix="/camera")
@app.get("/") @app.get("/")
def read_root(): def read_root():

View File

@ -0,0 +1,35 @@
from datetime import datetime, timedelta
from minio.error import InvalidResponseError
from pytz import UTC
from config import VIDEO_BUCKET
from database import minio_client
def list_objects_with_timestamp(bucket_name: str = VIDEO_BUCKET) -> list[tuple[str, datetime]]:
"""List objects in the specified bucket with their last modified timestamp"""
try:
objects = minio_client.list_objects(bucket_name, recursive=True)
jpeg_objects = [(obj.object_name, obj.last_modified) for obj in objects if obj.object_name.endswith('.jpg') or obj.object_name.endswith('.jpeg')]
return jpeg_objects
except InvalidResponseError as err:
print(err)
return []
def filter_objects_by_date(objects_with_timestamp: list, interval: str) -> list:
"""List objects with timestamp within the specified interval. Supported intervals: 'today', 'week', 'month', 'all'"""
now_datetime = datetime.now(UTC)
if interval == "today":
start_datetime = now_datetime - timedelta(days=1)
elif interval == "week":
start_datetime = now_datetime - timedelta(days=7)
elif interval == "month":
start_datetime = now_datetime - timedelta(days=30)
elif interval == "all":
start_datetime = datetime.min.replace(tzinfo=UTC) # Consider all dates
else:
raise ValueError("Invalid interval. Supported intervals: 'today', 'week', 'month', 'all'")
return [obj for obj, timestamp in objects_with_timestamp if start_datetime <= timestamp <= now_datetime]

View File

@ -0,0 +1,25 @@
from datetime import timedelta
from fastapi import APIRouter, HTTPException
from query.camera import list_objects_with_timestamp, filter_objects_by_date
from config import VIDEO_BUCKET
from database import minio_client
router = APIRouter()
@router.get("/snapshot/{interval}", response_model=list[str])
async def get_snapshot(interval: str):
"""Return the list of URLs of camera snapshot within the specified interval. Supported intervals: 'today', 'week', 'month', 'all'"""
try:
res = filter_objects_by_date(list_objects_with_timestamp(), interval)
except ValueError as err:
raise HTTPException(status_code=400, detail=str(err))
if not res:
raise HTTPException(status_code=404, detail="No snapshot found")
return [minio_client.presigned_get_object(VIDEO_BUCKET, obj, expires=timedelta(days=1), response_headers={'response-content-type': 'image/jpeg'}) for obj in res]