Skip to content

Latest commit

 

History

History
649 lines (498 loc) · 37.8 KB

File metadata and controls

649 lines (498 loc) · 37.8 KB

ONVIF Python

License DeepWiki Release
PyPI Downloads

This project provides a comprehensive and developer-friendly Python library for working with ONVIF-compliant devices. It is designed to be reliable, easy to integrate, and flexible enough to support a wide range of ONVIF profiles and services.

ONVIF (Open Network Video Interface Forum) is a global standard for the interface of IP-based physical security products, including network cameras, video recorders, and related systems.

Behind the scenes, ONVIF communication relies on SOAP (Simple Object Access Protocol) — an XML-based messaging protocol with strict schema definitions (WSDL/XSD). SOAP ensures interoperability, but when used directly it can be verbose, complex, and error-prone.

This library simplifies that process by wrapping SOAP communication into a clean, Pythonic API. You no longer need to handle low-level XML parsing, namespaces, or security tokens manually — the library takes care of it, letting you focus on building functionality.

Key Features

  • Full implementation of ONVIF core services and profiles
  • Support for device discovery, media streaming, PTZ control, event management, and more
  • Pythonic abstraction over SOAP requests and responses (no need to handcraft XML)
  • Extensible architecture for custom ONVIF extensions
  • Compatible with multiple ONVIF specification versions
  • Example scripts and tests included

Who Is It For?

  • Individual developers exploring ONVIF or building hobby projects
  • Companies building video intelligence, analytics, or VMS platforms
  • Security integrators who need reliable ONVIF interoperability across devices

Installation

From official PyPI:

pip install onvif-python

Or clone this repository and install locally:

git clone https://github.com/nirsimetri/onvif-python
cd onvif-python
pip install .

Usage Example

Tip

You can view the complete documentation automatically generated by DeepWiki via the onvif-python AI Wiki link. We currently do not have an official documentation site. Help us create more examples and helpful documentation by contributing.

Below are simple examples to help you get started with the ONVIF Python library. These demonstrate how to connect to an ONVIF-compliant device and retrieve basic device information.

1. Initialize the ONVIFClient

Create an instance of ONVIFClient by providing your device's IP address, port, username, and password:

from onvif import ONVIFClient

# Basic connection
client = ONVIFClient("192.168.1.17", 8000, "admin", "admin123")

# With custom WSDL directory (optional)
client = ONVIFClient(
    "192.168.1.17", 8000, "admin", "admin123",
    wsdl_dir="/path/to/custom/wsdl"  # Use custom WSDL files in this path
)

2. Create Service Instance

ONVIFClient provides several main services that can be accessed via the following methods:

  • client.devicemgmt() — Device Management
  • client.events() — Events
  • client.imaging() — Imaging
  • client.media() — Media
  • client.ptz() — PTZ (Pan-Tilt-Zoom)
  • client.analytics() — Analytics

and so on, check Implemented ONVIF Services for more details

Example usage:

device = client.devicemgmt()      # Device Management (Core)
media = client.media()            # Media

3. Get Device Information

Retrieve basic information about the device, such as manufacturer, model, firmware version, and serial number using devicemgmt() service:

info = device.GetDeviceInformation()
print(info)
# Example output: {'Manufacturer': '..', 'Model': '..', 'FirmwareVersion': '..', 'SerialNumber': '..'}

4. Get RTSP URL

Retrieve the RTSP stream URL for live video streaming from the device using media() service:

profile = media.GetProfiles()[0]  # use the first profile
stream = media.GetStreamUri(
    ProfileToken=profile.token, 
	StreamSetup={"Stream": "RTP-Unicast", "Transport": {"Protocol": "RTSP"}}
)
print(stream)
# Example output: {'Uri': 'rtsp://192.168.1.17:8554/Streaming/Channels/101', ...}

Explore more advanced usage and service-specific operations in the examples/ folder.

Important

If you're new to ONVIF and want to learn more, we highly recommend taking the official free online course provided by ONVIF at Introduction to ONVIF Course. Please note that we are not endorsed or sponsored by ONVIF, see Legal Notice for details.

ONVIFClient Parameters

The ONVIFClient class provides various configuration options to customize the connection behavior, caching strategy, security settings, and debugging capabilities. Below is a detailed description of all available parameters:

Basic Parameters
Parameter Type Required Default Description
host str ✅ Yes - IP address or hostname of the ONVIF device (e.g., "192.168.1.17")
port int ✅ Yes - Port number for ONVIF service (common ports: 80, 8000, 8080)
username str ✅ Yes - Username for device authentication (use digest authentication)
password str ✅ Yes - Password for device authentication
Connection Parameters
Parameter Type Required Default Description
timeout int ❌ No 10 Connection timeout in seconds for SOAP requests
use_https bool ❌ No False Use HTTPS instead of HTTP for secure communication
verify_ssl bool ❌ No True Verify SSL certificates when using HTTPS (set to False for self-signed certificates)
Caching Parameters
Parameter Type Required Default Description
cache CacheMode ❌ No CacheMode.ALL WSDL caching strategy (see Cache Modes below)
Feature Parameters
Parameter Type Required Default Description
apply_patch bool ❌ No True Enable zeep patching for better xsd:any field parsing and automatic flattening, applied at (>= v0.0.4)
capture_xml bool ❌ No False Enable XML capture plugin for debugging SOAP requests/responses, applied at (>= v0.0.6)
wsdl_dir str ❌ No None Custom WSDL directory path for using external WSDL files instead of built-in ones (e.g., /path/to/custom/wsdl), applied at (>= v0.1.0)
Cache Modes

The library provides four caching strategies via the CacheMode enum:

Mode Description Best For Startup Speed Disk Usage Memory Usage
CacheMode.ALL In-memory + disk cache (SQLite) Production servers, multi-device apps Fast High High
CacheMode.DB Disk cache only (SQLite) Batch jobs, CLI tools Medium Medium Low
CacheMode.MEM In-memory cache only Short-lived scripts, demos Medium None Medium
CacheMode.NONE No caching Testing, debugging Slow None Low

Recommendation: Use CacheMode.ALL (default) for production applications to maximize performance.

Usage Examples

Basic Connection:

from onvif import ONVIFClient

# Minimal configuration
client = ONVIFClient("192.168.1.17", 80, "admin", "password")

Secure Connection (HTTPS):

from onvif import ONVIFClient

# Connect via HTTPS with custom timeout
client = ONVIFClient(
    "your-cctv-node.viewplexus.com", 
    443,  # HTTPS port
    "admin", 
    "password",
    timeout=30,
    use_https=True
)

Performance Optimized (Memory Cache):

from onvif import ONVIFClient, CacheMode

# Use memory-only cache for quick scripts
client = ONVIFClient(
    "192.168.1.17", 
    80, 
    "admin", 
    "password",
    cache=CacheMode.MEM
)

No Caching and No Zeep Patching (Testing):

from onvif import ONVIFClient, CacheMode

# Disable all caching for testing
client = ONVIFClient(
    "192.168.1.17", 
    80, 
    "admin", 
    "password",
    cache=CacheMode.NONE,
    apply_patch=False  # Use original zeep behavior
)

Debugging Mode (XML Capture):

from onvif import ONVIFClient

# Enable XML capture for debugging
client = ONVIFClient(
    "192.168.1.17", 
    80, 
    "admin", 
    "password",
    capture_xml=True  # Captures all SOAP requests/responses
)

# Make some ONVIF calls
device = client.devicemgmt()
info = device.GetDeviceInformation()
services = device.GetCapabilities()

# Access the XML capture plugin
if client.xml_plugin:
    # Get last captured request/response
    print("Last Request XML:")
    print(client.xml_plugin.last_sent_xml)
    
    print("\nLast Response XML:")
    print(client.xml_plugin.last_received_xml)
    
    print(f"\nLast Operation: {client.xml_plugin.last_operation}")
    
    # Get complete history of all requests/responses
    print(f"\nTotal captured operations: {len(client.xml_plugin.history)}")
    for item in client.xml_plugin.history:
        print(f"  - {item['operation']} ({item['type']})")
    
    # Save captured XML to files
    client.xml_plugin.save_to_file(
        request_file="last_request.xml",
        response_file="last_response.xml"
    )
    
    # Clear history when done
    client.xml_plugin.clear_history()

XML Capture Plugin Methods:

  • last_sent_xml - Get the last SOAP request XML
  • last_received_xml - Get the last SOAP response XML
  • last_operation - Get the name of the last operation
  • history - List of all captured requests/responses with metadata
  • get_last_request() - Method to get last request
  • get_last_response() - Method to get last response
  • get_history() - Method to get all history
  • save_to_file(request_file, response_file) - Save XML to files
  • clear_history() - Clear captured history

Custom WSDL Directory:

from onvif import ONVIFClient

# Use custom WSDL files instead of built-in ones
client = ONVIFClient(
    "192.168.1.17", 
    80, 
    "admin", 
    "password",
    wsdl_dir="/path/to/custom/wsdl"  # Custom WSDL directory
)

# All services will automatically use custom WSDL files
device = client.devicemgmt()
media = client.media()
ptz = client.ptz()

# The custom WSDL directory should have a flat structure:
# /path/to/custom/wsdl/
# ├── devicemgmt.wsdl
# ├── media.wsdl
# ├── ptz.wsdl
# ├── imaging.wsdl
# └── ... (other WSDL files)
Production Configuration
from onvif import ONVIFClient, CacheMode

# Recommended production settings
client = ONVIFClient(
    host="your-cctv-node.viewplexus.com",
    port=443,
    username="admin",
    password="secure_password",
    timeout=15,
    cache=CacheMode.ALL,        # Maximum performance (default)
    use_https=True,             # Secure communication
    verify_ssl=True,            # Verify certificates (default)
    apply_patch=True,           # Enhanced parsing (default)
    capture_xml=False,          # Disable debug mode (default)
    wsdl_dir=None               # Use built-in WSDL files (default)
)

Notes

  • Authentication: This library uses WS-UsernameToken with Digest authentication by default, which is the standard for ONVIF devices.
  • Patching: The apply_patch=True (default) enables custom zeep patching that improves xsd:any field parsing. This is recommended for better compatibility with ONVIF responses.
  • XML Capture: Only use capture_xml=True during development/debugging as it increases memory usage and may expose sensitive data in logs.
  • Custom WSDL: Use wsdl_dir parameter to specify a custom directory containing WSDL files. The directory should have a flat structure with WSDL files directly in the root (e.g., /path/to/custom/wsdl/devicemgmt.wsdl, /path/to/custom/wsdl/media.wsdl, etc.).
  • Cache Location: Disk cache (when using CacheMode.DB or CacheMode.ALL) is stored in ~/.onvif-python/onvif_zeep_cache.sqlite.

Service Discovery: Understanding Device Capabilities

Warning

Before performing any operations on an ONVIF device, it is highly recommended to discover which services are available and supported by the device. This library automatically performs comprehensive service discovery during initialization using a robust fallback mechanism.

Why discover device services?

  • Device Diversity: Not all ONVIF devices support every service. Available services may vary by manufacturer, model, firmware, or configuration.
  • Error Prevention: Attempting to use unsupported services can result in failed requests, exceptions, or undefined behavior.
  • Dynamic Feature Detection: Devices may enable or disable services over time (e.g., after firmware updates or configuration changes).
  • Optimized Integration: By checking available services, your application can adapt its workflow and UI to match the device's actual features.

How service discovery works in this library:

The ONVIFClient uses a 3-tier discovery approach to maximize device compatibility:

  1. GetServices (Preferred) - Tries GetServices first for detailed service information
  2. GetCapabilities (Fallback) - Falls back to GetCapabilities if GetServices is not supported
  3. Default URLs (Final Fallback) - Uses standard ONVIF URLs as last resort
from onvif import ONVIFClient

client = ONVIFClient("192.168.1.17", 8000, "admin", "admin123")

# Check what discovery method was used
if client.services:
    print("Service discovery: GetServices (preferred)")
    print("Discovered services:", len(client.services))
    print("Service map:", client._service_map)
elif client.capabilities:
    print("Service discovery: GetCapabilities (fallback)")
    print("Available capabilities:", client.capabilities)
else:
    print("Service discovery: Using default URLs")

Why this approach?

  • GetServices provides the most accurate and detailed service information, but it's optional in the ONVIF specification
  • GetCapabilities is mandatory for all ONVIF-compliant devices, ensuring broader compatibility
  • Default URLs guarantee basic connectivity even with non-compliant devices

Get detailed service information:

If you need comprehensive service details, you can manually call GetServices with capabilities:

device = client.devicemgmt()

try:
    # Try to get detailed service information
    services = device.GetServices(IncludeCapability=True)
    for service in services:
        print(f"Service: {service.Namespace}")
        print(f"XAddr: {service.XAddr}")
        if hasattr(service, 'Capabilities'):
            print(f"Capabilities: {service.Capabilities}")
except Exception:
    # Fallback to GetCapabilities for legacy devices
    capabilities = device.GetCapabilities()
    print("Capabilities:", capabilities)

Access capabilities information:

When using GetCapabilities fallback, you can access capability information:

device = client.devicemgmt()

try:
    # Get capabilities information from device
    capabilities = device.GetCapabilities()
    
    # Main services (always available)
    print("Media XAddr:", getattr(capabilities.Media, 'XAddr', 'Not available'))
    print("PTZ XAddr:", getattr(capabilities.PTZ, 'XAddr', 'Not available'))
    
    # Extension services (device-dependent)
    ext = getattr(capabilities, 'Extension', None)
    if ext:
        print("DeviceIO XAddr:", getattr(ext.DeviceIO, 'XAddr', 'Not available'))
        print("Recording XAddr:", getattr(ext.Recording, 'XAddr', 'Not available'))
        print("Search XAddr:", getattr(ext.Search, 'XAddr', 'Not available'))
        print("Replay XAddr:", getattr(ext.Replay, 'XAddr', 'Not available'))
except Exception as e:
    print(f"Error getting capabilities: {e}")

Tip

The library handles service discovery automatically with intelligent fallback. You typically don't need to call discovery methods manually unless you need detailed capability information or want to refresh the service list after device configuration changes.

Tested Devices

This library has been tested with a variety of ONVIF-compliant devices. For the latest and most complete list of devices that have been verified to work with this library, please refer to:

If your device is not listed right now, feel free to contribute your test results or feedback via Issues or Discussions at onvif-products-directory. Your contribution will be invaluable to the community and the public.

Important

Device testing contributions must be made with a real device and use the scripts provided in the onvif-products-directory repo. Please be sure to contribute using a device model not already listed.

Supported ONVIF Profiles

This library fully supports all major ONVIF Profiles listed below. Each profile represents a standardized set of features and use cases, ensuring interoperability between ONVIF-compliant devices and clients. You can use this library to integrate with devices and systems that implement any of these profiles.

Name Specifications Main Features Typical Use Case Support
Profile_S Document Video streaming, PTZ, audio, multicasting Network video transmitters (cameras) and receivers (recorders, VMS) ✅ Yes
Profile_G Document Recording, search, replay, video storage Video recorders, storage devices ✅ Yes
Profile_T Document Advanced video streaming (H.265, analytics metadata, motion detection) Modern cameras and clients ✅ Yes
Profile_C Document Access control, door monitoring Door controllers, access systems ✅ Yes
Profile_A Document Advanced access control configuration, credential management Access control clients and devices ✅ Yes
Profile_D Document Access control peripherals (locks, sensors, relays) Peripheral devices for access control ✅ Yes
Profile_M Document Metadata, analytics events, object detection Analytics devices, metadata clients ✅ Yes

For a full description of each profile and its features, visit ONVIF Profiles.

Implemented ONVIF Services

Note

For details about the available service functions and methods already implemented in this library, see the source code in onvif/services/. Or if you want to read in a more proper format visit onvif-python AI Wiki.

Below is a list of ONVIF services implemented and supported by this library, along with links to the official specifications, service definitions, and schema files as referenced from the ONVIF Developer Specs. This table provides a quick overview of the available ONVIF features and their technical documentation for integration and development purposes.

Service Specifications Service Definitions Schema Files Status
Device Management Document device.wsdl onvif.xsd
common.xsd
✅ Complete
Events Document event.wsdl onvif.xsd
common.xsd
⚠️ Partial
Access Control Document accesscontrol.wsdl types.xsd ✅ Complete
Access Rules Document accessrules.wsdl - ✅ Complete
Action Engine Document actionengine.wsdl - ✅ Complete
Analytics Document analytics.wsdl rules.xsd
humanbody.xsd
humanface.xsd
✅ Complete
Application Management Document appmgmt.wsdl - ✅ Complete
Authentication Behavior Document authenticationbehavior.wsdl - ✅ Complete
Cloud Integration Document cloudintegration.yaml - ❌ Not yet
Credential Document credential.wsdl - ✅ Complete
Device IO Document deviceio.wsdl - ✅ Complete
Display Document display.wsdl - ✅ Complete
Door Control Document doorcontrol.wsdl - ✅ Complete
Imaging Document imaging.wsdl - ✅ Complete
Media Document media.wsdl - ✅ Complete
Media 2 Document media2.wsdl - ✅ Complete
Provisioning Document provisioning.wsdl - ✅ Complete
PTZ Document ptz.wsdl - ✅ Complete
Receiver Document receiver.wsdl - ✅ Complete
Recording Control Document recording.wsdl - ✅ Complete
Recording Search Document search.wsdl - ✅ Complete
Replay Control Document replay.wsdl - ✅ Complete
Resource Query Document - ❌ Any idea?
Schedule Document schedule.wsdl - ✅ Complete
Security Document advancedsecurity.wsdl - ✅ Complete
Thermal Document thermal.wsdl radiometry.xsd ✅ Complete
Uplink Document uplink.wsdl - ✅ Complete
WebRTC Document - - ❌ Any idea?

Service Bindings in ONVIF

ONVIF services are defined by WSDL bindings. In this library, there are two main patterns:

1. Single Binding Services

Most ONVIF services use a single binding, mapping directly to one endpoint. These are accessed via simple client methods, and the binding/xAddr is always known from device capabilities.

Examples:
client.devicemgmt()   # DeviceBinding
client.media()        # MediaBinding
client.ptz()          # PTZBinding
...

✅ These are considered fixed and always accessed directly.

2. Multi-Binding Services

Some ONVIF services have multiple bindings in the same WSDL. These typically include:

  • A root binding (main entry point)
  • One or more sub-bindings, discovered or created dynamically (e.g. after subscription/configuration creation)
Examples:
  1. Events

    • Root: EventBinding
    • Sub-bindings:
      • PullPointSubscriptionBinding (created via CreatePullPointSubscription)
      • SubscriptionManagerBinding (manages existing subscriptions)
      • NotificationProducerBinding

    Usage in library:

    client.events()                    # root binding
    client.pullpoint(subscription)     # sub-binding (dynamic, via SubscriptionReference.Address)
    client.subscription(subscription)  # sub-binding (dynamic, via SubscriptionReference.Address)
    client.notification()              # sub-binding accessor
  2. Security (Advanced Security)

    • Root: AdvancedSecurityServiceBinding
    • Sub-bindings:
      • AuthorizationServerBinding
      • KeystoreBinding
      • JWTBinding
      • Dot1XBinding
      • TLSServerBinding
      • MediaSigningBinding

    Usage in library:

    client.security()                  # root binding
    client.authorizationserver(xaddr)  # sub-binding accessor (requires xAddr)
    client.keystore(xaddr)             # ..
    client.jwt(xaddr)
    client.dot1x(xaddr)
    client.tlsserver(xaddr)
    client.mediasigning(xaddr)
  3. Analytics

    • Root: AnalyticsEngineBinding
    • Sub-bindings:
      • RuleEngineBinding

    Usage in library:

    client.analytics()   # root binding
    client.ruleengine()  # sub-binding accessor

Summary

  • Single binding services: Always accessed directly (e.g. client.media()).
  • Multi-binding services: Have a root + sub-binding(s). Root is fixed; sub-bindings may require dynamic creation or explicit xAddr (e.g. client.pullpoint(subscription), client.authorizationserver(xaddr)).

Future Improvements (Stay tuned and star ⭐ this repo)

  • Add debugging mode with raw xml on SOAP requests and responses. (c258162)
  • Add functionality for ONVIFClient to accept a custom wsdl_dir service. (65f2570)
  • Add ONVIF CLI program to interact directly with ONVIF devices via terminal.
  • Add asynchronous (async/await) support for non-blocking ONVIF operations and concurrent device communication.
  • Implement structured data models for ONVIF Schemas using xsdata.
  • Integrate xmltodict for simplified XML parsing and conversion.
  • Enhance documentation with API references and diagrams (not from AI Wiki).
  • Add more usage examples for advanced features.
  • Add benchmarking and performance metrics.
  • Add community-contributed device configuration templates.
  • Implement missing or partial ONVIF services.
  • Add function to expose ONVIF devices (for debugging purposes by the community).

Related Projects

  • onvif-products-directory: This project is a comprehensive ONVIF data aggregation and management suite, designed to help developers explore, analyze, and process ONVIF-compliant product information from hundreds of manufacturers worldwide. It provides a unified structure for device, client, and company data, making it easier to perform research, build integrations, and generate statistics for ONVIF ecosystem analysis.

  • (soon) onvif-rest-server: A RESTful API server for ONVIF devices, enabling easy integration of ONVIF device management, media streaming, and other capabilities into web applications and services.

  • (soon) onvif-mcp: A Model Context Protocol (MCP) server for ONVIF, providing a unified API and context-based integration for ONVIF devices, clients, and services. It enables advanced automation, orchestration, and interoperability across ONVIF-compliant devices and clients.

Alternatives

If you are looking for other ONVIF Python libraries, here are some alternatives:

  • python-onvif-zeep: A synchronous ONVIF client library for Python, using Zeep for SOAP communication. Focuses on compatibility and ease of use for standard ONVIF device operations. Good for scripts and applications where async is not required.

  • python-onvif-zeep-async: An asynchronous ONVIF client library for Python, based on Zeep and asyncio. Suitable for applications requiring non-blocking operations and concurrent device communication. Supports many ONVIF services and is actively maintained.

References

Legal Notice

This project is an independent open-source implementation of the ONVIF specifications. It is not affiliated with, endorsed by, or sponsored by ONVIF or its member companies.

  • The name “ONVIF” and the ONVIF logo are registered trademarks of the ONVIF organization.
  • Any references to ONVIF within this project are made strictly for the purpose of describing interoperability with ONVIF-compliant devices and services.
  • Use of the ONVIF trademark in this repository is solely nominative and does not imply any partnership, certification, or official status.
  • This project includes WSDL/XSD/HTML files from the official ONVIF specifications.
  • These files are © ONVIF and are redistributed here for interoperability purposes.
  • All rights to the ONVIF specifications are reserved by ONVIF.

If you require certified ONVIF-compliant devices or clients, please refer to the official ONVIF conformant product list. For authoritative reference and the latest official ONVIF specifications, please consult the ONVIF Official Specifications.

License

This project is licensed under the MIT License. See LICENSE for details.