Unofficial UniFi Protect Python API and CLI¶
Documentation: https://uiprotect.readthedocs.io
Source Code: https://github.com/uilibs/uiprotect
Python API for UniFi Protect (Unofficial)
Looking for maintainers¶
This project is looking for maintainers.
Installation¶
Install this via pip (or your favorite package manager):
pip install uiprotect
Developer Setup¶
The recommended way to develop is using the provided devcontainer with VS Code:
- Install VS Code and the Dev Containers extension
- Open the project in VS Code
- When prompted, click "Reopen in Container" (or use Command Palette: "Dev Containers: Reopen in Container")
- The devcontainer will automatically set up Python, Poetry, pre-commit hooks, and all dependencies
Alternatively, if you want to develop natively without devcontainer:
| Bash | |
|---|---|
Subscribing to events¶
ProtectApiClient exposes two parallel websocket contracts. The raw
subscribe_events_websocket continues to deliver WSSubscriptionMessage
frames for advanced callers, and the typed subscribe_events API
delivers (ProtectEvent, EventChange) pairs intended for application
code. The typed path goes through the Public Integration API, so the
ProtectApiClient must be configured with an API key and
update_public() must have been called at least once before calling
subscribe_events. The raw subscribe_events_websocket path does not
require an API key.
Notes:
subscribe_eventsdelivers only events whoseEventTypemaps to a non-OTHERProtectEventChannel(detection / sensor / alarm-hub / access). Administrative events such asprovision,factoryResetandfwUpdateare dropped. Callers that need the unfiltered stream should usesubscribe_events_websocket.event.rawis a permanent escape hatch onto the underlying private-APIEventmodel when the public contract does not expose the field you need. In particular, smart-detect detected attributes (license-plate text, face-match name) are not available over the public API today, so consumers that need them must fall back to the private path viaevent.raw.EventChange.UPDATEDmay carry no public-visible delta — diffevent.rawif you need to know exactly what changed.protect.active_events(device_id=...)returns the in-flight set, derived directly from the public bootstrap cache. Useful for restoring binary-sensor state after a reload — it works before anysubscribe_eventscall as long asupdate_public()has primed the cache.- All runtime state is sourced from
public_bootstrap: lifecycle/active state frompublic_bootstrap.events, credential-event identity frompublic_bootstrap.ulp_users(UniFi Identity), andevent.device_macfrom the bootstrap device stores. All are refreshed byupdate_public()— including automatically on websocket reconnect — and resolve with eventual consistency: anidentitythat resolves toUnknownIdentity(reason="ulp_user_not_cached")for a freshly-enrolled ULP user, or adevice_macofNonefor a device not yet in the bootstrap, both fill in on the nextupdate_public()/ reconnect resync.
History¶
This project was split off from pyunifiprotect because that project changed its license to one that would not be accepted in Home Assistant. This project is committed to keeping the MIT license.
Credits¶
- Bjarne Riis (@briis) for the original pyunifiprotect package
- Christopher Bailey (@AngellusMortis) for the maintaining the pyunifiprotect package
Contributors ✨¶
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
uiprotect is an unofficial API for UniFi Protect. There is no affiliation with Ubiquiti.
This module communicates with UniFi Protect surveillance software installed on a UniFi OS Console such as a Ubiquiti CloudKey+ or UniFi Dream Machine Pro.
The API is not documented by Ubiquiti, so there might be misses and/or frequent changes in this module, as Ubiquiti evolves the software.
The module is primarily written for the purpose of being used in Home Assistant core integration for UniFi Protect but might be used for other purposes also.
Documentation¶
Full documentation for the project.
Requirements¶
If you want to install uiprotect natively, the below are the requirements:
- UniFi Protect version 6.0+
- Only UniFi Protect version 6 and newer are supported. The library is generally tested against the latest stable version and the latest EA version.
- Python 3.11+
- POSIX compatible system
- Library is only tested on Linux, specifically the latest Debian version available for the official Python Docker images, but there is no reason the library should not work on any Linux distro or macOS.
- PyAV (av) - included as a dependency
- PyAV is used for audio streaming to camera speakers (talkback feature)
Alternatively you can use the provided Docker container, in which case the only requirement is Docker or another OCI compatible orchestrator (such as Kubernetes or podman).
Windows is not supported. If you need to use uiprotect on Windows, use Docker Desktop and the provided docker container or WSL.
Install¶
From PyPi¶
uiprotect is available on PyPi:
| Bash | |
|---|---|
To use the command-line interface, install the cli extra (it pulls in typer):
| Bash | |
|---|---|
From GitHub¶
| Bash | |
|---|---|
Using Docker Container¶
A Docker container is also provided, so you do not need to install/manage Python as well. You can add the following to your .bashrc or similar.
| Bash | |
|---|---|
Some notes about the Docker version since it is running inside a container:
- You can update at any time using the command
docker pull ghcr.io/uilibs/uiprotect:latest - Your local current working directory (
$PWD) will automatically be mounted to/datainside of the container. For commands that output files, this is the only path you can write to and have the file persist. - The container supports
linux/amd64andlinux/arm64natively. This means it will also work well on macOS or Windows using Docker Desktop. TZshould be the Olson timezone name for the timezone your UniFi Protect instance is in.- For more details on
TZand other environment variables, check the command line docs
Quickstart¶
CLI¶
[!WARNING] Ubiquiti SSO accounts are not supported and actively discouraged from being used. There is no option to use MFA. You are expected to use local access user.
uiprotectis not designed to allow you to use your owner account to access the console or to be used over the public internet as both pose a security risk.
Available CLI Commands¶
Top-level commands:
uiprotect shell- Start an interactive Python shell with the API clientuiprotect create-api-key <name>- Create a new API key for authenticationuiprotect get-meta-info- Get metadata informationuiprotect generate-sample-data- Generate sample data for testinguiprotect profile-ws- Profile WebSocket performanceuiprotect decode-ws-msg- Decode WebSocket messages
Device management commands:
uiprotect nvr- NVR information and settingsuiprotect events- Event management and exportuiprotect cameras- Camera managementuiprotect lights- Light device managementuiprotect sensors- Sensor managementuiprotect viewers- Viewer managementuiprotect liveviews- Live view configurationuiprotect chimes- Chime managementuiprotect doorlocks- Door lock managementuiprotect aiports- AI port management
For more details on any command, use uiprotect <command> --help.
Python¶
UniFi Protect itself is 100% async, so as such this library is primarily designed to be used in an async context.
The main interface for the library is the uiprotect.ProtectApiClient:
TODO / Planned / Not Implemented¶
Switching from Protect Private API to the New Public API
Generally any feature missing from the library is planned to be done eventually / nice to have with the following exceptions
UniFi OS Features¶
Anything that is strictly a UniFi OS feature. If it is ever done, it will be in a separate library that interacts with this one. Examples include:
- Managing RAID and disks
- Creating and managing users
Remote Access / Ubiquiti Cloud Features¶
Some features that require an Ubiquiti Account or "Remote Access" to be enabled are currently not implemented. Examples include:
- Stream sharing