Releases: nirsimetri/onvif-python
v0.2.5 — 2025-11-03
PyPI
https://pypi.org/project/onvif-python/0.2.5 (19067313640)
Feat
- [
CLI] Add output file option (--output/-o) for command results with format detection (0402c33)
Fix/Refactor
- [
Client] Remove unusedONVIFOperatorimport (b033781) - [
CLI] Improve error handling in JSON serialization by specifying exception types (609fc35) - [
CLI] Prepare output data for JSON format insave_output_to_filefunction (73ccdc9)
Style
- [
Examples] Enforce PEP8 Linting (8878fe1)
Docs
- Update badges links (a899a7c)
- Add library philosophy section with detailed description (6646ad3)
- Update contribution guidelines for branch naming and development setup (792c7a0)
Full Changelog: v0.2.4...v0.2.5
v0.2.4 — 2025-11-02
PyPI
https://pypi.org/project/onvif-python/0.2.4 (19009844081)
Feat
- [
Client] AddPausableSubscriptionservice class implementation (292a484)
Fix/Refactor
- [
Client] Improve error handling for documentation retrieval inONVIFService(5c1bc15) - [
CLI] Add JSON validation function to improve error handling inparse_json_params(28d56ad) - [
CLI] Fix all existing "Exception, Pass" implementations (8ae16ec) - [
CLI] Fix attribute resolve at type command from interactive shell (15427a1)
Maintenance
- Update
wsdlfolders from remote (https://github.com/onvif/specs) (4fafd8b)
Tests
- Add tests for
PausableSubscriptionservice compliance with WSDL (cf50a01) - Remove obsolete WSDL map tests (632d953)
- Remove exception handling in method call to ensure proper error reporting (86d8313)
- Remove exception handling in method call to ensure proper error reporting (/2) (c37f08a)
Docs
- [
Examples] Add example toUnsubscribePullPointSubscription(bb7984f) - [
Examples] Add script to get and set system date and time on ONVIF device (3a91c86) - [
Release] Bump version 0.2.3 → 0.2.4 (3e48beb)
Full Changelog: v0.2.3...v0.2.4
v0.2.3 — 2025-10-31 (Hotfix)
PyPI
https://pypi.org/project/onvif-python/0.2.3 (18960494401)
Fix/Refactor
Full Changelog: v0.2.2...v0.2.3
v0.2.2 — 2025-10-31
PyPI
https://pypi.org/project/onvif-python/0.2.2 (18959263050)
Feat
- [
Client] AddONVIFParserplugin for extracting XML elements from SOAP responses (4d1b634) - [
Client] Add support for user-provided plugins inONVIFClientinitialization (11163e1) - [
Client] Add lazy loading for security service capabilities inONVIFClient(8e307af) - [
Client] Add lazy loading for JWT service inONVIFClient(735a38c) - [
CLI] Enhance service availability checks forSecurityandJWTservices (8f139f3)
Fix/Refactor
- [
Client] Updateservice_pathinAdvancedSecurityto usedevice_service(18fc581) - [
Client] Improve handling of wrapper elements and attribute parsing inZeepPatcher(83600fe)
Docs
- [
Examples] Add media profile creation example with video source and encoder configurations (5f12aa5) - [
Examples] ReplaceXMLCapturePluginwithONVIFParserfor topic extraction inpull_live_events.py(99e7e8d) - [
Release] Bump version 0.2.1 → 0.2.2 (29d1ffb)
Full Changelog: v0.2.1...v0.2.2
Technical Details
1. ONVIFParser: Solving Zeep's Text Element Limitation (4d1b634) (11163e1)
Problem Statement:
Zeep has a known limitation when parsing XML text elements that contain attributes, specifically when extracting Topic information from the PullPoint (Event) service responses. After extensive debugging and attempts to modify the ZeepPatcher class (originally implemented in v0.0.8 to enhance XML parsing for xsd:any fields), no viable solution was found within Zeep's architecture.
Issue Example:
Below is a comparison showing how Zeep fails to parse the Topic text value:
Zeep Parsed Object:
{
'CurrentTime': datetime.datetime(2025, 10, 30, 22, 16, 42, tzinfo=<isodate.tzinfo.Utc>),
'TerminationTime': datetime.datetime(2025, 10, 30, 22, 26, 47, tzinfo=<isodate.tzinfo.Utc>),
'NotificationMessage': [
{
'SubscriptionReference': None,
'Topic': {
'_value_1': None, # ❌ Topic text is missing!
'Dialect': 'http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet',
'_attr_1': {}
},
'ProducerReference': None,
'Message': {
'_value_1': <Element {http://www.onvif.org/ver10/schema}Message at 0x1ea5df2bd00>
}
}
# ... more notifications
]
}Expected Raw XML:
<env:Header>
<wsa:Action>http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/PullMessagesResponse</wsa:Action>
</env:Header>
<env:Body>
<tev:PullMessagesResponse>
<tev:CurrentTime>2025-10-30T22:16:42Z</tev:CurrentTime>
<tev:TerminationTime>2025-10-30T22:26:47Z</tev:TerminationTime>
<wsnt:NotificationMessage>
<wsnt:Topic Dialect="http://www.onvif.org/ver10/tev/topicExpression/ConcreteSet">
tns1:RuleEngine/CellMotionDetector/Motion
</wsnt:Topic>
<wsnt:Message>
<tt:Message UtcTime="2025-10-30T22:16:41Z" PropertyOperation="Initialized">
<tt:Source>
<tt:SimpleItem Name="VideoSourceConfigurationToken" Value="VideoSourceToken"/>
<tt:SimpleItem Name="VideoAnalyticsConfigurationToken" Value="VideoAnalyticsToken"/>
<tt:SimpleItem Name="Rule" Value="MyMotionDetectorRule"/>
</tt:Source>
<tt:Data>
<tt:SimpleItem Name="IsMotion" Value="false"/>
</tt:Data>
</tt:Message>
</wsnt:Message>
</wsnt:NotificationMessage>
<!-- ... more notifications -->
</tev:PullMessagesResponse>
</env:Body>The Issue:
The _value_1 field should contain the topic string "tns1:RuleEngine/CellMotionDetector/Motion", but Zeep fails to extract it when the <wsnt:Topic> element has attributes (in this case, the Dialect attribute).
Solution: ONVIFParser
To work around this limitation, a new utility class ONVIFParser was introduced that directly parses raw XML using XPath expressions before Zeep processes it. This provides reliable access to element text content regardless of attributes.
Implementation Changes:
- New Class:
onvif.utils.ONVIFParser- Generic XML extraction plugin using Zeep'singress()hook - Updated Example:
examples/pull_live_events.pynow usesONVIFParserinstead ofXMLCapturePlugin - Removed in example:
XMLCapturePluginusage in production examples (this plugin is only suitable for development/testing as it stores all request/response XML in memory indefinitely)
Usage Example:
from onvif import ONVIFClient, ONVIFParser
# Create parser with XPath for topic extraction
parser = ONVIFParser(extract_xpaths={
'topic': './/{http://docs.oasis-open.org/wsn/b-2}Topic'
})
# Pass parser to client
client = ONVIFClient(host, port, username, password, plugins=[parser])
# Use parsed data
event_service = client.pullpoint(...)
response = event_service.PullMessages(...)
topics = parser.get_extracted_texts('topic', len(response.NotificationMessage))2. Advanced Security Service Discovery (18fc581) (8e307af) (735a38c)
Problem Statement:
The XAddr endpoint for the Security service (now called "Advanced Security" by the ONVIF consortium) was not discoverable through the standard 3-tier service discovery mechanism (GetServices → GetCapabilities → default URL). Extensive testing across multiple devices showed that neither "Security" nor "AdvancedSecurity" keys appeared in response structures, even within Extension or Extension.Extensions fields.
Investigation:
After thorough review of the ONVIF Advanced Security Service specification, the solution was discovered through experimentation: calling GetServiceCapabilities() on the Security service using the Device service's default endpoint (/onvif/device_service).
Discovery Response:
{
'KeystoreCapabilities': None,
'TLSServerCapabilities': None,
'Dot1XCapabilities': None,
'AuthorizationServer': None,
'MediaSigning': None,
'_value_1': [
<Element {http://www.onvif.org/ver10/device/wsdl}Network at 0x1ddc2c13640>,
<Element {http://www.onvif.org/ver10/device/wsdl}Security at 0x1ddc2c13680>,
<Element {http://www.onvif.org/ver10/device/wsdl}System at 0x1ddc2c136c0>
],
'_attr_1': None,
'Network': {
'IPFilter': False,
'ZeroConfiguration': True,
'IPVersion6': False,
'DHCPv6': False,
'DynDNS': False,
'Dot11Configuration': False,
'Dot1XConfigurations': 0,
'HostnameFromDHCP': True,
'NTP': 1
},
'Security': {
'TLS1.0': True,
'TLS1.1': True,
'TLS1.2': True,
'OnboardKeyGeneration': False,
'AccessPolicyConfig': False,
'DefaultAccessPolicy': True,
'Dot1X': False,
'RemoteUserHandling': False,
'X.509Token': False,
'SAMLToken': False,
'KerberosToken': False,
'UsernameToken': True,
'HttpDigest': True,
'RELToken': False,
'SupportedEAPMethods': 0,
'MaxUsers': 32,
'MaxUserNameLength': 32,
'MaxPasswordLength': 16
},
'System': {
'DiscoveryResolve': False,
'DiscoveryBye': True,
'RemoteDiscovery': True,
'SystemBackup': False,
'SystemLogging': False,
'FirmwareUpgrade': True,
'HttpFirmwareUpgrade': True,
'HttpSystemBackup': False,
'HttpSystemLogging': False,
'HttpSupportInformation': False,
'StorageConfiguration': False,
'MaxStorageConfigurations': 0
}
}Key Findings:
- Endpoint Location: The Advanced Security service is accessible at
/onvif/device_service(which is the endpoint of Device service) - Sub-service Detection: Security sub-services (Keystore, TLS Server, Dot1X, etc.) can be detected by checking if their capability objects are
Noneor contain data - Capability Response: The `GetServiceCapabilities()...
v0.2.1 — 2025-10-30 (Hotfix)
PyPI
https://pypi.org/project/onvif-python/0.2.1 (18908407242)
Feat
- [
CLI] Enhancesearch_productsfunction to includeproduct_categoryin search queries (365081f)
Fix/Refactor
- [
Client] AddNullHandlerto prevent duplicate logging errors in multiple modules (d42a68f)
Docs
- [
Release] Bump version 0.2.0 → 0.2.1 (3ba8b64)
Technical Details
- In version 0.2.0, all logging implemented in the majority of main classes does not implement
logger.addHandler(logging.NullHandler()), thus causing the log to run directly without being configured first by the user. This is a nuisance during application development when using this library, in this versionNullHandler()has been implemented, and some logs that have the potential to appear duplicate have also been removed. - The
--search/-sfeature for searching for products in the ONVIF CLI now filters theproduct_categorykey. This is because device details are sometimes more clearly defined in theproduct_categorykey than in thetypekey, which only contains 'device' or 'client'.
Full Changelog: v0.2.0...v0.2.1
v0.2.0 — 2025-10-29
PyPI
https://pypi.org/project/onvif-python/0.2.0 (18905306205)
Feat
- [
Client] Add comprehensive logging to ONVIF client, operator, and utils class (1458d93) - [
Client] Enhance logging for type creation and nested initialization inONVIFOperator(4af7281) - [
Client] Improve local IP retrieval logging inONVIFDiscoveryclass (83d90f4) - [
Client] Add method handleroperations()to list available methods forONVIFService(a2ae678) - [
Client] Adddesc()method to retrieve documentation and parameters for ONVIF operations (80b70b4) - [
CLI] Add product search functionality with pagination support (07546bd) - Add companies and products database files and update package data inclusion (79499de)
Fix/Refactor
- [
Client] Filter allurllib3warnings to show only once for cleaner output (5747186) - [
CLI] Remove unusedtruncate_outputfunction in utils (b9497bd) - [
CLI] Skip helper methods inget_service_methodsand updated related documentation (2491270) - Organize assets project and add ONVIF DB (61b0031)
- [
CLI] Change--search/-scommand to--filter/-fin discovery mode (f814814) - [
CLI] Rename filter parameter tofilter_termfor clarity in device discovery (1cd7465) - [
Client] Enhance logging by addingservice_nameinONVIFOperator(f68e8a0) - [
CLI] Correct pagination display insearch_productsfunction (9e41613)
Docs
- Update image paths in README files to correct path (8024e80)
- [
Examples] Update docstring to clarify patch applicability for device discovery example (a187e78) - [
Examples] Add comprehensive logging demonstration script for ONVIF operations (b450f41) - [
Release] Bump version 0.1.9 → 0.2.0 (100dea1)
Full Changelog: v0.1.9...v0.2.0
Breaking Changes
-
There are numerous logging additions across various classes and operations in this library (1458d93) (4af7281). Considering that the previous release didn't use any logging functionality at all, this release includes logging for all core classes. An example of how to handle onvif logging is in this script
logger.py. Or a simple example of its use is like this:Example usage:
import logging from onvif import ONVIFClient # This will log from root logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) # This will specifically log from 'onvif' logger onvif_logger = logging.getLogger('onvif') onvif_logger.setLevel(logging.INFO) # Set level of 'onvif' logger (INFO, WARNING, ERROR, or DEBUG) # Initiate client client = ONVIFClient('192.168.1.17', 8000, 'admin', 'password', wsdl_dir=r"F:\Projects\python-onvif-zeep\wsdl") service = client.devicemgmt() print(service.GetDeviceInformation())
Example output log:
2025-10-29 17:53:14,679 - onvif.client - INFO - Initializing ONVIF client for 192.168.1.17:8000 2025-10-29 17:53:14,679 - onvif.utils.wsdl - INFO - Setting custom WSDL directory: F:\Projects\python-onvif-zeep\wsdl 2025-10-29 17:53:14,755 - onvif.operator - INFO - ONVIFOperator initialized {http://www.onvif.org/ver10/device/wsdl}DeviceBinding at http://192.168.1.17:8000/onvif/device_service 2025-10-29 17:53:17,045 - onvif.client - INFO - Found 9 services via GetServices -
Device discovery with specific keyword filtering based on scope/type has now changed from using the command
--search/-sto--filter/-f(f814814) like this:Before this release:
onvif --discover --search "C210" --interactiveAfter this release:
onvif --discover --filter "C210" --interactive -
The
--search/-scommand remains in the ONVIF CLI, but is used to search for products in the database, rather than as a filter parameter for device discovery (07546bd).Example usage:
# Search by model name onvif --search "C210" onvif -s "axis camera" # Search by manufacturer onvif --search "hikvision" onvif -s "dahua" # Search by any keyword onvif --search "ptz" onvif -s "thermal"Example output:
Found 15 product(s) matching: hikvision Showing 1-10 of 15 results ID | Test Date | Model | Firmware | Profiles | Category | Type | Company ----|---------------------|-------------------|----------|----------|----------|---------|--------- 342 | 2024-08-15 17:53:12 | DS-2CD2143G2-IU | V5.7.3 | S,G,T | Camera | device | Hikvision 341 | 2024-08-14 14:22:05 | DS-2DE2A404IW-DE3 | V5.6.15 | S,G,T | Camera | device | Hikvision ... Page 1 of 2 Navigation: Next: --page 2
v0.1.9 — 2025-10-28
PyPI
https://pypi.org/project/onvif-python/0.1.9 (18877721778)
Feat
- [
Client] Enable passing Zeep type objects to ONVIF service methods (addtype()handler inONVIFServiceandcreate_type()inONVIFOperator) (148e1ea) - [
CLI] Add options info for custom WSDL path in interactive shell options (bf48e20)
Fix/Refactor
- [
Client] Correct parameter names inSetAnalyticsEngineControlandSetAnalyticsEngineInputmethods (15932df) - [
Client] Fix WSDL path resolution to support flat structure for custom directories (7c51616)
Docs
- Add missing Analytics Device service documentation and WSDL link (7ea76d2)
- Add ONVIF Specs License files (9f797de)
- Update legal notice regarding WSDL file licenses (bcad6e6)
- [
Release] Bump version 0.1.8 → 0.1.9 (1ee749f)
Tests
- Refactor
base_service_testto allow helper methods in Services (9346f60) - Add method to check for duplicate method implementations in service class (6c09519)
- Add test for completeness of method parameters against WSDL (6404950)
- Correct parameter names in
SetAnalyticsEngineControlandSetAnalyticsEngineInputmethod tests (b95e187)
Full Changelog: v0.1.8...v0.1.9
v0.1.8 — 2025-10-27
PyPI
https://pypi.org/project/onvif-python/0.1.8 (18825748585)
Feat
- [
Client] ImplementONVIFServicebase class for consistent error handling across services (646adcc) - [
Client] Improve error messages inONVIFOperationExceptionwith detailed context (08bc979) - [
Client] Add service decorator for consistent exception handling in service accessors (9dfb1fb)
Fix/Refactor
- [
Client] Correct spelling of 'ForcePersistence' to 'ForcePersistance' in SetSerialPortConfiguration method at DeviceIO class (dc33087) - [
Client] Fix SetDPAddresses method parameter from 'DPAddresses' to 'DPAddress' at Device class (fd92d1f) - [
Client] Update_get_local_ipmethod to return Optional[str] and improve IP retrieval logic (16472ef) - [
CLI] Bypass ONVIFService wrapper to retrieve original method in get_method_documentation (5a36146)
Docs
- Update image width in README files for better display (b0c3d27)
- [
Examples] Update XML parsing to use lxml for improved security and performance (e68c7c1) - [
Examples] Enhance get_network_interface to use hostname as fallback (b18e422) - [
Client] Adding docstrings in some main classes (39e81f4) - [
Release] Bump version 0.1.7 → 0.1.8 (e8ce290)
Tests
- Refactor service tests to use a base class for common functionality (9ba14de)
- Update test for
pullpoint_missing_subscription_refto raiseONVIFOperationException(5e48d64)
Full Changelog: v0.1.7...v0.1.8
v0.1.7 — 2025-10-25
PyPI
https://pypi.org/project/onvif-python/0.1.7 (18798603899)
Feat
- [
CLI] Add device filtering option--search/-sfor device discovery in ONVIF CLI (b84384d) - [
Client] Add search filtering for discovered ONVIF devices (10b6d84)
Fix/Refactor
- [
Client] Fix missing 'Feedback' operation inAccessControlclass (d6b0e97) - [
Client] Fix incorrect call 'SetCnMapsToUser' inTLSServerclass (5fa9295) - [
Client] Enhance XML parsing security inONVIFDiscoveryclass (09b5ce0) - [
CLI] Replace xml.etree.ElementTree with lxml for secure XML parsing (0382c1d) - [
Client] Update XML formatting to use lxml instead of minidom for improved performance and reliability (d2b6d2b)
Docs
- Update version format in README and interactive shell help text (2391ede)
- [
Release] Bump version 0.1.6 → 0.1.7 (b729fc5)
Tests
- Add WSDL compliance validation for all implemented Service Operations (8044280)
Full Changelog: v0.1.6...v0.1.7
v0.1.6 — 2025-10-24
PyPI
https://pypi.org/project/onvif-python/0.1.6 (18778932003)
Feat
- [
Client] AddONVIFDiscoveryclass for network device discovery (66aecb3)
Fix/Refactor
- [
CLI] Improve TLS handling in health check connection (0638858) - [
CLI] Rename parameter 'list' to 'items' in columnize method for clarity (2c30a14) - [
CLI] Simplify_display_gridmethod by removing unusedforce_recalcparameter (6848739) - [
CLI] Replace manual device discovery implementation withONVIFDiscoveryclass (da51177)
Docs
- [
Examples] Add device discovery script usingONVIFDiscoveryclass (68fb64a) - [
Release] Bump version 0.1.5 → 0.1.6 (31de639)
Full Changelog: v0.1.5...v0.1.6