From f76bb9cfb8a1d419aca78f0542a8d97c9b1cafba Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Thu, 5 Mar 2026 12:52:17 -0600 Subject: [PATCH] add profile API endpoints (GET /profiles, GET/PUT /profile) --- frigate/api/app.py | 41 +++++++++++++++++++++++++++- frigate/api/defs/request/app_body.py | 6 ++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/frigate/api/app.py b/frigate/api/app.py index 2472b5080..3ef0cccab 100644 --- a/frigate/api/app.py +++ b/frigate/api/app.py @@ -31,7 +31,11 @@ from frigate.api.auth import ( require_role, ) from frigate.api.defs.query.app_query_parameters import AppTimelineHourlyQueryParameters -from frigate.api.defs.request.app_body import AppConfigSetBody, MediaSyncBody +from frigate.api.defs.request.app_body import ( + AppConfigSetBody, + MediaSyncBody, + ProfileSetBody, +) from frigate.api.defs.tags import Tags from frigate.config import FrigateConfig from frigate.config.camera.updater import ( @@ -201,6 +205,41 @@ def config(request: Request): return JSONResponse(content=config) +@router.get("/profiles", dependencies=[Depends(allow_any_authenticated())]) +def get_profiles(request: Request): + """List all available profiles and the currently active profile.""" + profile_manager = request.app.profile_manager + return JSONResponse(content=profile_manager.get_profile_info()) + + +@router.get("/profile/active", dependencies=[Depends(allow_any_authenticated())]) +def get_active_profile(request: Request): + """Get the currently active profile.""" + config_obj: FrigateConfig = request.app.frigate_config + return JSONResponse(content={"active_profile": config_obj.active_profile}) + + +@router.put("/profile/set", dependencies=[Depends(require_role(["admin"]))]) +def set_profile(request: Request, body: ProfileSetBody): + """Activate or deactivate a profile.""" + profile_manager = request.app.profile_manager + err = profile_manager.activate_profile(body.profile) + if err: + return JSONResponse( + content={"success": False, "message": err}, + status_code=400, + ) + request.app.dispatcher.publish( + "profile/state", body.profile or "none", retain=True + ) + return JSONResponse( + content={ + "success": True, + "active_profile": body.profile, + } + ) + + @router.get("/ffmpeg/presets", dependencies=[Depends(allow_any_authenticated())]) def ffmpeg_presets(): """Return available ffmpeg preset keys for config UI usage.""" diff --git a/frigate/api/defs/request/app_body.py b/frigate/api/defs/request/app_body.py index 3d2ab5961..1640da739 100644 --- a/frigate/api/defs/request/app_body.py +++ b/frigate/api/defs/request/app_body.py @@ -30,6 +30,12 @@ class AppPutRoleBody(BaseModel): role: str +class ProfileSetBody(BaseModel): + profile: Optional[str] = Field( + default=None, description="Profile name to activate, or null to deactivate" + ) + + class MediaSyncBody(BaseModel): dry_run: bool = Field( default=True, description="If True, only report orphans without deleting them"