<h1 align="center">ONVIF Python</h1>
<div align="center">
[](https://app.codacy.com/gh/nirsimetri/onvif-python/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[](https://deepwiki.com/nirsimetri/onvif-python)
[](https://pypi.org/project/onvif-python/)
[](https://clickpy.clickhouse.com/dashboard/onvif-python)
<br>
[](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml)
[](https://github.com/nirsimetri/onvif-python/actions/workflows/python-publish.yml)
</div>
<h1 align="center">
<img src="https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/carbon_onvif.png" alt="onvif" width="700px">
<br>
</h1>
**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](https://www.onvif.org) (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](https://en.wikipedia.org/wiki/SOAP) (Simple Object Access Protocol)** — an [XML](https://en.wikipedia.org/wiki/XML)-based messaging protocol with strict schema definitions ([WSDL](https://en.wikipedia.org/wiki/Web_Services_Description_Language)/[XSD](https://en.wikipedia.org/wiki/XML_Schema_(W3C))). 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
## Requirements
- **Python**: 3.9 or higher
- **Dependencies**:
- [`zeep>=4.3.0`](https://github.com/mvantellingen/python-zeep) - SOAP client for ONVIF communication
- [`requests>=2.32.0`](https://github.com/psf/requests) - HTTP library for network requests
## Installation
From official [PyPI](https://pypi.org/project/onvif-python/):
```bash
pip install onvif-python
```
Or clone this repository and install locally:
```bash
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](https://deepwiki.com/nirsimetri/onvif-python) link. We currently do not have an official documentation site. Help us create more examples and helpful documentation by [contributing](https://github.com/nirsimetri/onvif-python?tab=contributing-ov-file).
Below are simple examples to help you get started with the ONVIF Python library. These demonstrate how to discover and connect to ONVIF-compliant devices and retrieve basic device information.
**1. Discover ONVIF Devices (Optional)**
Use `ONVIFDiscovery` (applied at [`>=v0.1.6`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.1.6)) to automatically find ONVIF devices on your local network:
```python
from onvif import ONVIFDiscovery
# Create discovery instance
discovery = ONVIFDiscovery(timeout=5)
# Discover devices
devices = discovery.discover()
# Or with
# Discover with search filter by types or scopes (case-insensitive substring match)
devices = discovery.discover(search="Profile/Streaming")
# Display discovered devices
for device in devices:
print(f"Found device at {device['host']}:{device['port']}")
print(f" Scopes: {device.get('scopes', [])}")
print(f" XAddrs: {device['xaddrs']}")
```
**2. Initialize the ONVIFClient**
Create an instance of `ONVIFClient` by providing your device's IP address, port, username, and password:
```python
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
)
```
**3. 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](https://github.com/nirsimetri/onvif-python?tab=readme-ov-file#implemented-onvif-services) for more details
Example usage:
```python
device = client.devicemgmt() # Device Management (Core)
media = client.media() # Media
```
**4. Get Device Information**
Retrieve basic information about the device, such as manufacturer, model, firmware version, and serial number using `devicemgmt()` service:
```python
info = device.GetDeviceInformation()
print(info)
# Example output: {'Manufacturer': '..', 'Model': '..', 'FirmwareVersion': '..', 'SerialNumber': '..'}
```
**5. Get RTSP URL**
Retrieve the RTSP stream URL for live video streaming from the device using `media()` service:
```python
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/`](./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](https://www.onvif.org/about/introduction-to-onvif-course). Please note that we are not endorsed or sponsored by ONVIF, see [Legal Notice](#legal-notice) for details.
## ONVIF CLI
> [!NOTE]
> The CLI is automatically installed when you install the `onvif-python` see [Installation](#installation). This feature has been available since `onvif-python` version [`>=0.1.1`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.1.1).




This library includes a powerful command-line interface (CLI) for interacting with ONVIF devices directly from your terminal. It supports both direct command execution and an interactive shell mode, providing a flexible and efficient way to manage and debug ONVIF devices.
### Features
- **Device Discovery:** Automatic ONVIF device discovery on local network using WS-Discovery protocol.
- **Interactive Shell:** A user-friendly shell with tab completion, command history, and colorized output.
- **Direct Command Execution:** Run ONVIF commands directly from the terminal for scripting and automation.
- **Automatic Discovery:** Automatically detects available services on the device.
- **Connection Management:** Supports HTTP/HTTPS, custom timeouts, and SSL verification.
- **Data Management:** Store results from commands and use them as parameters in subsequent commands.
- **Cross-Platform:** Works on Windows, macOS, Linux, and Raspberry Pi.
### Screenshoot
<table>
<tr>
<td width="34.2%">
<a href="https://github.com/nirsimetri/onvif-python">
<img src="https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/onvif_cli.png" />
</a>
</td>
<td width="65.8%">
<a href="https://github.com/nirsimetri/onvif-python">
<img src="https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/onvif_operations.png" />
</a>
</td>
</tr>
<tr>
<th align="center">
Onboarding
</th>
<th align="center">
List available operations
</th>
</tr>
</table>
### Help Command
<details>
<summary><b>1. Direct CLI</b></summary>
```bash
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--search SEARCH] [--timeout TIMEOUT] [--https]
[--no-verify] [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
[--health-check-interval HEALTH_CHECK_INTERVAL] [--version]
[service] [method] [params ...]
ONVIF Terminal Client — v0.1.8
https://github.com/nirsimetri/onvif-python
positional arguments:
service ONVIF service name (e.g., devicemgmt, media, ptz)
method Service method name (e.g., GetCapabilities, GetProfiles)
params Method parameters as Simple Parameter or JSON string
options:
-h, --help show this help message and exit
--host HOST, -H HOST ONVIF device IP address or hostname
--port PORT, -P PORT ONVIF device port (default: 80)
--username USERNAME, -u USERNAME
Username for authentication
--password PASSWORD, -p PASSWORD
Password for authentication
--discover, -d Discover ONVIF devices on the network using WS-Discovery
--search SEARCH, -s SEARCH
Filter discovered devices by types or scopes (case-insensitive substring match)
--timeout TIMEOUT Connection timeout in seconds (default: 10)
--https Use HTTPS instead of HTTP
--no-verify Disable SSL certificate verification
--no-patch Disable ZeepPatcher
--interactive, -i Start interactive mode
--debug Enable debug mode with XML capture
--wsdl WSDL Custom WSDL directory path
--cache {all,db,mem,none}
Caching mode for ONVIFClient (default: all). 'all': memory+disk, 'db': disk-only, 'mem': memory-only, 'none': disabled.
--health-check-interval HEALTH_CHECK_INTERVAL, -hci HEALTH_CHECK_INTERVAL
Health check interval in seconds for interactive mode (default: 10)
--version, -v Show ONVIF CLI version and exit
Examples:
# Discover ONVIF devices on network
onvif --discover --username admin --password admin123 --interactive
onvif media GetProfiles --discover --username admin
onvif -d -i
# Discover with filtering
onvif --discover --search ptz --interactive
onvif -d -s "C210" -i
onvif -d -s "audio_encoder" -u admin -p admin123 -i
# Direct command execution
onvif devicemgmt GetCapabilities Category=All --host 192.168.1.17 --port 8000 --username admin --password admin123
onvif ptz ContinuousMove ProfileToken=Profile_1 Velocity={"PanTilt": {"x": -0.1, "y": 0}} --host 192.168.1.17 --port 8000 --username admin --password admin123
# Interactive mode
onvif --host 192.168.1.17 --port 8000 --username admin --password admin123 --interactive
# Prompting for username and password
# (if not provided)
onvif -H 192.168.1.17 -P 8000 -i
# Using HTTPS
onvif media GetProfiles --host camera.example.com --port 443 --username admin --password admin123 --https
```
</details>
<details>
<summary><b>2. Interactive Shell</b></summary>
```bash
ONVIF Interactive Shell — v0.1.8
https://github.com/nirsimetri/onvif-python
Basic Commands:
capabilities, caps - Show device capabilities
services - Show available services with details
info - Show connection and device information
exit, quit - Exit the shell
shortcuts - Show available shortcuts
Navigation Commands:
<service> - Enter service mode (e.g., devicemgmt, media)
<service> <argument> - Enter service mode with argument (e.g. pullpoint SubscriptionRef=<value>)
cd <service> - Enter service mode (alias)
ls - List commands/services/methods in grid format
up - Exit current service mode (go up one level)
pwd - Show current service context
clear - Clear terminal screen
help <command> - Show help for a specific command
Service Mode Commands:
desc <method> - Show method documentation
type <method> - Show input/output types from WSDL
Method Execution:
<method> - Execute method without parameters
<method> {"param": "value"} - Execute method with JSON parameters
<method> param=value - Execute method with simple parameters
Data Management:
store <name> - Store last result with a name
show <name> - Show stored data
show <name>[0] - Show element at index (for lists)
show <name>.attribute - Show specific attribute
show - List all stored data
rm <name> - Remove stored data by name
cls - Clear all stored data
Using Stored Data in Methods:
Use $variable syntax to reference stored data in method parameters:
- $profiles[0].token - Access list element and attribute
- $profiles[0].VideoSourceConfiguration.SourceToken
Example:
GetProfiles - Get profiles
store profiles - Store result
show profiles[0].token - Show first profile token
GetImagingSettings VideoSourceToken=$profiles[0].VideoSourceConfiguration.SourceToken
Debug Commands:
debug - Show last SOAP request & response (if --debug enabled)
Tab Completion:
Use TAB key for auto-completion of commands, services, and methods
Type partial commands to see suggestions
Examples:
192.168.1.17:8000 > caps # Show capabilities
192.168.1.17:8000 > dev<TAB> # Completes to 'devicemgmt'
192.168.1.17:8000 > cd devicemgmt # Enter device management
192.168.1.17:8000/devicemgmt > Get<TAB> # Show methods starting with 'Get'
192.168.1.17:8000/devicemgmt > GetServices {"IncludeCapability": true}
192.168.1.17:8000/devicemgmt > GetServices IncludeCapability=True
192.168.1.17:8000/devicemgmt > store services_info
192.168.1.17:8000/devicemgmt > up # Exit service mode
192.168.1.17:8000 > # Back to root context
```
</details>
### Usage
**1. Interactive Mode**
The interactive shell is recommended for exploration and debugging. It provides an intuitive way to navigate services, call methods, and view results.
To start the interactive shell, provide the connection details:
```bash
onvif --host 192.168.1.17 --port 8000 --username admin --password admin123 -i
```
If you omit the username or password, you will be prompted to enter them securely.
**Interactive Shell Commands:**
| Command | Description |
|---|---|
| `help` | Show help information |
| `ls` | List available services or methods in the current context |
| `cd <service>` | Enter a service mode (e.g., `cd devicemgmt`) |
| `up` | Go back to the root context |
| `pwd` | Show the current service context |
| `desc <method>` | Show documentation for a method |
| `store <name>` | Store the last result with a variable name |
| `show <name>` | Display a stored variable |
| `exit` / `quit` | Exit the shell |
> [!IMPORTANT]
> You can see all the other commands available in the interactive shell by trying it out directly. The interactive shell runs periodic background health checks to detect connection loss. It uses silent TCP pings to avoid interrupting your work and will automatically exit if the device is unreachable, similar to an SSH session.
**Command Chaining with `&&`:**
The CLI supports chaining multiple commands in a single line using the `&&` operator, allowing you to execute sequential operations efficiently:
```bash
# Enter service and execute method in one line
192.168.1.17:8000 > media && GetProfiles && store profiles
# Chain multiple method calls
192.168.1.17:8000 > devicemgmt && GetDeviceInformation && store device_info
# Complex workflow
192.168.1.17:8000 > media && GetProfiles && store profiles && up && imaging && GetImagingSettings VideoSourceToken=$profiles[0].VideoSourceConfiguration.SourceToken
```
This feature is particularly useful for:
- Quick operations without entering service mode
- Scripting repetitive tasks
- Testing workflows
- Automating multi-step procedures
**2. Device Discovery (WS-Discovery)**
The CLI includes automatic ONVIF device discovery using the WS-Discovery protocol. This feature allows you to find all ONVIF-compliant devices on your local network without knowing their IP addresses beforehand.
**Discover and Connect Interactively:**
```bash
# Discover devices and enter interactive mode
onvif --discover --username admin --password admin123 --interactive
# Short form
onvif -d -u admin -p admin123 -i
# Discover with search filter
onvif --discover --search "C210" --interactive
onvif -d -s ptz -u admin -p admin123 -i
# Discover and interactive (will prompt for credentials)
onvif -d -i
```
**Discover and Execute Command:**
```bash
# Discover devices and execute a command on the selected device
onvif media GetProfiles --discover --username admin --password admin123
# Short form
onvif media GetProfiles -d -u admin -p admin123
```
**How Device Discovery Works:**
1. **Automatic Network Scanning**: Sends a WS-Discovery Probe message to the multicast address `239.255.255.250:3702`
2. **Device Detection**: Listens for ProbeMatch responses from ONVIF devices (default timeout: 4 seconds)
3. **Interactive Selection**: Displays a numbered list of discovered devices with their details:
- Device UUID (Endpoint Reference)
- XAddrs (ONVIF service URLs)
- Device Types (e.g., NetworkVideoTransmitter)
- Scopes (name, location, hardware, profile information)
4. **Connection**: Once you select a device, the CLI automatically connects using the discovered host and port
**Example Discovery Output:**
```
Discovering ONVIF devices on network...
Network interface: 192.168.1.100
Timeout: 4s
Found 2 ONVIF device(s):
[1] 192.168.1.14:2020
[id] uuid:3fa1fe68-b915-4053-a3e1-a8294833fe3c
[xaddrs] http://192.168.1.14:2020/onvif/device_service
[types] tdn:NetworkVideoTransmitter
[scopes] [name/C210] [hardware/C210] [Profile/Streaming] [location/Hong Kong]
[2] 192.168.1.17:8000
[id] urn:uuid:7d04ff31-61e6-11f0-a00c-6056eef47207
[xaddrs] http://192.168.1.17:8000/onvif/device_service
[types] dn:NetworkVideoTransmitter tds:Device
[scopes] [type/NetworkVideoTransmitter] [location/unknown] [name/IPC_123465959]
Select device number 1-2 or q to quit: 1
Selected: 192.168.1.14:2020
```
**Notes:**
- Discovery only works on the local network (same subnet)
- Some networks may block multicast traffic (check firewall settings)
- The `--host` and `--port` arguments are not required when using `--discover`
- You can still provide `--username` and `--password` upfront to avoid prompts
**3. Direct Command Execution**
You can also execute a single ONVIF command directly. This is useful for scripting or quick checks.
**Syntax:**
```bash
onvif <service> <method> [parameters...] -H <host> -P <port> -u <user> -p <pass>
```
**Example:**
```bash
# Get device capabilities
onvif devicemgmt GetCapabilities Category=All -H 192.168.1.17 -P 8000 -u admin -p admin123
# Move a PTZ camera
onvif ptz ContinuousMove ProfileToken=Profile_1 Velocity='{"PanTilt": {"x": 0.1}}' -H 192.168.1.17 -P 8000 -u admin -p admin123
```
### CLI Parameters
All `ONVIFClient` parameters (like `--timeout`, `--https`, `--cache`, etc.) are available as command-line arguments. Use `onvif --help` to see all available options.
## 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:
<details>
<summary><b>Basic Parameters</b></summary>
| 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 |
</details>
<details>
<summary><b>Connection Parameters</b></summary>
| 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) |
</details>
<details>
<summary><b>Caching Parameters</b></summary>
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `cache` | `CacheMode` | ❌ No | `CacheMode.ALL` | WSDL caching strategy (see **Cache Modes** below) |
</details>
<details>
<summary><b>Feature Parameters</b></summary>
| 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`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.0.4)) |
| `capture_xml` | `bool` | ❌ No | `False` | Enable XML capture plugin for debugging SOAP requests/responses, applied at ([`>=v0.0.6`](https://github.com/nirsimetri/onvif-python/releases/tag/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`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.1.0)) |
</details>
<details>
<summary><b>Cache Modes</b></summary>
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.
</details>
<details>
<summary><b>Usage Examples</b></summary>
**Basic Connection:**
```python
from onvif import ONVIFClient
# Minimal configuration
client = ONVIFClient("192.168.1.17", 80, "admin", "password")
```
**Secure Connection (HTTPS):**
```python
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):**
```python
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):**
```python
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):**
```python
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:**
```python
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)
```
</details>
<details>
<summary><b>Production Configuration</b></summary>
```python
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)
)
```
</details>
### 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
```python
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
> [!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:
- [List of tested devices (device-test)](https://github.com/nirsimetri/onvif-products-directory/blob/main/device-test)
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](https://github.com/nirsimetri/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](https://github.com/nirsimetri/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.
<details>
<summary><b>ONVIF profiles list</b></summary>
| Name | Specifications | Main Features | Typical Use Case | Support |
|-----------|----------------|---------------|------------------|---------|
| Profile_S | [Document](https://www.onvif.org/wp-content/uploads/2019/12/ONVIF_Profile_-S_Specification_v1-3.pdf) | Video streaming, PTZ, audio, multicasting | Network video transmitters (cameras) and receivers (recorders, VMS) | ✅ Yes |
| Profile_G | [Document](https://www.onvif.org/wp-content/uploads/2017/01/ONVIF_Profile_G_Specification_v1-0.pdf) | Recording, search, replay, video storage | Video recorders, storage devices | ✅ Yes |
| Profile_T | [Document](https://www.onvif.org/wp-content/uploads/2018/09/ONVIF_Profile_T_Specification_v1-0.pdf) | Advanced video streaming (H.265, analytics metadata, motion detection) | Modern cameras and clients | ✅ Yes |
| Profile_C | [Document](https://www.onvif.org/wp-content/uploads/2017/01/2013_12_ONVIF_Profile_C_Specification_v1-0.pdf) | Access control, door monitoring | Door controllers, access systems | ✅ Yes |
| Profile_A | [Document](https://www.onvif.org/wp-content/uploads/2017/06/ONVIF_Profile_A_Specification_v1-0.pdf) | Advanced access control configuration, credential management | Access control clients and devices | ✅ Yes |
| Profile_D | [Document](https://www.onvif.org/wp-content/uploads/2021/06/onvif-profile-d-specification-v1-0.pdf) | Access control peripherals (locks, sensors, relays) | Peripheral devices for access control | ✅ Yes |
| Profile_M | [Document](https://www.onvif.org/wp-content/uploads/2024/04/onvif-profile-m-specification-v1-1.pdf) | Metadata, analytics events, object detection | Analytics devices, metadata clients | ✅ Yes |
</details>
For a full description of each profile and its features, visit [ONVIF Profiles](https://www.onvif.org/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/`](./onvif/services). Or if you want to read in a more proper format visit [onvif-python AI Wiki](https://deepwiki.com/nirsimetri/onvif-python).
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](https://developer.onvif.org/pub/specs/branches/development/doc/index.html). This table provides a quick overview of the available ONVIF features and their technical documentation for integration and development purposes.
<details>
<summary><b>ONVIF services list</b></summary>
| Service | Specifications | Service Definitions | Schema Files | Status |
|------------------------|-------------------------------|-----------------------------|-------------------------------------|------------|
| Device Management | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Core.xml) | [device.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/device/wsdl/devicemgmt.wsdl) | [onvif.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/onvif.xsd) <br> [common.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/common.xsd) | ✅ Complete |
| Events | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Core.xml) | [event.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/events/wsdl/event.wsdl) | [onvif.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/onvif.xsd) <br> [common.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/common.xsd) | ⚠️ Partial |
| Access Control | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/AccessControl.xml) | [accesscontrol.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/pacs/accesscontrol.wsdl) | [types.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/pacs/types.xsd) | ✅ Complete |
| Access Rules | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/AccessRules.xml) | [accessrules.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/accessrules/wsdl/accessrules.wsdl) | - | ✅ Complete |
| Action Engine | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/ActionEngine.xml) | [actionengine.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/actionengine.wsdl) | - | ✅ Complete |
| Analytics | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Analytics.xml) | [analytics.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/wsdl/analytics.wsdl) | [rules.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/rules.xsd) <br> [humanbody.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/humanbody.xsd) <br> [humanface.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/humanface.xsd) | ✅ Complete |
| Application Management | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/AppMgmt.xml) | [appmgmt.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/appmgmt/wsdl/appmgmt.wsdl) | - | ✅ Complete |
| Authentication Behavior| [Document](https://developer.onvif.org/pub/specs/branches/development/doc/AuthenticationBehavior.xml) | [authenticationbehavior.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/authenticationbehavior/wsdl/authenticationbehavior.wsdl) | - | ✅ Complete |
| Cloud Integration | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/CloudIntegration.xml) | [cloudintegration.yaml](https://developer.onvif.org/pub/specs/branches/development/doc/yaml.php?yaml=cloudintegration.yaml) | - | ❌ Not yet |
| Credential | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Credential.xml) | [credential.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/credential/wsdl/credential.wsdl) | - | ✅ Complete |
| Device IO | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/DeviceIo.xml) | [deviceio.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/deviceio.wsdl) |- | ✅ Complete |
| Display | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Display.xml) | [display.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/display.wsdl) | - | ✅ Complete |
| Door Control | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/DoorControl.xml) | [doorcontrol.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/pacs/doorcontrol.wsdl) | - | ✅ Complete |
| Imaging | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Imaging.xml) | [imaging.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/imaging/wsdl/imaging.wsdl) | - | ✅ Complete |
| Media | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Media.xml) | [media.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/media/wsdl/media.wsdl) | - | ✅ Complete |
| Media 2 | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Media2.xml) | [media2.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/media/wsdl/media.wsdl) | - | ✅ Complete |
| Provisioning | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Provisioning.xml) | [provisioning.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/provisioning/wsdl/provisioning.wsdl) | - | ✅ Complete |
| PTZ | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/PTZ.xml) | [ptz.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/ptz/wsdl/ptz.wsdl) | - | ✅ Complete |
| Receiver | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Receiver.xml) | [receiver.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/receiver.wsdl) | - | ✅ Complete |
| Recording Control | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/RecordingControl.xml) | [recording.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/recording.wsdl) | - | ✅ Complete |
| Recording Search | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/RecordingSearch.xml) | [search.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/search.wsdl) | - | ✅ Complete |
| Replay Control | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Replay.xml) | [replay.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/replay.wsdl) | - | ✅ Complete |
| Resource Query | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/ResourceQuery.xml) | - | | ❌ Any idea? |
| Schedule | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Schedule.xml) | [schedule.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schedule/wsdl/schedule.wsdl) | - | ✅ Complete |
| Security | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Security.xml) | [advancedsecurity.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl) | - | ✅ Complete |
| Thermal | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Thermal.xml) | [thermal.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/thermal/wsdl/thermal.wsdl) | [radiometry.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/radiometry.xsd) | ✅ Complete |
| Uplink | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Uplink.xml) | [uplink.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/uplink/wsdl/uplink.wsdl) | - | ✅ Complete |
| WebRTC | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/WebRTC.xml) | - | - | ❌ Any idea? |
</details>
## 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.
<details>
<summary>Examples:</summary>
```python
client.devicemgmt() # DeviceBinding
client.media() # MediaBinding
client.ptz() # PTZBinding
...
```
✅ These are considered fixed and always accessed directly.
</details>
### 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)
<details>
<summary>Examples:</summary>
1. **Events**
- **Root:** `EventBinding`
- **Sub-bindings:**
- `PullPointSubscriptionBinding` (created via `CreatePullPointSubscription`)
- `SubscriptionManagerBinding` (manages existing subscriptions)
- `NotificationProducerBinding`
Usage in library:
```python
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:
```python
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:
```python
client.analytics() # root binding
client.ruleengine() # sub-binding accessor
```
</details>
### 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)
- [x] ~~Add debugging mode with raw xml on SOAP requests and responses.~~ ([c258162](https://github.com/nirsimetri/onvif-python/commit/c258162))
- [x] ~~Add functionality for `ONVIFClient` to accept a custom `wsdl_dir` service.~~ ([65f2570](https://github.com/nirsimetri/onvif-python/commit/65f2570))
- [x] ~~Add `ONVIF CLI` program to interact directly with ONVIF devices via terminal.~~ ([645be01](https://github.com/nirsimetri/onvif-python/commit/645be01))
- [ ] Add asynchronous (async/await) support for non-blocking ONVIF operations and concurrent device communication.
- [ ] Implement structured data models for ONVIF Schemas using [xsdata](https://github.com/tefra/xsdata).
- [ ] Integrate [xmltodict](https://github.com/martinblech/xmltodict) for simplified XML parsing and conversion.
- [ ] Enhance documentation with API references and diagrams (not from [AI Wiki](https://deepwiki.com/nirsimetri/onvif-python)).
- [ ] 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](https://github.com/nirsimetri/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](https://github.com/nirsimetri/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](https://github.com/nirsimetri/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](https://github.com/FalkTannhaeuser/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](https://github.com/openvideolibs/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
- [ONVIF Official Specifications](https://www.onvif.org/profiles/specifications/specification-history/)
- [ONVIF Official Specs Repository](https://github.com/onvif/specs)
- [ONVIF 2.0 Service Operation Index](https://www.onvif.org/onvif/ver20/util/operationIndex.html)
- [Usage Examples](./examples/)
## Legal Notice
This project is an **independent open-source implementation** of the [ONVIF](https://www.onvif.org) 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](https://www.onvif.org/conformant-products/). For authoritative reference and the latest official ONVIF specifications, please consult the [ONVIF Official Specifications](https://www.onvif.org/profiles/specifications/specification-history/).
## License
This project is licensed under the MIT License. See [LICENSE](./LICENSE.md) for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "onvif-python",
"maintainer": "Kaburagi",
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "onvif, Camera, onvif-python, ip-camera, cctv, soap, surveillance, cctv cameras, soap-client, onvif-client, onvif-library, onvif-specifications",
"author": null,
"author_email": "Nirsimetri Technologies\u00ae <open@nirsimetri.com>",
"download_url": "https://files.pythonhosted.org/packages/c7/55/18b4ba37c8c66a2dfcc520f5e75c2965961b8dbb4fa96336559438807e8a/onvif_python-0.1.8.tar.gz",
"platform": null,
"description": "<h1 align=\"center\">ONVIF Python</h1>\n\n<div align=\"center\">\n\t\n[](https://app.codacy.com/gh/nirsimetri/onvif-python/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)\n[](https://deepwiki.com/nirsimetri/onvif-python)\n[](https://pypi.org/project/onvif-python/)\n[](https://clickpy.clickhouse.com/dashboard/onvif-python)\n<br>\n[](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml)\n[](https://github.com/nirsimetri/onvif-python/actions/workflows/python-publish.yml)\n</div>\n\n<h1 align=\"center\">\n <img src=\"https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/carbon_onvif.png\" alt=\"onvif\" width=\"700px\">\n <br>\n</h1>\n\n**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. \n\n**[ONVIF](https://www.onvif.org) (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. \n\nBehind the scenes, ONVIF communication relies on **[SOAP](https://en.wikipedia.org/wiki/SOAP) (Simple Object Access Protocol)** \u2014 an [XML](https://en.wikipedia.org/wiki/XML)-based messaging protocol with strict schema definitions ([WSDL](https://en.wikipedia.org/wiki/Web_Services_Description_Language)/[XSD](https://en.wikipedia.org/wiki/XML_Schema_(W3C))). SOAP ensures interoperability, but when used directly it can be verbose, complex, and error-prone. \n\nThis 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 \u2014 the library takes care of it, letting you focus on building functionality. \n\n## Key Features\n- Full implementation of ONVIF core services and profiles \n- Support for device discovery, media streaming, PTZ control, event management, and more \n- Pythonic abstraction over SOAP requests and responses (no need to handcraft XML) \n- Extensible architecture for custom ONVIF extensions \n- Compatible with multiple ONVIF specification versions \n- Example scripts and tests included \n\n## Who Is It For?\n- **Individual developers** exploring ONVIF or building hobby projects \n- **Companies** building video intelligence, analytics, or VMS platforms \n- **Security integrators** who need reliable ONVIF interoperability across devices\n\n## Requirements\n\n- **Python**: 3.9 or higher\n- **Dependencies**:\n - [`zeep>=4.3.0`](https://github.com/mvantellingen/python-zeep) - SOAP client for ONVIF communication\n - [`requests>=2.32.0`](https://github.com/psf/requests) - HTTP library for network requests\n\n## Installation\n\nFrom official [PyPI](https://pypi.org/project/onvif-python/):\n```bash\npip install onvif-python\n```\nOr clone this repository and install locally:\n```bash\ngit clone https://github.com/nirsimetri/onvif-python\ncd onvif-python\npip install .\n```\n\n## Usage Example\n\n> [!TIP]\n> You can view the complete documentation automatically generated by DeepWiki via the [onvif-python AI Wiki](https://deepwiki.com/nirsimetri/onvif-python) link. We currently do not have an official documentation site. Help us create more examples and helpful documentation by [contributing](https://github.com/nirsimetri/onvif-python?tab=contributing-ov-file).\n\nBelow are simple examples to help you get started with the ONVIF Python library. These demonstrate how to discover and connect to ONVIF-compliant devices and retrieve basic device information.\n\n**1. Discover ONVIF Devices (Optional)**\n\nUse `ONVIFDiscovery` (applied at [`>=v0.1.6`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.1.6)) to automatically find ONVIF devices on your local network:\n\n```python\nfrom onvif import ONVIFDiscovery\n\n# Create discovery instance\ndiscovery = ONVIFDiscovery(timeout=5)\n\n# Discover devices\ndevices = discovery.discover()\n\n# Or with\n# Discover with search filter by types or scopes (case-insensitive substring match)\ndevices = discovery.discover(search=\"Profile/Streaming\")\n\n# Display discovered devices\nfor device in devices:\n print(f\"Found device at {device['host']}:{device['port']}\")\n print(f\" Scopes: {device.get('scopes', [])}\")\n print(f\" XAddrs: {device['xaddrs']}\")\n```\n\n**2. Initialize the ONVIFClient**\n\nCreate an instance of `ONVIFClient` by providing your device's IP address, port, username, and password:\n\n```python\nfrom onvif import ONVIFClient\n\n# Basic connection\nclient = ONVIFClient(\"192.168.1.17\", 8000, \"admin\", \"admin123\")\n\n# With custom WSDL directory (optional)\nclient = ONVIFClient(\n \"192.168.1.17\", 8000, \"admin\", \"admin123\",\n wsdl_dir=\"/path/to/custom/wsdl\" # Use custom WSDL files in this path\n)\n```\n\n**3. Create Service Instance**\n\n`ONVIFClient` provides several main services that can be accessed via the following methods:\n\n- `client.devicemgmt()` \u2014 Device Management\n- `client.events()` \u2014 Events\n- `client.imaging()` \u2014 Imaging\n- `client.media()` \u2014 Media\n- `client.ptz()` \u2014 PTZ (Pan-Tilt-Zoom)\n- `client.analytics()` \u2014 Analytics\n\nand so on, check [Implemented ONVIF Services](https://github.com/nirsimetri/onvif-python?tab=readme-ov-file#implemented-onvif-services) for more details\n\nExample usage:\n```python\ndevice = client.devicemgmt() # Device Management (Core)\nmedia = client.media() # Media\n```\n\n**4. Get Device Information**\n\nRetrieve basic information about the device, such as manufacturer, model, firmware version, and serial number using `devicemgmt()` service:\n\n```python\ninfo = device.GetDeviceInformation()\nprint(info)\n# Example output: {'Manufacturer': '..', 'Model': '..', 'FirmwareVersion': '..', 'SerialNumber': '..'}\n```\n\n**5. Get RTSP URL**\n\nRetrieve the RTSP stream URL for live video streaming from the device using `media()` service:\n\n```python\nprofile = media.GetProfiles()[0] # use the first profile\nstream = media.GetStreamUri(\n ProfileToken=profile.token, \n\tStreamSetup={\"Stream\": \"RTP-Unicast\", \"Transport\": {\"Protocol\": \"RTSP\"}}\n)\nprint(stream)\n# Example output: {'Uri': 'rtsp://192.168.1.17:8554/Streaming/Channels/101', ...}\n```\n\nExplore more advanced usage and service-specific operations in the [`examples/`](./examples/) folder.\n\n> [!IMPORTANT]\n> 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](https://www.onvif.org/about/introduction-to-onvif-course). Please note that we are not endorsed or sponsored by ONVIF, see [Legal Notice](#legal-notice) for details.\n\n## ONVIF CLI\n\n> [!NOTE]\n> The CLI is automatically installed when you install the `onvif-python` see [Installation](#installation). This feature has been available since `onvif-python` version [`>=0.1.1`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.1.1).\n\n\n\n\n\n\nThis library includes a powerful command-line interface (CLI) for interacting with ONVIF devices directly from your terminal. It supports both direct command execution and an interactive shell mode, providing a flexible and efficient way to manage and debug ONVIF devices.\n\n### Features\n\n- **Device Discovery:** Automatic ONVIF device discovery on local network using WS-Discovery protocol.\n- **Interactive Shell:** A user-friendly shell with tab completion, command history, and colorized output.\n- **Direct Command Execution:** Run ONVIF commands directly from the terminal for scripting and automation.\n- **Automatic Discovery:** Automatically detects available services on the device.\n- **Connection Management:** Supports HTTP/HTTPS, custom timeouts, and SSL verification.\n- **Data Management:** Store results from commands and use them as parameters in subsequent commands.\n- **Cross-Platform:** Works on Windows, macOS, Linux, and Raspberry Pi.\n\n### Screenshoot\n\n<table>\n <tr>\n <td width=\"34.2%\">\n <a href=\"https://github.com/nirsimetri/onvif-python\">\n <img src=\"https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/onvif_cli.png\" />\n </a>\n </td>\n <td width=\"65.8%\">\n <a href=\"https://github.com/nirsimetri/onvif-python\">\n <img src=\"https://raw.githubusercontent.com/nirsimetri/onvif-python/refs/heads/main/assets/onvif_operations.png\" />\n </a>\n </td>\n </tr>\n <tr>\n <th align=\"center\">\n Onboarding\n </th>\n <th align=\"center\">\n List available operations\n </th>\n </tr>\n</table>\n\n### Help Command\n\n<details>\n<summary><b>1. Direct CLI</b></summary> \n\n```bash\nusage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--search SEARCH] [--timeout TIMEOUT] [--https]\n [--no-verify] [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]\n [--health-check-interval HEALTH_CHECK_INTERVAL] [--version]\n [service] [method] [params ...]\n\nONVIF Terminal Client \u2014 v0.1.8\nhttps://github.com/nirsimetri/onvif-python\n\npositional arguments:\n service ONVIF service name (e.g., devicemgmt, media, ptz)\n method Service method name (e.g., GetCapabilities, GetProfiles)\n params Method parameters as Simple Parameter or JSON string\n\noptions:\n -h, --help show this help message and exit\n --host HOST, -H HOST ONVIF device IP address or hostname\n --port PORT, -P PORT ONVIF device port (default: 80)\n --username USERNAME, -u USERNAME\n Username for authentication\n --password PASSWORD, -p PASSWORD\n Password for authentication\n --discover, -d Discover ONVIF devices on the network using WS-Discovery\n --search SEARCH, -s SEARCH\n Filter discovered devices by types or scopes (case-insensitive substring match)\n --timeout TIMEOUT Connection timeout in seconds (default: 10)\n --https Use HTTPS instead of HTTP\n --no-verify Disable SSL certificate verification\n --no-patch Disable ZeepPatcher\n --interactive, -i Start interactive mode\n --debug Enable debug mode with XML capture\n --wsdl WSDL Custom WSDL directory path\n --cache {all,db,mem,none}\n Caching mode for ONVIFClient (default: all). 'all': memory+disk, 'db': disk-only, 'mem': memory-only, 'none': disabled.\n --health-check-interval HEALTH_CHECK_INTERVAL, -hci HEALTH_CHECK_INTERVAL\n Health check interval in seconds for interactive mode (default: 10)\n --version, -v Show ONVIF CLI version and exit\n\nExamples:\n # Discover ONVIF devices on network\n onvif --discover --username admin --password admin123 --interactive\n onvif media GetProfiles --discover --username admin\n onvif -d -i\n\n # Discover with filtering\n onvif --discover --search ptz --interactive\n onvif -d -s \"C210\" -i\n onvif -d -s \"audio_encoder\" -u admin -p admin123 -i\n\n # Direct command execution\n onvif devicemgmt GetCapabilities Category=All --host 192.168.1.17 --port 8000 --username admin --password admin123\n onvif ptz ContinuousMove ProfileToken=Profile_1 Velocity={\"PanTilt\": {\"x\": -0.1, \"y\": 0}} --host 192.168.1.17 --port 8000 --username admin --password admin123\n\n # Interactive mode\n onvif --host 192.168.1.17 --port 8000 --username admin --password admin123 --interactive\n\n # Prompting for username and password\n # (if not provided)\n onvif -H 192.168.1.17 -P 8000 -i\n\n # Using HTTPS\n onvif media GetProfiles --host camera.example.com --port 443 --username admin --password admin123 --https\n```\n\n</details>\n\n<details>\n<summary><b>2. Interactive Shell</b></summary> \n\n```bash\nONVIF Interactive Shell \u2014 v0.1.8\nhttps://github.com/nirsimetri/onvif-python\n\nBasic Commands:\n capabilities, caps - Show device capabilities\n services - Show available services with details\n info - Show connection and device information\n exit, quit - Exit the shell\n shortcuts - Show available shortcuts\n\nNavigation Commands:\n <service> - Enter service mode (e.g., devicemgmt, media)\n <service> <argument> - Enter service mode with argument (e.g. pullpoint SubscriptionRef=<value>)\n cd <service> - Enter service mode (alias)\n ls - List commands/services/methods in grid format\n up - Exit current service mode (go up one level)\n pwd - Show current service context\n clear - Clear terminal screen\n help <command> - Show help for a specific command\n\nService Mode Commands:\n desc <method> - Show method documentation\n type <method> - Show input/output types from WSDL\n\nMethod Execution:\n <method> - Execute method without parameters\n <method> {\"param\": \"value\"} - Execute method with JSON parameters\n <method> param=value - Execute method with simple parameters\n\nData Management:\n store <name> - Store last result with a name\n show <name> - Show stored data\n show <name>[0] - Show element at index (for lists)\n show <name>.attribute - Show specific attribute\n show - List all stored data\n rm <name> - Remove stored data by name\n cls - Clear all stored data\n\nUsing Stored Data in Methods:\n Use $variable syntax to reference stored data in method parameters:\n - $profiles[0].token - Access list element and attribute\n - $profiles[0].VideoSourceConfiguration.SourceToken\n\n Example:\n GetProfiles - Get profiles\n store profiles - Store result\n show profiles[0].token - Show first profile token\n GetImagingSettings VideoSourceToken=$profiles[0].VideoSourceConfiguration.SourceToken\n\nDebug Commands:\n debug - Show last SOAP request & response (if --debug enabled)\n\nTab Completion:\n Use TAB key for auto-completion of commands, services, and methods\n Type partial commands to see suggestions\n\nExamples:\n 192.168.1.17:8000 > caps # Show capabilities\n 192.168.1.17:8000 > dev<TAB> # Completes to 'devicemgmt'\n 192.168.1.17:8000 > cd devicemgmt # Enter device management\n 192.168.1.17:8000/devicemgmt > Get<TAB> # Show methods starting with 'Get'\n 192.168.1.17:8000/devicemgmt > GetServices {\"IncludeCapability\": true}\n 192.168.1.17:8000/devicemgmt > GetServices IncludeCapability=True\n 192.168.1.17:8000/devicemgmt > store services_info\n 192.168.1.17:8000/devicemgmt > up # Exit service mode\n 192.168.1.17:8000 > # Back to root context\n```\n\n</details>\n\n### Usage\n\n**1. Interactive Mode**\n\nThe interactive shell is recommended for exploration and debugging. It provides an intuitive way to navigate services, call methods, and view results.\n\nTo start the interactive shell, provide the connection details:\n\n```bash\nonvif --host 192.168.1.17 --port 8000 --username admin --password admin123 -i\n```\n\nIf you omit the username or password, you will be prompted to enter them securely.\n\n**Interactive Shell Commands:**\n| Command | Description |\n|---|---|\n| `help` | Show help information |\n| `ls` | List available services or methods in the current context |\n| `cd <service>` | Enter a service mode (e.g., `cd devicemgmt`) |\n| `up` | Go back to the root context |\n| `pwd` | Show the current service context |\n| `desc <method>` | Show documentation for a method |\n| `store <name>` | Store the last result with a variable name |\n| `show <name>` | Display a stored variable |\n| `exit` / `quit` | Exit the shell |\n\n> [!IMPORTANT]\n> You can see all the other commands available in the interactive shell by trying it out directly. The interactive shell runs periodic background health checks to detect connection loss. It uses silent TCP pings to avoid interrupting your work and will automatically exit if the device is unreachable, similar to an SSH session.\n\n**Command Chaining with `&&`:**\n\nThe CLI supports chaining multiple commands in a single line using the `&&` operator, allowing you to execute sequential operations efficiently:\n\n```bash\n# Enter service and execute method in one line\n192.168.1.17:8000 > media && GetProfiles && store profiles\n\n# Chain multiple method calls\n192.168.1.17:8000 > devicemgmt && GetDeviceInformation && store device_info\n\n# Complex workflow\n192.168.1.17:8000 > media && GetProfiles && store profiles && up && imaging && GetImagingSettings VideoSourceToken=$profiles[0].VideoSourceConfiguration.SourceToken\n```\n\nThis feature is particularly useful for:\n- Quick operations without entering service mode\n- Scripting repetitive tasks\n- Testing workflows\n- Automating multi-step procedures\n\n**2. Device Discovery (WS-Discovery)**\n\nThe CLI includes automatic ONVIF device discovery using the WS-Discovery protocol. This feature allows you to find all ONVIF-compliant devices on your local network without knowing their IP addresses beforehand.\n\n**Discover and Connect Interactively:**\n```bash\n# Discover devices and enter interactive mode\nonvif --discover --username admin --password admin123 --interactive\n\n# Short form\nonvif -d -u admin -p admin123 -i\n\n# Discover with search filter\nonvif --discover --search \"C210\" --interactive\nonvif -d -s ptz -u admin -p admin123 -i\n\n# Discover and interactive (will prompt for credentials)\nonvif -d -i\n```\n\n**Discover and Execute Command:**\n```bash\n# Discover devices and execute a command on the selected device\nonvif media GetProfiles --discover --username admin --password admin123\n\n# Short form\nonvif media GetProfiles -d -u admin -p admin123\n```\n\n**How Device Discovery Works:**\n\n1. **Automatic Network Scanning**: Sends a WS-Discovery Probe message to the multicast address `239.255.255.250:3702`\n2. **Device Detection**: Listens for ProbeMatch responses from ONVIF devices (default timeout: 4 seconds)\n3. **Interactive Selection**: Displays a numbered list of discovered devices with their details:\n - Device UUID (Endpoint Reference)\n - XAddrs (ONVIF service URLs)\n - Device Types (e.g., NetworkVideoTransmitter)\n - Scopes (name, location, hardware, profile information)\n4. **Connection**: Once you select a device, the CLI automatically connects using the discovered host and port\n\n**Example Discovery Output:**\n```\nDiscovering ONVIF devices on network...\nNetwork interface: 192.168.1.100\nTimeout: 4s\n\nFound 2 ONVIF device(s):\n\n[1] 192.168.1.14:2020\n [id] uuid:3fa1fe68-b915-4053-a3e1-a8294833fe3c\n [xaddrs] http://192.168.1.14:2020/onvif/device_service\n [types] tdn:NetworkVideoTransmitter\n [scopes] [name/C210] [hardware/C210] [Profile/Streaming] [location/Hong Kong]\n\n[2] 192.168.1.17:8000\n [id] urn:uuid:7d04ff31-61e6-11f0-a00c-6056eef47207\n [xaddrs] http://192.168.1.17:8000/onvif/device_service\n [types] dn:NetworkVideoTransmitter tds:Device\n [scopes] [type/NetworkVideoTransmitter] [location/unknown] [name/IPC_123465959]\n\nSelect device number 1-2 or q to quit: 1\n\nSelected: 192.168.1.14:2020\n```\n\n**Notes:**\n\n- Discovery only works on the local network (same subnet)\n- Some networks may block multicast traffic (check firewall settings)\n- The `--host` and `--port` arguments are not required when using `--discover`\n- You can still provide `--username` and `--password` upfront to avoid prompts\n\n**3. Direct Command Execution**\n\nYou can also execute a single ONVIF command directly. This is useful for scripting or quick checks.\n\n**Syntax:**\n```bash\nonvif <service> <method> [parameters...] -H <host> -P <port> -u <user> -p <pass>\n```\n\n**Example:**\n```bash\n# Get device capabilities\nonvif devicemgmt GetCapabilities Category=All -H 192.168.1.17 -P 8000 -u admin -p admin123\n\n# Move a PTZ camera\nonvif ptz ContinuousMove ProfileToken=Profile_1 Velocity='{\"PanTilt\": {\"x\": 0.1}}' -H 192.168.1.17 -P 8000 -u admin -p admin123\n```\n\n### CLI Parameters\n\nAll `ONVIFClient` parameters (like `--timeout`, `--https`, `--cache`, etc.) are available as command-line arguments. Use `onvif --help` to see all available options.\n\n## ONVIFClient Parameters\n\nThe `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:\n\n\n<details>\n<summary><b>Basic Parameters</b></summary>\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `host` | `str` | \u2705 Yes | - | IP address or hostname of the ONVIF device (e.g., `\"192.168.1.17\"`) |\n| `port` | `int` | \u2705 Yes | - | Port number for ONVIF service (common ports: `80`, `8000`, `8080`) |\n| `username` | `str` | \u2705 Yes | - | Username for device authentication (use digest authentication) |\n| `password` | `str` | \u2705 Yes | - | Password for device authentication |\n\n</details>\n\n<details>\n<summary><b>Connection Parameters</b></summary>\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `timeout` | `int` | \u274c No | `10` | Connection timeout in seconds for SOAP requests |\n| `use_https` | `bool` | \u274c No | `False` | Use HTTPS instead of HTTP for secure communication |\n| `verify_ssl` | `bool` | \u274c No | `True` | Verify SSL certificates when using HTTPS (set to `False` for self-signed certificates) |\n\n</details>\n\n<details>\n<summary><b>Caching Parameters</b></summary>\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `cache` | `CacheMode` | \u274c No | `CacheMode.ALL` | WSDL caching strategy (see **Cache Modes** below) |\n\n</details>\n\n<details>\n<summary><b>Feature Parameters</b></summary>\n\n| Parameter | Type | Required | Default | Description |\n|-----------|------|----------|---------|-------------|\n| `apply_patch` | `bool` | \u274c No | `True` | Enable zeep patching for better `xsd:any` field parsing and automatic flattening, applied at ([`>=v0.0.4`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.0.4)) |\n| `capture_xml` | `bool` | \u274c No | `False` | Enable XML capture plugin for debugging SOAP requests/responses, applied at ([`>=v0.0.6`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.0.6)) |\n| `wsdl_dir` | `str` | \u274c 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`](https://github.com/nirsimetri/onvif-python/releases/tag/v0.1.0)) |\n\n</details>\n\n<details>\n<summary><b>Cache Modes</b></summary> \n\nThe library provides four caching strategies via the `CacheMode` enum:\n\n| Mode | Description | Best For | Startup Speed | Disk Usage | Memory Usage |\n|------|-------------|----------|---------------|------------|--------------|\n| `CacheMode.ALL` | In-memory + disk cache (SQLite) | Production servers, multi-device apps | Fast | High | High |\n| `CacheMode.DB` | Disk cache only (SQLite) | Batch jobs, CLI tools | Medium | Medium | Low |\n| `CacheMode.MEM` | In-memory cache only | Short-lived scripts, demos | Medium | None | Medium |\n| `CacheMode.NONE` | No caching | Testing, debugging | Slow | None | Low |\n\n**Recommendation:** Use `CacheMode.ALL` (default) for production applications to maximize performance.\n\n</details>\n\n<details>\n<summary><b>Usage Examples</b></summary>\n\n**Basic Connection:**\n```python\nfrom onvif import ONVIFClient\n\n# Minimal configuration\nclient = ONVIFClient(\"192.168.1.17\", 80, \"admin\", \"password\")\n```\n\n**Secure Connection (HTTPS):**\n```python\nfrom onvif import ONVIFClient\n\n# Connect via HTTPS with custom timeout\nclient = ONVIFClient(\n \"your-cctv-node.viewplexus.com\", \n 443, # HTTPS port\n \"admin\", \n \"password\",\n timeout=30,\n use_https=True\n)\n```\n\n**Performance Optimized (Memory Cache):**\n```python\nfrom onvif import ONVIFClient, CacheMode\n\n# Use memory-only cache for quick scripts\nclient = ONVIFClient(\n \"192.168.1.17\", \n 80, \n \"admin\", \n \"password\",\n cache=CacheMode.MEM\n)\n```\n\n**No Caching and No Zeep Patching (Testing):**\n```python\nfrom onvif import ONVIFClient, CacheMode\n\n# Disable all caching for testing\nclient = ONVIFClient(\n \"192.168.1.17\", \n 80, \n \"admin\", \n \"password\",\n cache=CacheMode.NONE,\n apply_patch=False # Use original zeep behavior\n)\n```\n\n**Debugging Mode (XML Capture):**\n```python\nfrom onvif import ONVIFClient\n\n# Enable XML capture for debugging\nclient = ONVIFClient(\n \"192.168.1.17\", \n 80, \n \"admin\", \n \"password\",\n capture_xml=True # Captures all SOAP requests/responses\n)\n\n# Make some ONVIF calls\ndevice = client.devicemgmt()\ninfo = device.GetDeviceInformation()\nservices = device.GetCapabilities()\n\n# Access the XML capture plugin\nif client.xml_plugin:\n # Get last captured request/response\n print(\"Last Request XML:\")\n print(client.xml_plugin.last_sent_xml)\n \n print(\"\\nLast Response XML:\")\n print(client.xml_plugin.last_received_xml)\n \n print(f\"\\nLast Operation: {client.xml_plugin.last_operation}\")\n \n # Get complete history of all requests/responses\n print(f\"\\nTotal captured operations: {len(client.xml_plugin.history)}\")\n for item in client.xml_plugin.history:\n print(f\" - {item['operation']} ({item['type']})\")\n \n # Save captured XML to files\n client.xml_plugin.save_to_file(\n request_file=\"last_request.xml\",\n response_file=\"last_response.xml\"\n )\n \n # Clear history when done\n client.xml_plugin.clear_history()\n```\n\n> **XML Capture Plugin Methods:**\n> - `last_sent_xml` - Get the last SOAP request XML\n> - `last_received_xml` - Get the last SOAP response XML\n> - `last_operation` - Get the name of the last operation\n> - `history` - List of all captured requests/responses with metadata\n> - `get_last_request()` - Method to get last request\n> - `get_last_response()` - Method to get last response\n> - `get_history()` - Method to get all history\n> - `save_to_file(request_file, response_file)` - Save XML to files\n> - `clear_history()` - Clear captured history\n\n**Custom WSDL Directory:**\n```python\nfrom onvif import ONVIFClient\n\n# Use custom WSDL files instead of built-in ones\nclient = ONVIFClient(\n \"192.168.1.17\", \n 80, \n \"admin\", \n \"password\",\n wsdl_dir=\"/path/to/custom/wsdl\" # Custom WSDL directory\n)\n\n# All services will automatically use custom WSDL files\ndevice = client.devicemgmt()\nmedia = client.media()\nptz = client.ptz()\n\n# The custom WSDL directory should have a flat structure:\n# /path/to/custom/wsdl/\n# \u251c\u2500\u2500 devicemgmt.wsdl\n# \u251c\u2500\u2500 media.wsdl\n# \u251c\u2500\u2500 ptz.wsdl\n# \u251c\u2500\u2500 imaging.wsdl\n# \u2514\u2500\u2500 ... (other WSDL files)\n```\n\n</details>\n\n<details>\n<summary><b>Production Configuration</b></summary>\n\n```python\nfrom onvif import ONVIFClient, CacheMode\n\n# Recommended production settings\nclient = ONVIFClient(\n host=\"your-cctv-node.viewplexus.com\",\n port=443,\n username=\"admin\",\n password=\"secure_password\",\n timeout=15,\n cache=CacheMode.ALL, # Maximum performance (default)\n use_https=True, # Secure communication\n verify_ssl=True, # Verify certificates (default)\n apply_patch=True, # Enhanced parsing (default)\n capture_xml=False, # Disable debug mode (default)\n wsdl_dir=None # Use built-in WSDL files (default)\n)\n```\n</details>\n\n### Notes\n\n- **Authentication:** This library uses **WS-UsernameToken with Digest** authentication by default, which is the standard for ONVIF devices.\n- **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.\n- **XML Capture:** Only use `capture_xml=True` during development/debugging as it increases memory usage and may expose sensitive data in logs.\n- **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.).\n- **Cache Location:** Disk cache (when using `CacheMode.DB` or `CacheMode.ALL`) is stored in `~/.onvif-python/onvif_zeep_cache.sqlite`.\n\n## Service Discovery: Understanding Device Capabilities\n\n> [!WARNING]\n> 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.\n\n**Why discover device services?**\n\n- **Device Diversity:** Not all ONVIF devices support every service. Available services may vary by manufacturer, model, firmware, or configuration.\n- **Error Prevention:** Attempting to use unsupported services can result in failed requests, exceptions, or undefined behavior.\n- **Dynamic Feature Detection:** Devices may enable or disable services over time (e.g., after firmware updates or configuration changes).\n- **Optimized Integration:** By checking available services, your application can adapt its workflow and UI to match the device's actual features.\n\n**How service discovery works in this library:**\n\nThe `ONVIFClient` uses a **3-tier discovery approach** to maximize device compatibility:\n\n1. **GetServices (Preferred)** - Tries `GetServices` first for detailed service information\n2. **GetCapabilities (Fallback)** - Falls back to `GetCapabilities` if `GetServices` is not supported\n3. **Default URLs (Final Fallback)** - Uses standard ONVIF URLs as last resort\n\n```python\nfrom onvif import ONVIFClient\n\nclient = ONVIFClient(\"192.168.1.17\", 8000, \"admin\", \"admin123\")\n\n# Check what discovery method was used\nif client.services:\n print(\"Service discovery: GetServices (preferred)\")\n print(\"Discovered services:\", len(client.services))\n print(\"Service map:\", client._service_map)\nelif client.capabilities:\n print(\"Service discovery: GetCapabilities (fallback)\")\n print(\"Available capabilities:\", client.capabilities)\nelse:\n print(\"Service discovery: Using default URLs\")\n```\n\n**Why this approach?**\n\n- **GetServices** provides the most accurate and detailed service information, but it's **optional** in the ONVIF specification\n- **GetCapabilities** is **mandatory** for all ONVIF-compliant devices, ensuring broader compatibility\n- **Default URLs** guarantee basic connectivity even with non-compliant devices\n\n> [!TIP]\n> 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.\n\n## Tested Devices\n\nThis 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:\n\n- [List of tested devices (device-test)](https://github.com/nirsimetri/onvif-products-directory/blob/main/device-test)\n\nIf your device is not listed right now, feel free to contribute your test results or feedback via Issues or Discussions at [onvif-products-directory](https://github.com/nirsimetri/onvif-products-directory). Your contribution will be invaluable to the community and the public.\n\n> [!IMPORTANT]\n> Device testing contributions must be made with a real device and use the scripts provided in the [onvif-products-directory](https://github.com/nirsimetri/onvif-products-directory) repo. Please be sure to contribute using a device model not already listed.\n\n## Supported ONVIF Profiles\n\nThis 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.\n\n<details>\n<summary><b>ONVIF profiles list</b></summary>\n\n| Name | Specifications | Main Features | Typical Use Case | Support |\n|-----------|----------------|---------------|------------------|---------|\n| Profile_S | [Document](https://www.onvif.org/wp-content/uploads/2019/12/ONVIF_Profile_-S_Specification_v1-3.pdf) | Video streaming, PTZ, audio, multicasting | Network video transmitters (cameras) and receivers (recorders, VMS) | \u2705 Yes |\n| Profile_G | [Document](https://www.onvif.org/wp-content/uploads/2017/01/ONVIF_Profile_G_Specification_v1-0.pdf) | Recording, search, replay, video storage | Video recorders, storage devices | \u2705 Yes |\n| Profile_T | [Document](https://www.onvif.org/wp-content/uploads/2018/09/ONVIF_Profile_T_Specification_v1-0.pdf) | Advanced video streaming (H.265, analytics metadata, motion detection) | Modern cameras and clients | \u2705 Yes |\n| Profile_C | [Document](https://www.onvif.org/wp-content/uploads/2017/01/2013_12_ONVIF_Profile_C_Specification_v1-0.pdf) | Access control, door monitoring | Door controllers, access systems | \u2705 Yes |\n| Profile_A | [Document](https://www.onvif.org/wp-content/uploads/2017/06/ONVIF_Profile_A_Specification_v1-0.pdf) | Advanced access control configuration, credential management | Access control clients and devices | \u2705 Yes |\n| Profile_D | [Document](https://www.onvif.org/wp-content/uploads/2021/06/onvif-profile-d-specification-v1-0.pdf) | Access control peripherals (locks, sensors, relays) | Peripheral devices for access control | \u2705 Yes |\n| Profile_M | [Document](https://www.onvif.org/wp-content/uploads/2024/04/onvif-profile-m-specification-v1-1.pdf) | Metadata, analytics events, object detection | Analytics devices, metadata clients | \u2705 Yes |\n\n</details>\n\nFor a full description of each profile and its features, visit [ONVIF Profiles](https://www.onvif.org/profiles/).\n\n## Implemented ONVIF Services\n\n> [!NOTE]\n> For details about the available service functions and methods already implemented in this library, see the source code in [`onvif/services/`](./onvif/services). Or if you want to read in a more proper format visit [onvif-python AI Wiki](https://deepwiki.com/nirsimetri/onvif-python).\n\nBelow 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](https://developer.onvif.org/pub/specs/branches/development/doc/index.html). This table provides a quick overview of the available ONVIF features and their technical documentation for integration and development purposes.\n\n<details>\n<summary><b>ONVIF services list</b></summary>\n\n| Service | Specifications | Service Definitions | Schema Files | Status |\n|------------------------|-------------------------------|-----------------------------|-------------------------------------|------------|\n| Device Management | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Core.xml) | [device.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/device/wsdl/devicemgmt.wsdl) | [onvif.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/onvif.xsd) <br> [common.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/common.xsd) | \u2705 Complete |\n| Events | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Core.xml) | [event.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/events/wsdl/event.wsdl) | [onvif.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/onvif.xsd) <br> [common.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schema/common.xsd) | \u26a0\ufe0f Partial |\n| Access Control | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/AccessControl.xml) | [accesscontrol.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/pacs/accesscontrol.wsdl) | [types.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/pacs/types.xsd) | \u2705 Complete |\n| Access Rules | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/AccessRules.xml) | [accessrules.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/accessrules/wsdl/accessrules.wsdl) | - | \u2705 Complete |\n| Action Engine | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/ActionEngine.xml) | [actionengine.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/actionengine.wsdl) | - | \u2705 Complete |\n| Analytics | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Analytics.xml) | [analytics.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/wsdl/analytics.wsdl) | [rules.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/rules.xsd) <br> [humanbody.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/humanbody.xsd) <br> [humanface.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/humanface.xsd) | \u2705 Complete |\n| Application Management | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/AppMgmt.xml) | [appmgmt.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/appmgmt/wsdl/appmgmt.wsdl) | - | \u2705 Complete |\n| Authentication Behavior| [Document](https://developer.onvif.org/pub/specs/branches/development/doc/AuthenticationBehavior.xml) | [authenticationbehavior.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/authenticationbehavior/wsdl/authenticationbehavior.wsdl) | - | \u2705 Complete |\n| Cloud Integration | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/CloudIntegration.xml) | [cloudintegration.yaml](https://developer.onvif.org/pub/specs/branches/development/doc/yaml.php?yaml=cloudintegration.yaml) | - | \u274c Not yet |\n| Credential | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Credential.xml) | [credential.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/credential/wsdl/credential.wsdl) | - | \u2705 Complete |\n| Device IO | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/DeviceIo.xml) | [deviceio.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/deviceio.wsdl) |- | \u2705 Complete |\n| Display | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Display.xml) | [display.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/display.wsdl) | - | \u2705 Complete |\n| Door Control | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/DoorControl.xml) | [doorcontrol.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/pacs/doorcontrol.wsdl) | - | \u2705 Complete |\n| Imaging | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Imaging.xml) | [imaging.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/imaging/wsdl/imaging.wsdl) | - | \u2705 Complete |\n| Media | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Media.xml) | [media.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/media/wsdl/media.wsdl) | - | \u2705 Complete |\n| Media 2 | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Media2.xml) | [media2.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/media/wsdl/media.wsdl) | - | \u2705 Complete |\n| Provisioning | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Provisioning.xml) | [provisioning.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/provisioning/wsdl/provisioning.wsdl) | - | \u2705 Complete |\n| PTZ | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/PTZ.xml) | [ptz.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/ptz/wsdl/ptz.wsdl) | - | \u2705 Complete |\n| Receiver | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Receiver.xml) | [receiver.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/receiver.wsdl) | - | \u2705 Complete |\n| Recording Control | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/RecordingControl.xml) | [recording.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/recording.wsdl) | - | \u2705 Complete |\n| Recording Search | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/RecordingSearch.xml) | [search.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/search.wsdl) | - | \u2705 Complete |\n| Replay Control | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Replay.xml) | [replay.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/replay.wsdl) | - | \u2705 Complete |\n| Resource Query | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/ResourceQuery.xml) | - | | \u274c Any idea? |\n| Schedule | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Schedule.xml) | [schedule.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/schedule/wsdl/schedule.wsdl) | - | \u2705 Complete |\n| Security | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Security.xml) | [advancedsecurity.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl) | - | \u2705 Complete |\n| Thermal | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Thermal.xml) | [thermal.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/thermal/wsdl/thermal.wsdl) | [radiometry.xsd](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver20/analytics/radiometry.xsd) | \u2705 Complete |\n| Uplink | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/Uplink.xml) | [uplink.wsdl](https://developer.onvif.org/pub/specs/branches/development/wsdl/ver10/uplink/wsdl/uplink.wsdl) | - | \u2705 Complete |\n| WebRTC | [Document](https://developer.onvif.org/pub/specs/branches/development/doc/WebRTC.xml) | - | - | \u274c Any idea? |\n\n</details>\n\n## Service Bindings in ONVIF\n\nONVIF services are defined by WSDL bindings. In this library, there are two main patterns:\n\n### 1. Single Binding Services\n\nMost 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.\n\n<details>\n<summary>Examples:</summary>\n\n```python\nclient.devicemgmt() # DeviceBinding\nclient.media() # MediaBinding\nclient.ptz() # PTZBinding\n...\n```\n\n\u2705 These are considered fixed and always accessed directly.\n\n</details>\n\n### 2. Multi-Binding Services\n\nSome ONVIF services have multiple bindings in the same WSDL. These typically include:\n- A **root binding** (main entry point)\n- One or more **sub-bindings**, discovered or created dynamically (e.g. after subscription/configuration creation)\n\n<details>\n<summary>Examples:</summary>\n\n1. **Events**\n - **Root:** `EventBinding`\n - **Sub-bindings:**\n - `PullPointSubscriptionBinding` (created via `CreatePullPointSubscription`)\n - `SubscriptionManagerBinding` (manages existing subscriptions)\n - `NotificationProducerBinding`\n\n Usage in library:\n ```python\n client.events() # root binding\n client.pullpoint(subscription) # sub-binding (dynamic, via SubscriptionReference.Address)\n client.subscription(subscription) # sub-binding (dynamic, via SubscriptionReference.Address)\n client.notification() # sub-binding accessor\n ```\n\n2. **Security (Advanced Security)**\n - **Root:** `AdvancedSecurityServiceBinding`\n - **Sub-bindings:**\n - `AuthorizationServerBinding`\n - `KeystoreBinding`\n - `JWTBinding`\n - `Dot1XBinding`\n - `TLSServerBinding`\n - `MediaSigningBinding`\n\n Usage in library:\n ```python\n client.security() # root binding\n client.authorizationserver(xaddr) # sub-binding accessor (requires xAddr)\n client.keystore(xaddr) # ..\n client.jwt(xaddr)\n client.dot1x(xaddr)\n client.tlsserver(xaddr)\n client.mediasigning(xaddr)\n ```\n\n3. **Analytics**\n - **Root:** `AnalyticsEngineBinding`\n - **Sub-bindings:**\n - `RuleEngineBinding`\n\n Usage in library:\n ```python\n client.analytics() # root binding\n client.ruleengine() # sub-binding accessor\n ```\n</details>\n\n### Summary\n\n- **Single binding services:** Always accessed directly (e.g. `client.media()`).\n- **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)`).\n\n## Future Improvements (Stay tuned and star \u2b50 this repo)\n\n- [x] ~~Add debugging mode with raw xml on SOAP requests and responses.~~ ([c258162](https://github.com/nirsimetri/onvif-python/commit/c258162))\n- [x] ~~Add functionality for `ONVIFClient` to accept a custom `wsdl_dir` service.~~ ([65f2570](https://github.com/nirsimetri/onvif-python/commit/65f2570))\n- [x] ~~Add `ONVIF CLI` program to interact directly with ONVIF devices via terminal.~~ ([645be01](https://github.com/nirsimetri/onvif-python/commit/645be01))\n- [ ] Add asynchronous (async/await) support for non-blocking ONVIF operations and concurrent device communication.\n- [ ] Implement structured data models for ONVIF Schemas using [xsdata](https://github.com/tefra/xsdata).\n- [ ] Integrate [xmltodict](https://github.com/martinblech/xmltodict) for simplified XML parsing and conversion.\n- [ ] Enhance documentation with API references and diagrams (not from [AI Wiki](https://deepwiki.com/nirsimetri/onvif-python)).\n- [ ] Add more usage examples for advanced features.\n- [ ] Add benchmarking and performance metrics.\n- [ ] Add community-contributed device configuration templates.\n- [ ] Implement missing or partial ONVIF services.\n- [ ] Add function to expose ONVIF devices (for debugging purposes by the community).\n\n## Related Projects\n\n- [onvif-products-directory](https://github.com/nirsimetri/onvif-products-directory):\n\tThis 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.\n\n- (soon) [onvif-rest-server](https://github.com/nirsimetri/onvif-rest-server):\n\tA RESTful API server for ONVIF devices, enabling easy integration of ONVIF device management, media streaming, and other capabilities into web applications and services.\n\n- (soon) [onvif-mcp](https://github.com/nirsimetri/onvif-mcp):\n\tA 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.\n\n## Alternatives\n\nIf you are looking for other ONVIF Python libraries, here are some alternatives:\n\n- [python-onvif-zeep](https://github.com/FalkTannhaeuser/python-onvif-zeep):\n\tA 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.\n\n- [python-onvif-zeep-async](https://github.com/openvideolibs/python-onvif-zeep-async):\n\tAn 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.\n\n## References\n- [ONVIF Official Specifications](https://www.onvif.org/profiles/specifications/specification-history/)\n- [ONVIF Official Specs Repository](https://github.com/onvif/specs)\n- [ONVIF 2.0 Service Operation Index](https://www.onvif.org/onvif/ver20/util/operationIndex.html)\n- [Usage Examples](./examples/)\n\n## Legal Notice\n\nThis project is an **independent open-source implementation** of the [ONVIF](https://www.onvif.org) specifications. It is **not affiliated with, endorsed by, or sponsored by ONVIF** or its member companies.\n\n- The name **\u201cONVIF\u201d** and the ONVIF logo are registered trademarks of the ONVIF organization. \n- Any references to ONVIF within this project are made strictly for the purpose of describing interoperability with ONVIF-compliant devices and services. \n- Use of the ONVIF trademark in this repository is solely nominative and does not imply any partnership, certification, or official status.\n- This project includes WSDL/XSD/HTML files from the official ONVIF specifications.\n- These files are \u00a9 ONVIF and are redistributed here for interoperability purposes.\n- All rights to the ONVIF specifications are reserved by ONVIF.\n\nIf you require certified ONVIF-compliant devices or clients, please refer to the official [ONVIF conformant product list](https://www.onvif.org/conformant-products/). For authoritative reference and the latest official ONVIF specifications, please consult the [ONVIF Official Specifications](https://www.onvif.org/profiles/specifications/specification-history/).\n\n## License\n\nThis project is licensed under the MIT License. See [LICENSE](./LICENSE.md) for details.\n",
"bugtrack_url": null,
"license": null,
"summary": "A modern Python library for ONVIF-compliant devices",
"version": "0.1.8",
"project_urls": {
"Changelog": "https://github.com/nirsimetri/onvif-python/releases",
"Documentation": "https://deepwiki.com/nirsimetri/onvif-python",
"Homepage": "https://github.com/nirsimetri/onvif-python"
},
"split_keywords": [
"onvif",
" camera",
" onvif-python",
" ip-camera",
" cctv",
" soap",
" surveillance",
" cctv cameras",
" soap-client",
" onvif-client",
" onvif-library",
" onvif-specifications"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "54ad9d5c8f0692600477ba66274d8728c841120c6620d49f9a60a26f5120c4f8",
"md5": "48522b445803790abd9b0c0d6335a43d",
"sha256": "c3a49394cc1964105f485256bb4c5bb979c5e71bc4df23b099dcaf66ef2b22c6"
},
"downloads": -1,
"filename": "onvif_python-0.1.8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "48522b445803790abd9b0c0d6335a43d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 419819,
"upload_time": "2025-10-27T00:09:08",
"upload_time_iso_8601": "2025-10-27T00:09:08.307447Z",
"url": "https://files.pythonhosted.org/packages/54/ad/9d5c8f0692600477ba66274d8728c841120c6620d49f9a60a26f5120c4f8/onvif_python-0.1.8-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c75518b4ba37c8c66a2dfcc520f5e75c2965961b8dbb4fa96336559438807e8a",
"md5": "bdcb40d4086fe5c0d6d020df65a05d39",
"sha256": "fddec254430e25c260847417d37d610c7fca95ff22e3dee6175521c3d1c9710a"
},
"downloads": -1,
"filename": "onvif_python-0.1.8.tar.gz",
"has_sig": false,
"md5_digest": "bdcb40d4086fe5c0d6d020df65a05d39",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 395463,
"upload_time": "2025-10-27T00:09:10",
"upload_time_iso_8601": "2025-10-27T00:09:10.036780Z",
"url": "https://files.pythonhosted.org/packages/c7/55/18b4ba37c8c66a2dfcc520f5e75c2965961b8dbb4fa96336559438807e8a/onvif_python-0.1.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-27 00:09:10",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "nirsimetri",
"github_project": "onvif-python",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "onvif-python"
}