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.auth import AuthBp, get_jwt_secret, limiter
from frigate.api.defs.tags import Tags from frigate.api.defs.tags import Tags
from frigate.api.event import EventBp from frigate.api.event import EventBp
from frigate.api.export import ExportBp
from frigate.config import FrigateConfig from frigate.config import FrigateConfig
from frigate.const import CONFIG_DIR from frigate.const import CONFIG_DIR
from frigate.embeddings import EmbeddingsContext from frigate.embeddings import EmbeddingsContext
@ -45,7 +44,6 @@ logger = logging.getLogger(__name__)
bp = Blueprint("frigate", __name__) bp = Blueprint("frigate", __name__)
bp.register_blueprint(EventBp) bp.register_blueprint(EventBp)
bp.register_blueprint(ExportBp)
bp.register_blueprint(AuthBp) bp.register_blueprint(AuthBp)
router = APIRouter() router = APIRouter()

View File

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

View File

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

View File

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