Async Python library for the official UniFi Network and Protect APIs
Project description
UniFi Official API
Async Python library for the official UniFi Network and Protect APIs.
Features
- Async-first: Built with
aiohttpfor efficient async operations - Type-safe: Full type hints and Pydantic models for all API responses
- Official API: Uses the official UniFi developer API endpoints
- Comprehensive: Supports both UniFi Network and UniFi Protect
- Dual Connection Support: Works with both LOCAL (direct to device) and REMOTE (cloud) connections
- Home Assistant ready: Designed for integration with Home Assistant and other automation platforms
Requirements
Python 3.11 or higher is required.
- Python 3.11, 3.12, or 3.13
- UniFi API Key from developer.ui.com or generated locally on your device
Installation
pip install unifi-official-api
Optional Dependencies
Install with optional dependency groups for development:
# Install with test dependencies
pip install unifi-official-api[test]
# Install with linting/type checking tools
pip install unifi-official-api[lint]
# Install with documentation tools
pip install unifi-official-api[docs]
# Install all development dependencies
pip install unifi-official-api[dev]
Connection Types
This library supports two connection types:
| Connection Type | Use Case | Base URL | API Key Source |
|---|---|---|---|
| LOCAL | Direct connection to your UniFi device (UDM, UDM-Pro, etc.) | Your device IP (e.g., https://192.168.1.1) |
Generated on device under Settings → Admins & Users → API Keys |
| REMOTE | Cloud connection via Ubiquiti's API | https://api.ui.com (default) |
Generated at account.ui.com |
Quick Start
Local Connection (Direct to Device)
For direct connection to your UniFi device on your local network:
import asyncio
from unifi_official_api import LocalAuth, ConnectionType
from unifi_official_api.network import UniFiNetworkClient
async def main():
async with UniFiNetworkClient(
auth=LocalAuth(
api_key="your-local-api-key",
verify_ssl=False, # Disable SSL verification for self-signed certs
),
base_url="https://192.168.1.1", # Your device IP
connection_type=ConnectionType.LOCAL,
) as client:
# List all sites
sites = await client.sites.get_all()
site_id = sites[0].id # Use the actual site ID
# List all devices
devices = await client.devices.get_all(site_id)
for device in devices:
print(f"Device: {device.name} ({device.mac})")
# List connected clients
clients = await client.clients.get_all(site_id)
for client_info in clients:
print(f"Client: {client_info.display_name} - {client_info.ip}")
asyncio.run(main())
Remote Connection (Cloud API)
For cloud connection via Ubiquiti's API:
import asyncio
from unifi_official_api import ApiKeyAuth, ConnectionType
from unifi_official_api.network import UniFiNetworkClient
async def main():
async with UniFiNetworkClient(
auth=ApiKeyAuth(api_key="your-cloud-api-key"),
connection_type=ConnectionType.REMOTE,
console_id="your-console-id", # Required for REMOTE
) as client:
# List all sites
sites = await client.sites.get_all()
site_id = sites[0].id
# List all devices
devices = await client.devices.get_all(site_id)
for device in devices:
print(f"Device: {device.name} ({device.mac})")
asyncio.run(main())
UniFi Protect API
import asyncio
from unifi_official_api import ApiKeyAuth
from unifi_official_api.protect import UniFiProtectClient
async def main():
async with UniFiProtectClient(
auth=ApiKeyAuth(api_key="your-api-key"),
) as client:
# Get available hosts
hosts = await client.get_hosts()
host_id = hosts[0]["id"]
site_id = "your-site-id"
# List all cameras
cameras = await client.cameras.get_all(host_id, site_id)
for camera in cameras:
print(f"Camera: {camera.name} - Recording: {camera.is_recording}")
# Get a camera snapshot
if cameras:
snapshot = await client.cameras.get_snapshot(
host_id, site_id, cameras[0].id
)
with open("snapshot.jpg", "wb") as f:
f.write(snapshot)
# List recent motion events
events = await client.events.list_motion_events(
host_id, site_id, limit=10
)
asyncio.run(main())
API Coverage
UniFi Network API
| Endpoint | Methods |
|---|---|
| Sites | list, get |
| Devices | list, get, restart, adopt, forget, locate, get_statistics, execute_action |
| Clients | list, get, block, unblock, reconnect, forget, execute_action |
| Networks | list, get, create, update, delete, get_references |
| WiFi | list, get, create, update, delete |
| Firewall | list_zones, get_zone, create_zone, update_zone, delete_zone, list_rules, get_rule, create_rule, update_rule, delete_rule |
| Vouchers | list, get, create, delete, delete_multiple |
| ACL | list, get, create, update, delete |
| Traffic | list_matching_lists, create_list, update_list, delete_list, get_dpi_categories, get_dpi_applications, get_countries |
| Resources | get_wan_interfaces, get_vpn_tunnels, get_vpn_servers, get_radius_profiles, get_device_tags |
UniFi Protect API
| Endpoint | Methods |
|---|---|
| Cameras | list, get, update, get_snapshot, ptz_patrol_start, ptz_patrol_stop, ptz_goto_preset, create_rtsps_stream, delete_rtsps_stream, create_talkback_session |
| Sensors | list, get, update |
| Lights | list, get, update |
| Chimes | list, get, update |
| NVR | get, update |
| Live Views | list, get, create, update, delete |
| Viewers | list, get, update, set_liveview |
| Events | list, get, get_thumbnail, get_heatmap, list_motion_events, list_smart_detect_events |
| Application | get_info, get_files, upload_file, trigger_alarm_webhook |
| WebSocket | subscribe_devices, subscribe_events |
Error Handling
The library provides specific exceptions for different error types:
from unifi_official_api import (
UniFiError,
UniFiAuthenticationError,
UniFiConnectionError,
UniFiNotFoundError,
UniFiRateLimitError,
UniFiTimeoutError,
)
try:
devices = await client.devices.get_all(host_id)
except UniFiAuthenticationError:
print("Invalid API key")
except UniFiConnectionError:
print("Failed to connect to API")
except UniFiRateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
except UniFiNotFoundError:
print("Resource not found")
except UniFiError as e:
print(f"API error: {e.message}")
Configuration Options
Both clients accept the following configuration options:
from unifi_official_api import LocalAuth, ConnectionType
from unifi_official_api.network import UniFiNetworkClient
# Local connection
client = UniFiNetworkClient(
auth=LocalAuth(
api_key="your-local-api-key",
verify_ssl=False, # For self-signed certificates
),
base_url="https://192.168.1.1", # Your device IP
connection_type=ConnectionType.LOCAL,
timeout=30, # Request timeout in seconds
connect_timeout=10, # Connection timeout in seconds
)
# Remote/Cloud connection
from unifi_official_api import ApiKeyAuth
client = UniFiNetworkClient(
auth=ApiKeyAuth(api_key="your-cloud-api-key"),
connection_type=ConnectionType.REMOTE,
console_id="your-console-id", # Required for REMOTE connections
timeout=30,
connect_timeout=10,
)
Local Protect Installation
For connecting directly to a local UniFi Protect installation:
from unifi_official_api import LocalAuth
from unifi_official_api.protect import UniFiProtectClient
client = UniFiProtectClient(
auth=LocalAuth(
api_key="local-api-key",
verify_ssl=False, # Disable SSL verification for self-signed certs
),
base_url="https://192.168.1.1:7443",
)
Development
Setup
# Clone the repository
git clone https://github.com/ruaan-deysel/unifi-official-api.git
cd unifi-official-api
# Install development dependencies
pip install -e ".[dev]"
# Install pre-commit hooks (recommended)
pre-commit install
# Run tests
pytest
# Run linting
ruff check src tests
# Run type checking
mypy src
Pre-commit Hooks
This project uses pre-commit hooks to ensure code quality before commits. The hooks automatically run:
- Ruff - Linting and formatting
- Mypy - Static type checking
- Bandit - Security vulnerability scanning
- Markdownlint - Markdown file linting
- Codespell - Spell checking
- Pyupgrade - Python syntax modernization
- File checks - YAML, TOML, JSON validation, trailing whitespace, etc.
To set up pre-commit hooks:
# Install pre-commit
pip install pre-commit
# Install the git hooks
pre-commit install
# (Optional) Run against all files
pre-commit run --all-files
Once installed, the hooks will automatically run on every commit. If any check fails, the commit will be blocked until you fix the issues.
Running Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=unifi_official_api --cov-report=html
# Run specific test file
pytest tests/network/test_client.py
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Disclaimer
This is an unofficial library. UniFi is a trademark of Ubiquiti Inc. This project is not affiliated with, endorsed by, or sponsored by Ubiquiti Inc.
Related Projects
- Home Assistant - Open source home automation
- UniFi Developer Documentation - Official API documentation
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file unifi_official_api-1.3.0.tar.gz.
File metadata
- Download URL: unifi_official_api-1.3.0.tar.gz
- Upload date:
- Size: 93.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
974bb248f8fc663729c281c8c78267625456748d190db8d4d0eb61ae039003cf
|
|
| MD5 |
9f04ae6385af449c9006ddbed3bd8792
|
|
| BLAKE2b-256 |
461653e574d923f996df11402642990ec67e1da1faea2e8cc7643d19a28171f6
|
Provenance
The following attestation bundles were made for unifi_official_api-1.3.0.tar.gz:
Publisher:
release.yml on ruaan-deysel/unifi-official-api
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
unifi_official_api-1.3.0.tar.gz -
Subject digest:
974bb248f8fc663729c281c8c78267625456748d190db8d4d0eb61ae039003cf - Sigstore transparency entry: 1198968495
- Sigstore integration time:
-
Permalink:
ruaan-deysel/unifi-official-api@8922dc5ae2b16d4175c299083336f842aad67f8c -
Branch / Tag:
refs/tags/v1.3.0 - Owner: https://github.com/ruaan-deysel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8922dc5ae2b16d4175c299083336f842aad67f8c -
Trigger Event:
push
-
Statement type:
File details
Details for the file unifi_official_api-1.3.0-py3-none-any.whl.
File metadata
- Download URL: unifi_official_api-1.3.0-py3-none-any.whl
- Upload date:
- Size: 75.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
550502336fafaa73c4448d34241d879520bcfe014a5c6d2c8a77d9c18087fa17
|
|
| MD5 |
2e5e1ad1e6e463092fa6ee9f9430a362
|
|
| BLAKE2b-256 |
802965a3c42e9af79f922b57b7e6ea46317c90753093c189a5b3498772804583
|
Provenance
The following attestation bundles were made for unifi_official_api-1.3.0-py3-none-any.whl:
Publisher:
release.yml on ruaan-deysel/unifi-official-api
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
unifi_official_api-1.3.0-py3-none-any.whl -
Subject digest:
550502336fafaa73c4448d34241d879520bcfe014a5c6d2c8a77d9c18087fa17 - Sigstore transparency entry: 1198968551
- Sigstore integration time:
-
Permalink:
ruaan-deysel/unifi-official-api@8922dc5ae2b16d4175c299083336f842aad67f8c -
Branch / Tag:
refs/tags/v1.3.0 - Owner: https://github.com/ruaan-deysel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@8922dc5ae2b16d4175c299083336f842aad67f8c -
Trigger Event:
push
-
Statement type: