Skip to content

Releases: nirsimetri/onvif-python

v0.0.5 — 2025-10-12

11 Oct 20:59
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Overview

This release introduces two major improvements to the ONVIF client library:

  1. Enhanced Zeep xsd:any Parser: Improved parsing of XML elements with attributes, enabling proper data extraction from complex ONVIF responses
  2. Service Discovery Migration: Changed from GetCapabilities to GetServices for more reliable and accurate service endpoint resolution

Changelog Summary

PyPI

https://pypi.org/project/onvif-python/0.0.5 (18434660509)

Changed

  • Service endpoint resolution now uses GetServices instead of GetCapabilities (60e3496) (6211651)
  • Enhanced flatten_xsd_any_fields to preserve nested structures (8d24b9a)

Fixed

  • GetServices(IncludeCapability=True) returning None for capability fields (2284db9)

Full Changelog: v0.0.4...v0.0.5

v0.0.4 — 2025-10-11

11 Oct 05:13
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Added

1. Smart XML Text Value Parser (parse_text_value) (e1995d6)

A new utility function that intelligently converts XML text values to appropriate Python types (boolean, integer, float, or string).

Features:

  • Automatic type detection and conversion
  • Handles boolean values ("true"True, "false"False)
  • Converts numeric strings to int or float
  • Falls back to string for non-numeric values
Example:
from onvif.utils.zeep import parse_text_value

# Boolean conversion
result = parse_text_value("true")  # Returns: True
result = parse_text_value("false")  # Returns: False

# Numeric conversion
result = parse_text_value("42")  # Returns: 42 (int)
result = parse_text_value("3.14")  # Returns: 3.14 (float)

# String fallback
result = parse_text_value("hello")  # Returns: "hello" (str)

2. XSD Any Fields Flattening (flatten_xsd_any_fields) (e1995d6)

A powerful post-processing function that automatically extracts and populates data from zeep's _value_N fields (xsd:any with maxOccurs) into their proper attributes.

Features:

  • Recursively processes all zeep objects
  • Handles multiple _value_N fields (_value_1, _value_2, _value_3, etc.)
  • Preserves original XML Elements in _value_N fields
  • Prevents infinite recursion with visited object tracking
  • Maintains zeep object structure (no dict conversion)

Problem Solved:
Before this feature, ONVIF Extension fields like DeviceIO, AudioSource, etc., would be None even though the data existed in _value_1 as XML elements.

Example:
from onvif import ONVIFClient

# Create client (flatten_xsd_any_fields is automatically applied)
client = ONVIFClient('192.168.1.100', 80, 'admin', 'password')

# Get capabilities
capabilities = client.devicemgmt.GetCapabilities()

# Before v0.0.4: capabilities.Extension.DeviceIO would be None
# After v0.0.4: capabilities.Extension.DeviceIO is now populated!
print(capabilities.Extension.DeviceIO.XAddr)
# Output: http://192.168.1.100:80/onvif/device_io_service

# The original XML Elements are preserved
print(capabilities.Extension._value_1)
# Output: [<Element {http://www.onvif.org/ver10/schema}DeviceIO at 0x...>]

# Works recursively with nested extensions
print(capabilities.Extension.DeviceIO.RelayOutputs)
print(capabilities.Extension.DeviceIO.RelayOutputs[0].Properties.Mode)
Manual Usage:
from onvif.utils.zeep import flatten_xsd_any_fields

# Manually process a zeep object
flattened_result = flatten_xsd_any_fields(some_zeep_object)

3. Optional Zeep Patching (apply_patch Parameter) (e1995d6)

A new optional parameter in ONVIFClient that gives you control over whether to apply the zeep monkey patch and automatic flattening.

Features:

  • Control patching behavior at client initialization
  • Default is True (patched behavior with automatic flattening)
  • Set to False to use original zeep behavior
  • Global patch management functions: apply_patch(), remove_patch(), is_patched()
Example:
from onvif import ONVIFClient

# Default behavior - with patch and automatic flattening
client = ONVIFClient('192.168.1.100', 80, 'admin', 'password')
capabilities = client.devicemgmt.GetCapabilities()
print(capabilities.Extension.DeviceIO)  # Populated automatically
# Output: {'XAddr': 'http://192.168.1.100:80/onvif/device_io_service', ...}

# Without patch - original zeep behavior
client = ONVIFClient(
    '192.168.1.100', 80, 'admin', 'password',
    apply_patch=False
)
capabilities = client.devicemgmt.GetCapabilities()
print(capabilities.Extension.DeviceIO)  # None
print(capabilities.Extension._value_1)  # Data is here as XML Elements
# Output: [<Element {http://www.onvif.org/ver10/schema}DeviceIO at 0x...>]
Global Patch Management:
from onvif import apply_patch, remove_patch, is_patched

# Check if patch is currently applied
if is_patched():
    print("Zeep is patched")

# Manually apply patch
apply_patch()

# Manually remove patch
remove_patch()

# Check again
if not is_patched():
    print("Zeep is unpatched")

Changed

  • Modified ONVIFOperator to support conditional flattening via apply_flatten parameter
  • Enhanced monkey patch to store original XML Elements before parsing
  • Improved handling of xsd:any elements with maxOccurs > 1

Technical Details

Zeep Internal Structure:

  • Zeep objects use __values__ OrderedDict internally (not __dict__)
  • xsd:any elements are stored as _value_1, _value_2, etc.
  • Original XML Elements are preserved in __original_elements__ during patching

Backward Compatibility:

  • All changes are backward compatible
  • Default behavior provides enhanced functionality
  • Original zeep behavior available via apply_patch=False

Migration Guide

No migration required. The default behavior now includes automatic flattening, which improves the usability of ONVIF Extension fields. If you need the original behavior, simply set apply_patch=False when creating the ONVIFClient.

PyPI

https://pypi.org/project/onvif-python/0.0.4 (18424895514)


Full Changelog: v0.0.3...v0.0.4

v0.0.3 — 2025-10-11

10 Oct 18:44
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

PyPI

https://pypi.org/project/onvif-python/0.0.3

Fixed

  • Fix issue Incorrect call "DeleteKey" in CreatePKCS10CSR (#2) (7b9685f) at Keystore service. Reported by @hsunner

Full Changelog: v0.0.2...v0.0.3

v0.0.2 — 2025-09-27

26 Sep 21:43
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

PyPI

https://pypi.org/project/onvif-python/0.0.2

Added

  • Improved xsd:any parsing logic for child elements, allowing automatic dictionary conversion of ONVIF <Extension> blocks (via monkey patch on parse_xmlelements) (fce868e)
    → This implements behavior proposed in python-zeep#1473
    → Since the PR is not yet merged, this version includes a local monkey patch applied at runtime to zeep.xsd.elements.any.Any.parse_xmlelements

Fixed

  • ONVIFClient._get_xaddr() now supports resolving service addresses (XAddr) from nested _value_1 dictionaries (common in normalized extensions) (4292fc4)
  • Added support for overriding XAddr host/port when device is behind NAT or proxy (d5f5b1e)
  • Changed fallback service_path for Search service to improve compatibility with some ONVIF devices (d5f5b1e)

Comparison

These improvements make this version of onvif-python significantly more capable in handling dynamic ONVIF service extensions than other popular forks such as:

...which still rely on the unpatched version of Zeep and require manual parsing of xsd:any elements.


Full Changelog: v0.0.1...v0.0.2

v0.0.1 — 2025-09-25

24 Sep 18:40
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

PyPI

https://pypi.org/project/onvif-python/0.0.1

Initial Release

  • First public release of the ONVIF Python Library!
  • Implements core ONVIF services: Device Management, Media, PTZ, Imaging, Events, Recording, and more.
  • Supports ONVIF Profiles S, G, T, C, A, D, M.
  • Provides a Pythonic API that wraps SOAP/XML communication for easy integration.
  • Includes example scripts and tests for various ONVIF devices.
  • Basic documentation and badges for PyPI, DeepWiki, and total downloads.
  • Compatible with a wide range of ONVIF devices and firmware versions.

Please report bugs, suggestions, or contribute via GitHub Issues!