Skip to main content

A Python client/wrapper for the UniFi Access API

Project description

UniFi Access Python Client

A modern, thin API wrapper for the UniFi Access API. This library provides a clean and intuitive interface for managing UniFi Access devices, users, visitors, access policies, and more.

Features

  • Thin API Wrapper: Returns simple dictionaries for flexibility and performance
  • Comprehensive API Coverage: Full support for all UniFi Access API endpoints
  • Async Support: Built-in async client for high-performance applications
  • Easy Configuration: Environment variable support with .env files
  • Webhook Support: Built-in webhook listener and manager

Installation

pip install unifi_access

Quick Start

Configuration

Create a .env file in your project root:

UNIFI_ACCESS_BASE_URL=https://192.168.1.1
UNIFI_ACCESS_API_TOKEN=your-api-token-here
UNIFI_ACCESS_PORT=12445
UNIFI_SESSION_TIMEOUT=30

UNIFI_SESSION_TIMEOUT is optional and defaults to 15 seconds. Increasing timeout time is sometimes required on busy systems with large amounts of users, doors, etc. and the Unifi console/NVR takes a little longer to process requests.

Basic Setup

from unifi_access.client import UniFiAccessClient

# Initialize with environment variables
client = UniFiAccessClient()

# Or initialize with explicit credentials
client = UniFiAccessClient(
    base_url="https://192.168.1.1",
    api_token="your-api-token",
    port="12445",
    verify_ssl=False
)

Usage Examples

Most methods/functions are named identical to Unifi Access API documentation section headings. IE: From the unifi docs "7.5 Fetch All Door Groups" the method will be client.spaces.fetch_all_door_groups()

User Management

# Fetch all users - returns a list of dictionaries
users = client.users.fetch_all_users()

if users:
    user = users[0]
    print(f"User: {user.get('first_name')} {user.get('last_name')}")

    # Update user
    client.users.update_user(user['id'], first_name="NewName")
    
    # Assign an NFC card
    client.users.assign_nfc_card_to_user(user['id'], "card_token_123")
    
    # Get access policies
    policies = client.users.fetch_access_policies_assigned_to_user(user['id'])

Visitor Management

# Create a visitor - returns a dictionary
visitor = client.visitors.create_visitor(
    first_name="John",
    last_name="Doe",
    start_time=1688546460, # Unix timestamp in timezone of the location
    end_time=1688572799, 
    email="john.doe@example.com",
    resources=[
        {
            "id": "door_id_123",
            "type": "door"
        }
    ],
    week_schedule={
        "sunday": [],
        "monday": [],
        "tuesday": [
            # Single time slot
            {
                "start_time": "06:00:00", # 6 am
                "end_time": "18:00:00" # 6 pm
            }
        ],
        "wednesday": [],
        "thursday": [
            # Multiple time slots in single day.
            {
                "start_time": "06:00:00",
                "end_time": "09:00:00", # 9 am
            },
            {
                "start_time": "18:00:00", # 6 pm
                "end_time": "23:59:59" # Midnight
            }
        ],
        "friday": [],
        "saturday": []        
    }
)

# Manage visitor
client.visitors.assign_nfc_card_to_visitor(visitor['id'], "card_token_456")
client.visitors.assign_pin_code_to_visitor(visitor['id'], "1234")
client.visitors.update_visitor(visitor['id'], remarks="VIP visitor")
client.visitors.delete_visitor(visitor['id'])

Flexible Schedules

Both Visitor and Access Policy managers support flexible weekly schedules. You only need to provide the days you want to set; other days will default to empty. You can also use the everyday shortcut.

# Partial schedule - only Monday is set, others default to empty
client.visitors.create_visitor(
    ...,
    week_schedule={
        "monday": [{"start_time": "09:00:00", "end_time": "17:00:00"}]
    }
)

# Everyday shortcut - applies to all 7 days
client.access_policies.create_schedule(
    name="Everyday Access",
    week_schedule={
        "everyday": [{"start_time": "08:00:00", "end_time": "20:00:00"}]
    }
)

# Everyday with override - Sunday will be empty, others will have the everyday schedule
client.visitors.create_visitor(
    ...,
    week_schedule={
        "everyday": [{"start_time": "08:00:00", "end_time": "20:00:00"}],
        "sunday": []
    }
)

Door Management

# Fetch all doors - returns a list of dictionaries
doors = client.spaces.fetch_all_doors()

if doors:
    door = doors[0]
    print(f"Door: {door.get('name')}")

    # Control doors
    client.spaces.unlock_door(door['id'])
    client.spaces.set_temporary_door_locking_rule(door['id'], "keep_unlock", 60)  # Keep unlocked for 1 hour

Access Policy Management

# List all access policies
policies = client.access_policies.fetch_all_access_policies()

if policies:
    policy = policies[0]
    print(f"Policy: {policy.get('name')}")

    # Manage policies
    client.access_policies.update_access_policy(policy['id'], name="New Policy Name")
    client.access_policies.delete_access_policy(policy['id'])

Credential Management

Third-Party NFC Card Import

You can import third-party NFC cards either from an existing CSV file or from a list of dictionaries in memory. Both methods use the same API endpoint but differ in how you provide the data.

Import from CSV File

Use import_third_party_nfc_cards if you already have a CSV file on disk.

# Import from a CSV file
client.credentials.import_third_party_nfc_cards("path/to/your/cards.csv")
Import from List

Use import_third_party_nfc_cards_as_list if you have card data in memory (e.g., from a database or another API). The method automatically handles the CSV conversion and upload.

nfc_cards = [
    {"nfc_id": "AABBCCDDEEFF", "alias": "Staff Card 1"},
    {"nfc_id": "112233445566", "alias": "Staff Card 2"},
]
client.credentials.import_third_party_nfc_cards_as_list(nfc_cards)
Difference Summary
Method Input Type Best For
import_third_party_nfc_cards file_path (str) Bulk imports from existing files.
import_third_party_nfc_cards_as_list list[dict] Programmatic data processing without temporary files.

26-bit Wiegand Card Import

The library provides a convenient way to import 26-bit Wiegand cards. Valid ranges are 0–255 for facility_code and 0–65535 for card_number. You can optionally provide an alias for each card; if omitted, one will be generated automatically (e.g., "100 - 1234").

Basic Import
wiegand_cards = [
    {"facility_code": 100, "card_number": 1234, "alias": "Front Door Card"},
    {"facility_code": 100, "card_number": 1235}, # Alias will be "100 - 1235"
]
client.credentials.import_26bit_wiegand_cards(wiegand_cards)
Import from CSV
import csv

wiegand_cards = []
with open('cards.csv', mode='r') as f:
    reader = csv.DictReader(f)
    for row in reader:
        wiegand_cards.append({
            "facility_code": int(row['facility_code']),
            "card_number": int(row['card_number']),
            "alias": row.get('alias') # Optional
        })

client.credentials.import_26bit_wiegand_cards(wiegand_cards)
Async Import
from unifi_access.client import AsyncUniFiAccessClient

# Use async client for importing
async with AsyncUniFiAccessClient(base_url, api_token) as client:
    wiegand_cards = [
        {"facility_code": 100, "card_number": 1234, "alias": "Reception Card"},
    ]
    await client.credentials.import_26bit_wiegand_cards(wiegand_cards)

Async Support

from unifi_access.client import AsyncUniFiAccessClient

# Use async client for high-performance applications
async with AsyncUniFiAccessClient() as client:
    users = await client.users.fetch_all_users()
    for user in users:
        print(f"{user.get('first_name')} {user.get('last_name')}")

API Managers

The client provides the following manager interfaces. Click each to see available functions:

client.users (User and user group management)
  • create_user
  • update_user
  • fetch_user
  • fetch_all_users
  • delete_user
  • search_users
  • assign_access_policy_to_user
  • assign_nfc_card_to_user
  • unassign_nfc_card_from_user
  • assign_pin_code_to_user
  • unassign_pin_code_from_user
  • create_user_group
  • fetch_all_user_groups
  • fetch_user_group
  • update_user_group
  • delete_user_group
  • assign_users_to_user_group
  • unassign_users_from_user_group
  • fetch_users_in_a_user_group
  • fetch_all_users_in_a_user_group
  • fetch_access_policies_assigned_to_user
  • assign_access_policy_to_user_group
  • fetch_access_policies_assigned_to_user_group
  • assign_touch_pass_to_user
  • unassign_touch_pass_from_user
  • batch_assign_touch_passes_to_users
  • assign_license_plate_numbers_to_user
  • unassign_license_plate_number_from_user
  • upload_user_profile_picture
client.visitors (Visitor management)
  • create_visitor
  • update_visitor
  • fetch_visitor
  • fetch_all_visitors
  • delete_visitor
  • assign_nfc_card_to_visitor
  • unassign_nfc_card_from_visitor
  • assign_pin_code_to_visitor
  • unassign_pin_code_from_visitor
  • assign_qr_code_to_visitor
  • unassign_qr_code_from_visitor
  • assign_license_plate_numbers_to_visitor
  • unassign_license_plate_numbers_from_visitor
client.access_policies (Access policy management)
  • create_access_policy
  • update_access_policy
  • delete_access_policy
  • fetch_access_policy
  • fetch_all_access_policies
  • create_holiday_group
  • update_holiday_group
  • delete_holiday_group
  • fetch_holiday_group
  • fetch_all_holiday_groups
  • create_schedule
  • update_schedule
  • delete_schedule
  • fetch_schedule
  • fetch_all_schedules
client.credentials (Credential management)
  • generate_pin_code
  • enroll_nfc_card
  • fetch_nfc_card_enrollment_status
  • remove_session_created_for_nfc_card_enrollment
  • fetch_nfc_card
  • fetch_all_nfc_cards (alias: list_nfc_cards)
  • update_nfc_card
  • delete_nfc_card
  • fetch_the_touch_pass_list
  • search_touch_pass
  • fetch_all_assignable_touch_passes
  • update_touch_pass
  • fetch_touch_pass_details
  • purchase_touch_passes
  • download_qr_code_image
  • import_third_party_nfc_cards
  • import_third_party_nfc_cards_as_list
  • import_26bit_wiegand_cards
client.spaces (Door and door group management)
  • fetch_door_group_topology
  • create_door_group
  • fetch_door_group
  • update_door_group
  • fetch_all_door_groups
  • delete_door_group
  • fetch_door
  • fetch_all_doors
  • unlock_door
  • set_temporary_door_locking_rule
  • fetch_door_lock_rule
  • set_door_emergency_status
  • fetch_door_emergency_status
client.devices (Device management)
  • fetch_devices
  • fetch_access_devices_access_method_settings
  • update_access_devices_access_method_settings
  • trigger_doorbells
client.system_logs (System log retrieval)
  • fetch_system_logs
  • export_system_logs
  • fetch_resources_in_system_logs
  • fetch_static_resources_in_system_logs
client.https_certificates (HTTPS certificate management)
  • upload_https_certificate
  • delete_https_certificate
client.notifications (Notification management)
  • fetch_webhook_endpoints_list
  • add_webhook_endpoint
  • update_webhook_endpoint
  • delete_webhook_endpoint
client.identity (Identity management)
  • send_invitations
  • fetch_available_resources
  • assign_resources_to_users
  • fetch_user_resources
  • assign_resources_to_user_groups
  • fetch_user_group_resources

Requirements

  • Python 3.8+
  • httpx >= 0.23.0

License

MIT License - see LICENSE file for details

Author

Travis Tucker

Links

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unifi_access-0.1.7.tar.gz (32.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unifi_access-0.1.7-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file unifi_access-0.1.7.tar.gz.

File metadata

  • Download URL: unifi_access-0.1.7.tar.gz
  • Upload date:
  • Size: 32.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for unifi_access-0.1.7.tar.gz
Algorithm Hash digest
SHA256 a6561969db3328ac636a0a979d6307a07a0b6d902a416ae80f6c6895b15abbdb
MD5 8b938fba09fd022c03169b71d75b3880
BLAKE2b-256 7a62da1b4f81b77ea0f7097cb33b234e5a49e596399b111532c5178fdfa69cc0

See more details on using hashes here.

File details

Details for the file unifi_access-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: unifi_access-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 36.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for unifi_access-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 554d3508703023c2ac899c5d22c4ba8dd9f06f7805f2180b9f3f29f10953e8b5
MD5 7e033edb611c6eba5b70a19b29237753
BLAKE2b-256 19e6efef55b37f8ac679070bdf7d331f2b450f9fb73b4964d3f2bb015041d818

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page