Compare commits

..

No commits in common. "d87f8dc12ac792bd73283656c9ca911f9a9f73e3" and "fa8cd1c51e44064933f528902a955ed36658f8a3" have entirely different histories.

7 changed files with 40 additions and 330 deletions

View File

@ -270,8 +270,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -301,8 +300,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -340,8 +338,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -406,8 +403,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -441,8 +437,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -493,8 +488,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
/audio/transcribe:
put:
tags:
@ -516,8 +510,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -600,8 +593,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -643,8 +635,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -680,8 +671,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -716,8 +706,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -1640,12 +1629,8 @@ paths:
get:
tags:
- Preview
summary: Get preview clips for time range
description: |-
Gets all preview clips for a specified camera and time range.
Returns a list of preview video clips that overlap with the requested time period,
ordered by start time. Use camera_name='all' to get previews from all cameras.
Returns an error if no previews are found.
summary: Preview Ts
description: Get all mp4 previews relevant for time period.
operationId: preview_ts_preview__camera_name__start__start_ts__end__end_ts__get
parameters:
- name: camera_name
@ -1673,13 +1658,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PreviewModel'
title: >-
Response Preview Ts Preview Camera Name Start Start Ts
End End Ts Get
schema: {}
'422':
description: Validation Error
content:
@ -1690,12 +1669,8 @@ paths:
get:
tags:
- Preview
summary: Get preview clips for specific hour
description: |-
Gets all preview clips for a specific hour in a given timezone.
Converts the provided date/time from the specified timezone to UTC and retrieves
all preview clips for that hour. Use camera_name='all' to get previews from all cameras.
The tz_name should be a timezone like 'America/New_York' (use commas instead of slashes).
summary: Preview Hour
description: Get all mp4 previews relevant for time period given the timezone
operationId: >-
preview_hour_preview__year_month___day___hour___camera_name___tz_name__get
parameters:
@ -1736,13 +1711,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PreviewModel'
title: >-
Response Preview Hour Preview Year Month Day Hour
Camera Name Tz Name Get
schema: {}
'422':
description: Validation Error
content:
@ -1753,12 +1722,8 @@ paths:
get:
tags:
- Preview
summary: Get cached preview frame filenames
description: >-
Gets a list of cached preview frame filenames for a specific camera and
time range.
Returns an array of filenames for preview frames that fall within the specified time period,
sorted in chronological order. These are individual frame images cached for quick preview display.
summary: Get Preview Frames From Cache
description: Get list of cached preview frames
operationId: >-
get_preview_frames_from_cache_preview__camera_name__start__start_ts__end__end_ts__frames_get
parameters:
@ -1787,13 +1752,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
type: array
items:
type: string
title: >-
Response Get Preview Frames From Cache Preview Camera Name
Start Start Ts End End Ts Frames Get
schema: {}
'422':
description: Validation Error
content:
@ -1804,10 +1763,7 @@ paths:
get:
tags:
- Notifications
summary: Get VAPID public key
description: |-
Gets the VAPID public key for the notifications.
Returns the public key or an error if notifications are not enabled.
summary: Get Vapid Pub Key
operationId: get_vapid_pub_key_notifications_pubkey_get
responses:
'200':
@ -1819,10 +1775,7 @@ paths:
post:
tags:
- Notifications
summary: Register notifications
description: |-
Registers a notifications subscription.
Returns a success message or an error if the subscription is not provided.
summary: Register Notifications
operationId: register_notifications_notifications_register_post
requestBody:
content:
@ -1846,31 +1799,19 @@ paths:
get:
tags:
- Export
summary: Get exports
description: |-
Gets all exports from the database for cameras the user has access to.
Returns a list of exports ordered by date (most recent first).
summary: Get Exports
operationId: get_exports_exports_get
responses:
'200':
description: Successful Response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/ExportModel'
title: Response Get Exports Exports Get
schema: {}
/export/{camera_name}/start/{start_time}/end/{end_time}:
post:
tags:
- Export
summary: Start recording export
description: |-
Starts an export of a recording for the specified time range.
The export can be from recordings or preview footage. Returns the export ID if
successful, or an error message if the camera is invalid or no recordings/previews
are found for the time range.
summary: Export Recording
operationId: >-
export_recording_export__camera_name__start__start_time__end__end_time__post
parameters:
@ -1905,8 +1846,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/StartExportResponse'
schema: {}
'422':
description: Validation Error
content:
@ -1917,10 +1857,7 @@ paths:
patch:
tags:
- Export
summary: Rename export
description: |-
Renames an export.
NOTE: This changes the friendly name of the export, not the filename.
summary: Export Rename
operationId: export_rename_export__event_id__rename_patch
parameters:
- name: event_id
@ -1940,8 +1877,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -1952,7 +1888,7 @@ paths:
delete:
tags:
- Export
summary: Delete export
summary: Export Delete
operationId: export_delete_export__event_id__delete
parameters:
- name: event_id
@ -1966,8 +1902,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
schema: {}
'422':
description: Validation Error
content:
@ -1978,10 +1913,7 @@ paths:
get:
tags:
- Export
summary: Get a single export
description: |-
Gets a specific export by ID. The user must have access to the camera
associated with the export.
summary: Get Export
operationId: get_export_exports__export_id__get
parameters:
- name: export_id
@ -1995,8 +1927,7 @@ paths:
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/ExportModel'
schema: {}
'422':
description: Validation Error
content:
@ -3613,14 +3544,14 @@ paths:
required: false
schema:
type: number
default: 1759932070.40171
default: 1759928397.31333
title: After
- name: before
in: query
required: false
schema:
type: number
default: 1759935670.40172
default: 1759931997.313336
title: Before
responses:
'200':
@ -4874,47 +4805,6 @@ components:
required:
- subLabel
title: EventsSubLabelBody
ExportModel:
properties:
id:
type: string
title: Id
description: Unique identifier for the export
camera:
type: string
title: Camera
description: Camera name associated with this export
name:
type: string
title: Name
description: Friendly name of the export
date:
type: number
title: Date
description: Unix timestamp when the export was created
video_path:
type: string
title: Video Path
description: File path to the exported video
thumb_path:
type: string
title: Thumb Path
description: File path to the export thumbnail
in_progress:
type: boolean
title: In Progress
description: Whether the export is currently being processed
type: object
required:
- id
- camera
- name
- date
- video_path
- thumb_path
- in_progress
title: ExportModel
description: Model representing a single export.
ExportRecordingsBody:
properties:
playback:
@ -5054,37 +4944,6 @@ components:
- recordings
- preview
title: PlaybackSourceEnum
PreviewModel:
properties:
camera:
type: string
title: Camera
description: Camera name for this preview
src:
type: string
title: Src
description: Path to the preview video file
type:
type: string
title: Type
description: MIME type of the preview video (video/mp4)
start:
type: number
title: Start
description: Unix timestamp when the preview starts
end:
type: number
title: End
description: Unix timestamp when the preview ends
type: object
required:
- camera
- src
- type
- start
- end
title: PreviewModel
description: Model representing a single preview clip.
RegenerateDescriptionEnum:
type: string
enum:
@ -5187,28 +5046,6 @@ components:
- alert
- detection
title: SeverityEnum
StartExportResponse:
properties:
success:
type: boolean
title: Success
description: Whether the export was started successfully
message:
type: string
title: Message
description: Status or error message
export_id:
anyOf:
- type: string
- type: 'null'
title: Export Id
description: The export ID if successfully started
type: object
required:
- success
- message
title: StartExportResponse
description: Response model for starting an export.
SubmitPlusBody:
properties:
include_annotation:

View File

@ -23,7 +23,6 @@ from frigate.api.defs.response.classification_response import (
FaceRecognitionResponse,
FacesResponse,
)
from frigate.api.defs.response.generic_response import GenericResponse
from frigate.api.defs.tags import Tags
from frigate.config import FrigateConfig
from frigate.config.camera import DetectConfig
@ -112,7 +111,6 @@ def reclassify_face(request: Request, body: dict = None):
@router.post(
"/faces/train/{name}/classify",
response_model=GenericResponse,
summary="Classify and save a face training image",
description="""Adds a training image to a specific face name for face recognition.
Accepts either a training file from the train directory or an event_id to extract
@ -226,7 +224,6 @@ def train_face(request: Request, name: str, body: dict = None):
@router.post(
"/faces/{name}/create",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Create a new face name",
description="""Creates a new folder for a face name in the faces directory.
@ -252,7 +249,6 @@ async def create_face(request: Request, name: str):
@router.post(
"/faces/{name}/register",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Register a face image",
description="""Registers a face image for a specific face name by uploading an image file.
@ -320,7 +316,6 @@ async def recognize_face(request: Request, file: UploadFile):
@router.post(
"/faces/{name}/delete",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Delete face images",
description="""Deletes specific face images for a given face name. The image IDs must belong
@ -344,7 +339,6 @@ def deregister_faces(request: Request, name: str, body: DeleteFaceImagesBody):
@router.put(
"/faces/{old_name}/rename",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Rename a face name",
description="""Renames a face name in the system. The old name must exist and the new
@ -420,7 +414,6 @@ def reprocess_license_plate(request: Request, event_id: str):
@router.put(
"/reindex",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Reindex embeddings",
description="""Reindexes the embeddings for all tracked objects.
@ -473,7 +466,6 @@ def reindex_embeddings(request: Request):
@router.put(
"/audio/transcribe",
response_model=GenericResponse,
summary="Transcribe audio",
description="""Transcribes audio from a specific event.
Requires audio transcription to be enabled in the configuration. The event_id
@ -592,7 +584,6 @@ def get_classification_images(name: str):
@router.post(
"/classification/{name}/train",
response_model=GenericResponse,
summary="Train a classification model",
description="""Trains a specific classification model.
The name must exist in the classification models. Returns a success message or an error if the name is invalid.""",
@ -621,7 +612,6 @@ async def train_configured_model(request: Request, name: str):
@router.post(
"/classification/{name}/dataset/{category}/delete",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Delete classification dataset images",
description="""Deletes specific dataset images for a given classification model and category.
@ -663,7 +653,6 @@ def delete_classification_dataset_images(
@router.post(
"/classification/{name}/dataset/categorize",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Categorize a classification image",
description="""Categorizes a specific classification image for a given classification model and category.
@ -722,7 +711,6 @@ def categorize_classification_image(request: Request, name: str, body: dict = No
@router.post(
"/classification/{name}/train/delete",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Delete classification train images",
description="""Deletes specific train images for a given classification model.

View File

@ -1,30 +0,0 @@
from typing import List, Optional
from pydantic import BaseModel, Field
class ExportModel(BaseModel):
"""Model representing a single export."""
id: str = Field(description="Unique identifier for the export")
camera: str = Field(description="Camera name associated with this export")
name: str = Field(description="Friendly name of the export")
date: float = Field(description="Unix timestamp when the export was created")
video_path: str = Field(description="File path to the exported video")
thumb_path: str = Field(description="File path to the export thumbnail")
in_progress: bool = Field(
description="Whether the export is currently being processed"
)
class StartExportResponse(BaseModel):
"""Response model for starting an export."""
success: bool = Field(description="Whether the export was started successfully")
message: str = Field(description="Status or error message")
export_id: Optional[str] = Field(
default=None, description="The export ID if successfully started"
)
ExportsResponse = List[ExportModel]

View File

@ -1,17 +0,0 @@
from typing import List
from pydantic import BaseModel, Field
class PreviewModel(BaseModel):
"""Model representing a single preview clip."""
camera: str = Field(description="Camera name for this preview")
src: str = Field(description="Path to the preview video file")
type: str = Field(description="MIME type of the preview video (video/mp4)")
start: float = Field(description="Unix timestamp when the preview starts")
end: float = Field(description="Unix timestamp when the preview ends")
PreviewsResponse = List[PreviewModel]
PreviewFramesResponse = List[str]

View File

@ -19,12 +19,6 @@ from frigate.api.auth import (
)
from frigate.api.defs.request.export_recordings_body import ExportRecordingsBody
from frigate.api.defs.request.export_rename_body import ExportRenameBody
from frigate.api.defs.response.export_response import (
ExportModel,
ExportsResponse,
StartExportResponse,
)
from frigate.api.defs.response.generic_response import GenericResponse
from frigate.api.defs.tags import Tags
from frigate.const import EXPORT_DIR
from frigate.models import Export, Previews, Recordings
@ -40,13 +34,7 @@ logger = logging.getLogger(__name__)
router = APIRouter(tags=[Tags.export])
@router.get(
"/exports",
response_model=ExportsResponse,
summary="Get exports",
description="""Gets all exports from the database for cameras the user has access to.
Returns a list of exports ordered by date (most recent first).""",
)
@router.get("/exports")
def get_exports(
allowed_cameras: List[str] = Depends(get_allowed_cameras_for_filter),
):
@ -62,13 +50,7 @@ def get_exports(
@router.post(
"/export/{camera_name}/start/{start_time}/end/{end_time}",
response_model=StartExportResponse,
dependencies=[Depends(require_camera_access)],
summary="Start recording export",
description="""Starts an export of a recording for the specified time range.
The export can be from recordings or preview footage. Returns the export ID if
successful, or an error message if the camera is invalid or no recordings/previews
are found for the time range.""",
)
def export_recording(
request: Request,
@ -166,13 +148,7 @@ def export_recording(
@router.patch(
"/export/{event_id}/rename",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Rename export",
description="""Renames an export.
NOTE: This changes the friendly name of the export, not the filename.
""",
"/export/{event_id}/rename", dependencies=[Depends(require_role(["admin"]))]
)
async def export_rename(event_id: str, body: ExportRenameBody, request: Request):
try:
@ -202,12 +178,7 @@ async def export_rename(event_id: str, body: ExportRenameBody, request: Request)
)
@router.delete(
"/export/{event_id}",
response_model=GenericResponse,
dependencies=[Depends(require_role(["admin"]))],
summary="Delete export",
)
@router.delete("/export/{event_id}", dependencies=[Depends(require_role(["admin"]))])
async def export_delete(event_id: str, request: Request):
try:
export: Export = Export.get(Export.id == event_id)
@ -261,13 +232,7 @@ async def export_delete(event_id: str, request: Request):
)
@router.get(
"/exports/{export_id}",
response_model=ExportModel,
summary="Get a single export",
description="""Gets a specific export by ID. The user must have access to the camera
associated with the export.""",
)
@router.get("/exports/{export_id}")
async def get_export(export_id: str, request: Request):
try:
export = Export.get(Export.id == export_id)

View File

@ -19,13 +19,7 @@ logger = logging.getLogger(__name__)
router = APIRouter(tags=[Tags.notifications])
@router.get(
"/notifications/pubkey",
summary="Get VAPID public key",
description="""Gets the VAPID public key for the notifications.
Returns the public key or an error if notifications are not enabled.
""",
)
@router.get("/notifications/pubkey")
def get_vapid_pub_key(request: Request):
config = request.app.frigate_config
notifications_enabled = config.notifications.enabled
@ -45,13 +39,7 @@ def get_vapid_pub_key(request: Request):
return JSONResponse(content=utils.b64urlencode(raw_pub), status_code=200)
@router.post(
"/notifications/register",
summary="Register notifications",
description="""Registers a notifications subscription.
Returns a success message or an error if the subscription is not provided.
""",
)
@router.post("/notifications/register")
def register_notifications(request: Request, body: dict = None):
if request.app.frigate_config.auth.enabled:
# FIXME: For FastAPI the remote-user is not being populated

View File

@ -9,10 +9,6 @@ from fastapi import APIRouter, Depends
from fastapi.responses import JSONResponse
from frigate.api.auth import require_camera_access
from frigate.api.defs.response.preview_response import (
PreviewFramesResponse,
PreviewsResponse,
)
from frigate.api.defs.tags import Tags
from frigate.const import BASE_DIR, CACHE_DIR, PREVIEW_FRAME_TYPE
from frigate.models import Previews
@ -25,13 +21,7 @@ router = APIRouter(tags=[Tags.preview])
@router.get(
"/preview/{camera_name}/start/{start_ts}/end/{end_ts}",
response_model=PreviewsResponse,
dependencies=[Depends(require_camera_access)],
summary="Get preview clips for time range",
description="""Gets all preview clips for a specified camera and time range.
Returns a list of preview video clips that overlap with the requested time period,
ordered by start time. Use camera_name='all' to get previews from all cameras.
Returns an error if no previews are found.""",
)
def preview_ts(camera_name: str, start_ts: float, end_ts: float):
"""Get all mp4 previews relevant for time period."""
@ -87,13 +77,7 @@ def preview_ts(camera_name: str, start_ts: float, end_ts: float):
@router.get(
"/preview/{year_month}/{day}/{hour}/{camera_name}/{tz_name}",
response_model=PreviewsResponse,
dependencies=[Depends(require_camera_access)],
summary="Get preview clips for specific hour",
description="""Gets all preview clips for a specific hour in a given timezone.
Converts the provided date/time from the specified timezone to UTC and retrieves
all preview clips for that hour. Use camera_name='all' to get previews from all cameras.
The tz_name should be a timezone like 'America/New_York' (use commas instead of slashes).""",
)
def preview_hour(year_month: str, day: int, hour: int, camera_name: str, tz_name: str):
"""Get all mp4 previews relevant for time period given the timezone"""
@ -111,12 +95,7 @@ def preview_hour(year_month: str, day: int, hour: int, camera_name: str, tz_name
@router.get(
"/preview/{camera_name}/start/{start_ts}/end/{end_ts}/frames",
response_model=PreviewFramesResponse,
dependencies=[Depends(require_camera_access)],
summary="Get cached preview frame filenames",
description="""Gets a list of cached preview frame filenames for a specific camera and time range.
Returns an array of filenames for preview frames that fall within the specified time period,
sorted in chronological order. These are individual frame images cached for quick preview display.""",
)
def get_preview_frames_from_cache(camera_name: str, start_ts: float, end_ts: float):
"""Get list of cached preview frames"""