Convert export endpoints to FastAPI

This commit is contained in:
Rui Alves 2024-09-15 18:45:37 +01:00
parent 349891b0a6
commit ce1c048adc
4 changed files with 53 additions and 57 deletions

View File

@ -22,7 +22,6 @@ from werkzeug.middleware.proxy_fix import ProxyFix
from frigate.api.auth import AuthBp, get_jwt_secret, limiter
from frigate.api.defs.tags import Tags
from frigate.api.event import EventBp
from frigate.api.export import ExportBp
from frigate.config import FrigateConfig
from frigate.const import CONFIG_DIR
from frigate.embeddings import EmbeddingsContext
@ -45,7 +44,6 @@ logger = logging.getLogger(__name__)
bp = Blueprint("frigate", __name__)
bp.register_blueprint(EventBp)
bp.register_blueprint(ExportBp)
bp.register_blueprint(AuthBp)
router = APIRouter()

View File

@ -8,3 +8,4 @@ class Tags(Enum):
media = "Media"
notifications = "Notifications"
review = "Review"
export = "Export"

View File

@ -5,54 +5,50 @@ from pathlib import Path
from typing import Optional
import psutil
from flask import (
Blueprint,
current_app,
jsonify,
make_response,
request,
)
from fastapi import APIRouter, Request
from fastapi.responses import JSONResponse
from peewee import DoesNotExist
from frigate.api.defs.tags import Tags
from frigate.const import EXPORT_DIR
from frigate.models import Export, Recordings
from frigate.record.export import PlaybackFactorEnum, RecordingExporter
logger = logging.getLogger(__name__)
ExportBp = Blueprint("exports", __name__)
router = APIRouter(tags=[Tags.export])
@ExportBp.route("/exports")
@router.get("/exports")
def get_exports():
exports = Export.select().order_by(Export.date.desc()).dicts().iterator()
return jsonify([e for e in exports])
return JSONResponse(content=[e for e in exports])
@ExportBp.route(
"/export/<camera_name>/start/<int:start_time>/end/<int:end_time>", methods=["POST"]
)
@ExportBp.route(
"/export/<camera_name>/start/<float:start_time>/end/<float:end_time>",
methods=["POST"],
)
def export_recording(camera_name: str, start_time, end_time):
if not camera_name or not current_app.frigate_config.cameras.get(camera_name):
return make_response(
jsonify(
@router.post("/export/{camera_name}/start/{start_time}/end/{end_time}")
def export_recording(
request: Request,
camera_name: str,
start_time: float,
end_time: float,
body: dict = None,
):
if not camera_name or not request.app.frigate_config.cameras.get(camera_name):
return JSONResponse(
content=(
{"success": False, "message": f"{camera_name} is not a valid camera."}
),
404,
status_code=404,
)
json: dict[str, any] = request.get_json(silent=True) or {}
json: dict[str, any] = body or {}
playback_factor = json.get("playback", "realtime")
friendly_name: Optional[str] = json.get("name")
if len(friendly_name or "") > 256:
return make_response(
jsonify({"success": False, "message": "File name is too long."}),
401,
return JSONResponse(
content=({"success": False, "message": "File name is too long."}),
status_code=401,
)
existing_image = json.get("image_path")
@ -69,15 +65,15 @@ def export_recording(camera_name: str, start_time, end_time):
)
if recordings_count <= 0:
return make_response(
jsonify(
return JSONResponse(
content=(
{"success": False, "message": "No recordings found for time range"}
),
400,
status_code=400,
)
exporter = RecordingExporter(
current_app.frigate_config,
request.app.frigate_config,
camera_name,
friendly_name,
existing_image,
@ -90,58 +86,58 @@ def export_recording(camera_name: str, start_time, end_time):
),
)
exporter.start()
return make_response(
jsonify(
return JSONResponse(
content=(
{
"success": True,
"message": "Starting export of recording.",
}
),
200,
status_code=200,
)
@ExportBp.route("/export/<id>/<new_name>", methods=["PATCH"])
def export_rename(id, new_name: str):
@router.patch("/export/{id}/{new_name}")
def export_rename(event_id, new_name: str):
try:
export: Export = Export.get(Export.id == id)
export: Export = Export.get(Export.id == event_id)
except DoesNotExist:
return make_response(
jsonify(
return JSONResponse(
content=(
{
"success": False,
"message": "Export not found.",
}
),
404,
status_code=404,
)
export.name = new_name
export.save()
return make_response(
jsonify(
return JSONResponse(
content=(
{
"success": True,
"message": "Successfully renamed export.",
}
),
200,
status_code=200,
)
@ExportBp.route("/export/<id>", methods=["DELETE"])
def export_delete(id: str):
@router.delete("/export/{event_id}", methods=["DELETE"])
def export_delete(event_id: str):
try:
export: Export = Export.get(Export.id == id)
export: Export = Export.get(Export.id == event_id)
except DoesNotExist:
return make_response(
jsonify(
return JSONResponse(
content=(
{
"success": False,
"message": "Export not found.",
}
),
404,
status_code=404,
)
files_in_use = []
@ -158,11 +154,11 @@ def export_delete(id: str):
continue
if export.video_path.split("/")[-1] in files_in_use:
return make_response(
jsonify(
return JSONResponse(
content=(
{"success": False, "message": "Can not delete in progress export."}
),
400,
status_code=400,
)
Path(export.video_path).unlink(missing_ok=True)
@ -171,12 +167,12 @@ def export_delete(id: str):
Path(export.thumb_path).unlink(missing_ok=True)
export.delete_instance()
return make_response(
jsonify(
return JSONResponse(
content=(
{
"success": True,
"message": "Successfully deleted export.",
}
),
200,
status_code=200,
)

View File

@ -3,7 +3,7 @@ import logging
from fastapi import FastAPI
from frigate.api import app as main_app
from frigate.api import media, notification, preview, review
from frigate.api import export, media, notification, preview, review
from frigate.plus import PlusApi
from frigate.ptz.onvif import OnvifController
from frigate.stats.emitter import StatsEmitter
@ -31,6 +31,7 @@ def create_fastapi_app(
app.include_router(preview.router)
app.include_router(notification.router)
app.include_router(review.router)
app.include_router(export.router)
# App Properties
app.frigate_config = frigate_config
app.detected_frames_processor = detected_frames_processor