From 14461a54ac436b86496c67e03693df2424cd3035 Mon Sep 17 00:00:00 2001 From: kaburagisec <135169292+kaburagisec@users.noreply.github.com> Date: Wed, 21 Oct 2026 03:52:34 +0700 Subject: [PATCH 1/2] code: Update examples --- examples/add_media_profile.py | 15 +++--- examples/add_onvif_user.py | 8 ++-- examples/check_all_capabilities.py | 10 ++-- examples/check_all_services.py | 8 ++-- examples/check_device.py | 8 ++-- examples/check_ptz.py | 8 ++-- examples/device_discovery_raw.py | 9 ++-- examples/direct_zeep.py | 75 ++++++++++++++++++++++++++++++ examples/error_handling.py | 22 ++++++--- examples/get_analytics_list.py | 8 ++-- examples/get_imaging.py | 8 ++-- examples/get_media_profiles.py | 8 ++-- examples/get_onvif_version.py | 2 +- examples/get_snapshot.py | 8 ++-- examples/open_stream.py | 4 +- examples/open_stream_with_ptz.py | 4 +- examples/pull_live_events.py | 6 +-- examples/set_device_time.py | 8 ++-- examples/set_imaging.py | 8 ++-- examples/set_irlamp.py | 8 ++-- 20 files changed, 161 insertions(+), 74 deletions(-) create mode 100644 examples/direct_zeep.py diff --git a/examples/add_media_profile.py b/examples/add_media_profile.py index 9677dcfd..ac148999 100644 --- a/examples/add_media_profile.py +++ b/examples/add_media_profile.py @@ -17,16 +17,17 @@ 7. Verify the profile was created successfully """ -from onvif import ONVIFClient +import sys +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: # Initialize ONVIF client - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) media = client.media() # Get available video sources @@ -34,7 +35,7 @@ video_sources = media.GetVideoSources() if not video_sources: print("No video sources available") - exit(1) + sys.exit() print(f"Found {len(video_sources)} video source(s)") video_source_token = video_sources[0].token @@ -45,7 +46,7 @@ video_source_configs = media.GetVideoSourceConfigurations() if not video_source_configs: print("No video source configurations available") - exit(1) + sys.exit() video_source_config_token = video_source_configs[0].token print(f"Using video source configuration token: {video_source_config_token}") @@ -55,7 +56,7 @@ video_encoder_configs = media.GetVideoEncoderConfigurations() if not video_encoder_configs: print("No video encoder configurations available") - exit(1) + sys.exit() video_encoder_config_token = video_encoder_configs[0].token print(f"Using video encoder configuration token: {video_encoder_config_token}") @@ -112,7 +113,7 @@ ) print(f"Stream URI: {stream_uri.Uri}") -except Exception as e: # pylint: disable=broad-exception-caught +except (ONVIFOperationException, KeyError, AttributeError) as e: print(f"Error: {e}") import traceback diff --git a/examples/add_onvif_user.py b/examples/add_onvif_user.py index 16b17d1d..b4936866 100644 --- a/examples/add_onvif_user.py +++ b/examples/add_onvif_user.py @@ -8,15 +8,15 @@ a new user using the Core (Device Management) service. """ -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) device = client.devicemgmt() device.CreateUsers( User=[{"Username": "newuser", "Password": "newpassword", "UserLevel": "User"}] @@ -24,5 +24,5 @@ # print current users to verify addition print(device.GetUsers()) -except Exception as e: # pylint: disable=broad-exception-caught +except ONVIFOperationException as e: print(e) diff --git a/examples/check_all_capabilities.py b/examples/check_all_capabilities.py index 6ab94a27..17a28024 100644 --- a/examples/check_all_capabilities.py +++ b/examples/check_all_capabilities.py @@ -8,16 +8,18 @@ capabilities using the Core (Device Management) service. """ -from onvif import CacheMode, ONVIFClient +from onvif import CacheMode, ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD, cache=CacheMode.NONE) + client = ONVIFClient( + host=HOST, port=PORT, username=USERNAME, password=PASSWORD, cache=CacheMode.NONE + ) capabilities = client.devicemgmt().GetCapabilities(Category="All") print(capabilities) -except Exception as e: # pylint: disable=broad-exception-caught +except ONVIFOperationException as e: print(e) diff --git a/examples/check_all_services.py b/examples/check_all_services.py index 3e5fb56b..495121a8 100644 --- a/examples/check_all_services.py +++ b/examples/check_all_services.py @@ -8,16 +8,16 @@ of all available services using the Core (Device Management) service. """ -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) services = client.devicemgmt().GetServices(IncludeCapability=True) print(services) -except Exception as e: # pylint: disable=broad-exception-caught +except ONVIFOperationException as e: print(e) diff --git a/examples/check_device.py b/examples/check_device.py index 0d192ea0..2b8b4935 100644 --- a/examples/check_device.py +++ b/examples/check_device.py @@ -11,15 +11,15 @@ import json -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 8000 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) device = client.devicemgmt() # print device information @@ -27,5 +27,5 @@ # print device scopes print(json.dumps(device.to_dict(device.GetScopes()), indent=4)) -except Exception as e: # pylint: disable=broad-exception-caught +except ONVIFOperationException as e: print(e) diff --git a/examples/check_ptz.py b/examples/check_ptz.py index 3d8ca34f..7224dae4 100644 --- a/examples/check_ptz.py +++ b/examples/check_ptz.py @@ -9,15 +9,15 @@ from time import sleep -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) media = client.media() profile = media.GetProfiles()[0] # use first profile ptz = client.ptz() @@ -33,5 +33,5 @@ ) sleep(2.5) ptz.Stop(ProfileToken=profile.token) -except Exception as e: # pylint: disable=broad-exception-caught +except (ONVIFOperationException, KeyError) as e: print(e) diff --git a/examples/device_discovery_raw.py b/examples/device_discovery_raw.py index 5e159605..d6e42337 100644 --- a/examples/device_discovery_raw.py +++ b/examples/device_discovery_raw.py @@ -21,6 +21,7 @@ import struct import sys import uuid +import traceback from lxml import etree @@ -55,14 +56,14 @@ def get_network_interface(): local_ip = s.getsockname()[0] s.close() return local_ip - except Exception: + except OSError: # Try alternative method to get local IP try: hostname = socket.gethostname() local_ip = socket.gethostbyname(hostname) if local_ip and not local_ip.startswith("127."): return local_ip - except Exception: + except OSError: pass # Return empty string instead of "0.0.0.0" @@ -158,7 +159,6 @@ def send_probe_and_get_responses(network_interface=None, timeout=WS_DISCOVERY_TI except Exception as e: print(f"Error during discovery: {e}") - import traceback traceback.print_exc() @@ -346,9 +346,8 @@ def print_device_info(device, is_onvif=True): except KeyboardInterrupt: print("\n\nDiscovery interrupted by user.") sys.exit(0) - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught print(f"\nUnexpected error: {e}") - import traceback traceback.print_exc() sys.exit(1) diff --git a/examples/direct_zeep.py b/examples/direct_zeep.py new file mode 100644 index 00000000..821058c4 --- /dev/null +++ b/examples/direct_zeep.py @@ -0,0 +1,75 @@ +""" +Path: examples/direct_zeep.py +Author: @kaburagisec +Created: October 21, 2026 + +This script demonstrates how to invoke ONVIF operations using +the `zeep` library directly, without relying on the `onvif-python` module. +""" + +from requests import Session +from requests.auth import HTTPDigestAuth +from zeep import Client, Settings +from zeep.plugins import HistoryPlugin +from zeep.transports import Transport + +HOST = "192.168.69.249" +PORT = 80 +USERNAME = "admin" +PASSWORD = "password" + +WSDL = "https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl" +ADDRESS = f"http://{HOST}:{PORT}/devicemgmt" + +session = Session() +session.auth = HTTPDigestAuth(USERNAME, PASSWORD) + +history = HistoryPlugin() + +client = Client( + wsdl=WSDL, + transport=Transport(session=session, timeout=15), + settings=Settings(strict=True, xml_huge_tree=True), + plugins=[history], +) + +service = client.create_service( + "{http://www.onvif.org/ver10/device/wsdl}DeviceBinding", + ADDRESS, +) + +for schema_type in client.wsdl.types.types: + if getattr(schema_type, "name", None) == "SystemCapabilities": + print("Type:", schema_type) + print("Attributes:") + + for attribute in schema_type.attributes: + print(" ", attribute) + +try: + result = service.GetServiceCapabilities() + + print("=== Zeep parsed result ===") + print(result) + + print("\n=== System capabilities ===") + system = result.Capabilities.System + + print("FirmwareUpgrade:", system.FirmwareUpgrade) + print("HttpFirmwareUpgrade:", system.HttpFirmwareUpgrade) + +except Exception as exc: + print(f"{type(exc).__name__}: {exc}") + +finally: + if history.last_received: + print("\n=== Raw SOAP response ===") + print( + client.transport.binding_options + if False + else __import__("lxml.etree", fromlist=["etree"]).tostring( + history.last_received["envelope"], + pretty_print=True, + encoding="unicode", + ) + ) diff --git a/examples/error_handling.py b/examples/error_handling.py index dc2ba409..ffbb10ad 100644 --- a/examples/error_handling.py +++ b/examples/error_handling.py @@ -26,7 +26,7 @@ HOST = "192.168.1.14" PORT = 2020 USERNAME = "admintapo" -PASSWORD = "admin123" +PASSWORD = "password" def example_1_safe_call(): @@ -40,7 +40,9 @@ def example_1_safe_call(): print("Example 1: Using safe_call") print("=" * 60) - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD, cache=CacheMode.NONE) + client = ONVIFClient( + host=HOST, port=PORT, username=USERNAME, password=PASSWORD, cache=CacheMode.NONE + ) device = client.devicemgmt() # Returns None if operation is not supported @@ -68,7 +70,9 @@ def example_2_decorator(): print("Example 2: Using @ignore_unsupported decorator") print("=" * 60) - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD, cache=CacheMode.NONE) + client = ONVIFClient( + host=HOST, port=PORT, username=USERNAME, password=PASSWORD, cache=CacheMode.NONE + ) device = client.devicemgmt() @ignore_unsupported @@ -105,7 +109,9 @@ def example_3_manual_handling(): print("Example 3: Manual exception handling") print("=" * 60) - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD, cache=CacheMode.NONE) + client = ONVIFClient( + host=HOST, port=PORT, username=USERNAME, password=PASSWORD, cache=CacheMode.NONE + ) device = client.devicemgmt() # Try GetSystemUris (not always supported), fallback to alternative @@ -167,7 +173,9 @@ def example_4_batch_operations(): print("Example 4: Batch operations with graceful degradation") print("=" * 60) - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD, cache=CacheMode.NONE) + client = ONVIFClient( + host=HOST, port=PORT, username=USERNAME, password=PASSWORD, cache=CacheMode.NONE + ) device = client.devicemgmt() # Define operations to try @@ -214,7 +222,9 @@ def example_5_critical_operations(): print("Example 5: Critical operations (don't ignore errors)") print("=" * 60) - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD, cache=CacheMode.NONE) + client = ONVIFClient( + host=HOST, port=PORT, username=USERNAME, password=PASSWORD, cache=CacheMode.NONE + ) device = client.devicemgmt() # Critical operation - must succeed diff --git a/examples/get_analytics_list.py b/examples/get_analytics_list.py index a5c41778..af4f336f 100644 --- a/examples/get_analytics_list.py +++ b/examples/get_analytics_list.py @@ -8,15 +8,15 @@ analytics modules using the Analytics service. """ -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) profile = client.media().GetProfiles()[0] # use the first profile analytics = client.analytics() @@ -29,5 +29,5 @@ ConfigurationToken=profile.VideoAnalyticsConfiguration.token ) print("Supported Analytics Modules:\n{}".format(supported_analytics_modules)) -except Exception as e: +except (ONVIFOperationException, KeyError) as e: print(e) diff --git a/examples/get_imaging.py b/examples/get_imaging.py index d2cd8ddb..e4b1f737 100644 --- a/examples/get_imaging.py +++ b/examples/get_imaging.py @@ -8,15 +8,15 @@ imaging settings using the Imaging service from the first media profile. """ -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) profile = client.media().GetProfiles()[0] # use the first profile imaging = client.imaging() @@ -25,5 +25,5 @@ VideoSourceToken=profile.VideoSourceConfiguration.SourceToken ) ) -except Exception as e: # pylint: disable=broad-exception-caught +except (ONVIFOperationException, KeyError) as e: print(e) diff --git a/examples/get_media_profiles.py b/examples/get_media_profiles.py index 986c03dc..faf5f583 100644 --- a/examples/get_media_profiles.py +++ b/examples/get_media_profiles.py @@ -8,18 +8,18 @@ the media profiles using the Media service. """ -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) device = client.media() # print available media profiles print(device.GetProfiles()) -except Exception as e: # pylint: disable=broad-exception-caught +except ONVIFOperationException as e: print(e) diff --git a/examples/get_onvif_version.py b/examples/get_onvif_version.py index 090f424f..143179ab 100644 --- a/examples/get_onvif_version.py +++ b/examples/get_onvif_version.py @@ -13,7 +13,7 @@ HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) diff --git a/examples/get_snapshot.py b/examples/get_snapshot.py index e5e09fb0..d167aa31 100644 --- a/examples/get_snapshot.py +++ b/examples/get_snapshot.py @@ -8,15 +8,15 @@ the snapshot URI using the Media service. """ -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) media = client.media() profile = media.GetProfiles()[0] # use the first profile @@ -24,5 +24,5 @@ snapshot_uri = media.GetSnapshotUri(ProfileToken=profile.token) print("Snapshot URI:", snapshot_uri.Uri) -except Exception as e: # pylint: disable=broad-exception-caught +except (ONVIFOperationException, KeyError) as e: print(e) diff --git a/examples/open_stream.py b/examples/open_stream.py index f1b0b03c..9e6b29eb 100644 --- a/examples/open_stream.py +++ b/examples/open_stream.py @@ -18,9 +18,9 @@ HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" -client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) +client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) media = client.media() profile = media.GetProfiles()[0] # use the first profile diff --git a/examples/open_stream_with_ptz.py b/examples/open_stream_with_ptz.py index d64124d6..f731e697 100644 --- a/examples/open_stream_with_ptz.py +++ b/examples/open_stream_with_ptz.py @@ -19,9 +19,9 @@ HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" -client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) +client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) media = client.media() ptz = client.ptz() diff --git a/examples/pull_live_events.py b/examples/pull_live_events.py index 5fa9b421..4da722d9 100644 --- a/examples/pull_live_events.py +++ b/examples/pull_live_events.py @@ -12,12 +12,12 @@ import datetime -from onvif import ONVIFClient, ONVIFParser +from onvif import ONVIFClient, ONVIFParser, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" # Create parser to extract Topic elements from SOAP responses parser = ONVIFParser( @@ -118,7 +118,7 @@ print("\n-> Event without Message") else: print("\n-> 🔁 No new events.") - except Exception as e: # pylint: disable=broad-exception-caught + except (ONVIFOperationException, AttributeError, ValueError, KeyError) as e: print("\n-> ❌ Error while pulling events:", e) # time.sleep(1) # small delay between requests diff --git a/examples/set_device_time.py b/examples/set_device_time.py index b52bd0c0..98b52094 100644 --- a/examples/set_device_time.py +++ b/examples/set_device_time.py @@ -10,15 +10,15 @@ from datetime import datetime -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.14" PORT = 2020 USERNAME = "admintapo" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) device_service = client.devicemgmt() system_date_time = device_service.GetSystemDateAndTime() @@ -49,5 +49,5 @@ system_date_time_after = device_service.GetSystemDateAndTime() print(f"Updated System Date and Time: {system_date_time_after}\n") -except Exception as e: # pylint: disable=broad-exception-caught +except (ONVIFOperationException, ValueError, AttributeError) as e: print(e) diff --git a/examples/set_imaging.py b/examples/set_imaging.py index 2d459ecd..3901a1d7 100644 --- a/examples/set_imaging.py +++ b/examples/set_imaging.py @@ -8,15 +8,15 @@ with defined parameters. """ -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) media = client.media() profile = media.GetProfiles()[0] # use first profile video_source_token = profile.VideoSourceConfiguration.SourceToken @@ -32,5 +32,5 @@ ) print(imaging.GetImagingSettings(VideoSourceToken=video_source_token)) -except Exception as e: # pylint: disable=broad-exception-caught +except (ONVIFOperationException, KeyError) as e: print(e) diff --git a/examples/set_irlamp.py b/examples/set_irlamp.py index e8746010..f78c21ec 100644 --- a/examples/set_irlamp.py +++ b/examples/set_irlamp.py @@ -8,15 +8,15 @@ to ON, OFF, or AUTO mode using the Imaging service. """ -from onvif import ONVIFClient +from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" PORT = 80 USERNAME = "admin" -PASSWORD = "admin123" +PASSWORD = "password" try: - client = ONVIFClient(HOST, PORT, USERNAME, PASSWORD) + client = ONVIFClient(host=HOST, port=PORT, username=USERNAME, password=PASSWORD) media = client.media() profile = media.GetProfiles()[0] # use first profile video_source_token = profile.VideoSourceConfiguration.SourceToken @@ -30,5 +30,5 @@ ) print(imaging.GetImagingSettings(VideoSourceToken=video_source_token)) -except Exception as e: # pylint: disable=broad-exception-caught +except (ONVIFOperationException, KeyError) as e: print(e) From cf29c13d059a6d9b1a9f7910397f4ca08fd6617d Mon Sep 17 00:00:00 2001 From: kaburagisec <135169292+kaburagisec@users.noreply.github.com> Date: Wed, 21 Oct 2026 03:54:37 +0700 Subject: [PATCH 2/2] style: Run isort --- examples/add_media_profile.py | 1 + examples/device_discovery_raw.py | 2 +- examples/pull_live_events.py | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/add_media_profile.py b/examples/add_media_profile.py index ac148999..49b071d5 100644 --- a/examples/add_media_profile.py +++ b/examples/add_media_profile.py @@ -18,6 +18,7 @@ """ import sys + from onvif import ONVIFClient, ONVIFOperationException HOST = "192.168.1.3" diff --git a/examples/device_discovery_raw.py b/examples/device_discovery_raw.py index d6e42337..1c61d128 100644 --- a/examples/device_discovery_raw.py +++ b/examples/device_discovery_raw.py @@ -20,8 +20,8 @@ import socket import struct import sys -import uuid import traceback +import uuid from lxml import etree diff --git a/examples/pull_live_events.py b/examples/pull_live_events.py index 4da722d9..fefbb628 100644 --- a/examples/pull_live_events.py +++ b/examples/pull_live_events.py @@ -12,7 +12,7 @@ import datetime -from onvif import ONVIFClient, ONVIFParser, ONVIFOperationException +from onvif import ONVIFClient, ONVIFOperationException, ONVIFParser HOST = "192.168.1.3" PORT = 80