DEVELOPER CENTER · Universal v1.9.59 Fix30

Securex Nvr Plugin Developer Docs

Extend official Frigate through the Universal Plugin API. Keep one feature per plugin so it can be installed, upgraded, and removed independently without repeatedly patching Frigate core.

Plugin baselineUniversal v1.9.59 Fix30Empty Base
Frigatev0.18.0Recommended baseline
Regular plugin ZIP≤ 16 MBZIP
UI languages3简 / 繁 / EN
01
QUICK START

Create your first plugin in 5 minutes

Start with the smallest working skeleton, then add settings UI, background work, and Store capabilities only when needed.

1Define scopeOne feature per plugin.
2Create skeletonmanifest.json + plugin.py
3Validate locallyFirst-load/update, hot-save, toggle, uninstall.
4PublishZIP and submit for review.
Core ruleIf a feature can live in a plugin, do not patch Frigate core. This keeps Frigate upgrades substantially easier to maintain.
02
PACKAGE

Package structure

Recommended structure

tynvr_module_example/
├── manifest.json
├── plugin.py
├── config.example.yml
├── README.md
└── assets/
    └── plugin.css

Packaging rules

  • Keep exactly one plugin root at ZIP top level.
  • manifest.json and plugin.py are required.
  • Keep regular plugin ZIPs at or below 16 MB.
  • Do not bundle large models, PyTorch, CUDA, or other heavy runtimes into a regular plugin ZIP.
AvoidDo not ship __pycache__, temporary logs, training outputs, tokens, or database backups in the release ZIP.
03
MANIFEST

manifest.json

Defines plugin identity, version, Settings UI, navigation mounts, and actions.

manifest.jsonMinimal practical example
{
  "id": "tynvr_module_example",
  "name": "Example Plugin",
  "version": "1.0.0",
  "description": "Example Securex Nvr plugin",
  "enabled": true,
  "kind": "tynvr_core_module",
  "module_id": "example",
  "order": 50,
  "config_apply": "hot",
  "first_install_restart": true,
  "navigation_user_toggle": true,
  "navigation_default_visible": true,
  "actions": [
    {"id": "reload", "label": "Reload"}
  ],
  "navigation": {
    "key": "example",
    "mount": "settings.sidebar.plugins",
    "label": "Example Plugin",
    "url": "/api/example/?embed=1",
    "view": "iframe",
    "order": 50,
    "icon": "puzzle"
  }
}
idStable unique ID; tynvr_module_xxx is recommended.
versionIncrement for every Store release.
navigationDeclare navigation dynamically; provide a stable key explicitly.
navigation_user_toggleLets users control sidebar visibility; upgrades must preserve the user choice.
config_applyPrefer hot: ordinary settings apply immediately without restarting Frigate.
first_install_restartA first install/code update may require one reload; ordinary config saves should not.
actionsExplicit operations exposed to plugin management.
04
PYTHON

plugin.py / class Plugin

Current Universal plugins derive from FrigatePlugin. Keep routes, config, background threads, and shutdown behavior inside the plugin instance.

plugin.pyRecommended skeleton
from pathlib import Path
from typing import Any
from fastapi import APIRouter, Depends
from frigate.api.auth import require_role
from frigate.plugins.base import FrigatePlugin

class Plugin(FrigatePlugin):
    def __init__(self, frigate_config: Any, plugin_dir: Path, stop_event=None):
        super().__init__(frigate_config, plugin_dir, stop_event)
        self._router = APIRouter(tags=["example"])
        self._build_routes()

    @property
    def router(self):
        return self._router

    def _build_routes(self):
        @self._router.get(
            "/api/example/status",
            dependencies=[Depends(require_role(["admin"]))],
        )
        def status():
            return {"ok": True}

    def get_public_config(self):
        return {"enabled": True}

    def update_config(self, payload):
        return {"success": True}

    def run_action(self, action, payload):
        return {"success": action == "reload"}

    def stop(self):
        pass
RecommendationReturn only browser-safe fields from get_public_config(). Never expose full tokens, passwords, or private keys there.
06
CONFIG & DATA

Configuration, state & user data

config.ymlPersistent plugin configuration. Preserve on upgrade.
*.dbQueues, history, and local indexes. Do not delete during upgrades.
*_status.jsonRuntime status and recoverable state.
.runtime/Keep heavy runtimes separate from plugin code so upgrades can reuse them.
Upgrade ruleNew config fields need safe defaults and backward-compatible loading. Ordinary saves should hot-apply; upgrades must not overwrite sidebar visibility, tokens, runtimes, or persistent data.
07
SECURITY

Permissions, secrets & sensitive actions

01

Least privilege: normal reads require authenticated access; config changes, tokens, model deployment, and hardware control require administrator permission.

02

Secret: keep full tokens, passwords, and keys server-side. UI should show only configured state or a masked value.

03

CSRF / POST: never use GET for state changes. Same-origin Frigate POST/PUT/PATCH/DELETE should explicitly send X-CSRF-TOKEN: 1 (and preferably X-CACHE-BYPASS: 1). Universal has a generic bridge, but plugins should still implement requests correctly.

04

Input validation: validate paths, URLs, command arguments, and upload names; never concatenate untrusted input directly into shell commands.

08
RUNTIME

Background work, networking & recovery

Do not block requests

Run training, downloads, synchronization, and scans in background threads/workers. Expose status, progress, stop controls, and useful errors.

No blocking loopback HTTP in async routes

Do not call Frigate loopback APIs with blocking urllib/requests inside async FastAPI routes; this can deadlock the event loop until timeout. Use a threadpool/async client or reuse already available data.

Network operations must recover

Use bounded timeouts, backoff after failures, chunking plus checksums for large files, and idempotent retry behavior where possible.

Logs & runtimes must be maintainable

Provide log-clear controls using in-place truncation so active Worker/training processes continue. Keep heavy runtimes and artifacts outside plugin code so upgrades replace only plugin code.

09
OFFICIAL AI REFERENCE

Official AI plugin reference

Current official baselines that demonstrate the expected platform contracts.

Securex AI Cloud v1.1.7

  • Shadow A/B compares production and candidate models on the same frame without switching the production detector.
  • Explore manual review submits on Yes/No; “Submitted” appears only after Store confirms correct/incorrect.
  • Manual reviews use sample_reason=manual and appear as Correct/Incorrect · Manual review in Images.
  • Frigate event/snapshot reads for manual submission run in a threadpool to avoid async loopback deadlocks.

Securex AI Training Worker v1.0.11

  • Training runtime is separated from plugin code; plugin upgrades/restarts preserve the environment and artifacts.
  • Reattaches to running jobs instead of restarting training.
  • Installer and Worker logs can be truncated in place without stopping active processes.
  • Embedded UI follows the Frigate theme and state-changing operations follow Frigate CSRF rules.
10
I18N & RESPONSIVE

Simplified / Traditional / English & responsive UI

EN

Plugin names, descriptions, buttons, errors, and settings fields should be complete in all three languages—not just page titles.

  • English strings are often longer; buttons and cards must not depend on Chinese-only fixed widths.
  • Test at 1366px, tablet widths, and narrow embedded Settings views.
  • Wrap or truncate logs, long IDs, and URLs so they cannot break the layout.
11
VERSIONING

Versioning, upgrades & uninstall

1.0.0Initial release
1.0.1Compatible fix
1.1.0New capability

When upgrading plugin code, preserve user config, sidebar visibility preferences, and persistent data; ordinary config saves should hot-apply. During uninstall, distinguish removing plugin code from deleting user data; destructive cleanup must be explicit.

12
RELEASE CHECKLIST

Release checklist

ZIP structure is correctmanifest.json / plugin.py

Install and enable workFresh install test

Restart recovery worksState survives Frigate restart

Upgrade preserves dataconfig / db / status

No stale navigation after uninstallDynamic navigation verified

All three languages complete简 / 繁 / EN

No narrow-screen overflow1366 / tablet / embed

Network failures recovertimeout / retry / resume

No secret leakageBrowser and log audit

State-changing requests pass CSRFX-CSRF-TOKEN / POST / PUT / DELETE

Hot-save does not restart Frigateconfig_apply=hot

Upgrade preserves sidebar preferencenavigation_visible

No blocking loopback in async routesthreadpool / async client

Version matches Store metadatamanifest / catalog / ZIP

READY TO SHIP

Plugin ready?

Upload the ZIP after completing the checklist. Store review focuses on security, compatibility, upgrade retention, localization, and UI completeness.

Sign in to submit