onvif-python 0.1.5__tar.gz → 0.1.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {onvif_python-0.1.5/onvif_python.egg-info → onvif_python-0.1.7}/PKG-INFO +49 -11
- {onvif_python-0.1.5 → onvif_python-0.1.7}/README.md +47 -10
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/__init__.py +8 -1
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/cli/interactive.py +23 -32
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/cli/main.py +35 -171
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/cli/utils.py +34 -11
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/accesscontrol.py +11 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/security/tlsserver.py +1 -1
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/utils/__init__.py +2 -0
- onvif_python-0.1.7/onvif/utils/discovery.py +352 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/utils/xml_capture.py +18 -16
- {onvif_python-0.1.5 → onvif_python-0.1.7/onvif_python.egg-info}/PKG-INFO +49 -11
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif_python.egg-info/SOURCES.txt +1 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/pyproject.toml +2 -1
- {onvif_python-0.1.5 → onvif_python-0.1.7}/LICENSE.md +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/MANIFEST.in +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/cli/__init__.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/cli/__main__.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/client.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/operator.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/__init__.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/accessrules.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/actionengine.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/analytics/analytics.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/analytics/ruleengine.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/analyticsdevice.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/appmgmt.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/authenticationbehavior.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/credential.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/deviceio.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/devicemgmt.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/display.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/doorcontrol.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/events/events.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/events/notification.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/events/pullpoint.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/events/subscription.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/imaging.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/media.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/media2.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/provisioning.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/ptz.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/receiver.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/recording.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/replay.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/schedule.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/search.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/security/advancedsecurity.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/security/authorizationserver.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/security/dot1x.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/security/jwt.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/security/keystore.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/security/mediasigning.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/thermal.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/services/uplink.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/utils/error_handlers.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/utils/exceptions.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/utils/wsdl.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/utils/zeep.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/accesscontrol/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/accessrules/wsdl/accessrules.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/accessrules/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/actionengine.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/advancedsecurity/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/analyticsdevice.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/appmgmt/wsdl/appmgmt.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/appmgmt/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/authenticationbehavior/wsdl/authenticationbehavior.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/authenticationbehavior/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/credential/wsdl/credential.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/credential/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/device/wsdl/devicemgmt.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/deviceio.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/display/display.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/display/wsdl/index.htm +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/display.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/doorcontrol/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/events/wsdl/bw-2-vs-mod.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/events/wsdl/event-vs.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/events/wsdl/event.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/events/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/federatedsearch.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/media/wsdl/media.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/pacs/accesscontrol.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/pacs/doorcontrol.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/pacs/types.xsd +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/provisioning/wsdl/provisioning.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/receiver.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/recording.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/replay.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/schedule/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/schedule/wsdl/schedule.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/schema/common.xsd +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/schema/metadatastream.xsd +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/schema/onvif.xsd +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/search.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/thermal/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/thermal/wsdl/thermal.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/topics/topicns.xml +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/uplink/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver10/uplink/wsdl/uplink.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/analytics/humanbody.xsd +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/analytics/humanface.xsd +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/analytics/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/analytics/radiometry.xsd +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/analytics/rules.xsd +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/analytics/wsdl/analytics.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/analytics/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/imaging/wsdl/imaging.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/media/wsdl/index.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/media/wsdl/media.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/ptz/wsdl/ptz.wsdl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/util/federated_search_documentation.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/util/fedsearch-docu-viewer.xsl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/util/onvif-wsdl-viewer.xsl +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif/wsdl/ver20/util/operationIndex.html +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif_python.egg-info/dependency_links.txt +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif_python.egg-info/entry_points.txt +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif_python.egg-info/requires.txt +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/onvif_python.egg-info/top_level.txt +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/setup.cfg +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/setup.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/tests/test_client.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/tests/test_core.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/tests/test_error_handlers.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/tests/test_exceptions.py +0 -0
- {onvif_python-0.1.5 → onvif_python-0.1.7}/tests/test_wsdl_map.py +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: onvif-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: A comprehensive and developer-friendly Python library for working with ONVIF-compliant devices
|
|
5
5
|
Author-email: Nirsimetri Technologies® <open@nirsimetri.com>
|
|
6
6
|
Maintainer: Kaburagi
|
|
7
7
|
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/nirsimetri/onvif-python
|
|
8
9
|
Project-URL: Documentation, https://deepwiki.com/nirsimetri/onvif-python
|
|
9
10
|
Project-URL: Changelog, https://github.com/nirsimetri/onvif-python/releases
|
|
10
11
|
Keywords: onvif,Camera,onvif-python,ip-camera,cctv,soap,surveillance,cctv cameras,soap-client,onvif-client,onvif-library,onvif-specifications
|
|
@@ -40,7 +41,7 @@ Dynamic: license-file
|
|
|
40
41
|
|
|
41
42
|
[](https://app.codacy.com/gh/nirsimetri/onvif-python/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
|
42
43
|
[](https://deepwiki.com/nirsimetri/onvif-python)
|
|
43
|
-
[](https://pypi.org/project/onvif-python/)
|
|
44
45
|
[](https://clickpy.clickhouse.com/dashboard/onvif-python)
|
|
45
46
|
<br>
|
|
46
47
|
[](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml)
|
|
@@ -92,9 +93,33 @@ pip install .
|
|
|
92
93
|
> [!TIP]
|
|
93
94
|
> 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).
|
|
94
95
|
|
|
95
|
-
Below are simple examples to help you get started with the ONVIF Python library. These demonstrate how to connect to
|
|
96
|
+
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.
|
|
96
97
|
|
|
97
|
-
**1.
|
|
98
|
+
**1. Discover ONVIF Devices (Optional)**
|
|
99
|
+
|
|
100
|
+
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:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from onvif import ONVIFDiscovery
|
|
104
|
+
|
|
105
|
+
# Create discovery instance
|
|
106
|
+
discovery = ONVIFDiscovery(timeout=5)
|
|
107
|
+
|
|
108
|
+
# Discover devices
|
|
109
|
+
devices = discovery.discover()
|
|
110
|
+
|
|
111
|
+
# Or with
|
|
112
|
+
# Discover with search filter by types or scopes (case-insensitive substring match)
|
|
113
|
+
devices = discovery.discover(search="Profile/Streaming")
|
|
114
|
+
|
|
115
|
+
# Display discovered devices
|
|
116
|
+
for device in devices:
|
|
117
|
+
print(f"Found device at {device['host']}:{device['port']}")
|
|
118
|
+
print(f" Scopes: {device.get('scopes', [])}")
|
|
119
|
+
print(f" XAddrs: {device['xaddrs']}")
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**2. Initialize the ONVIFClient**
|
|
98
123
|
|
|
99
124
|
Create an instance of `ONVIFClient` by providing your device's IP address, port, username, and password:
|
|
100
125
|
|
|
@@ -111,7 +136,7 @@ client = ONVIFClient(
|
|
|
111
136
|
)
|
|
112
137
|
```
|
|
113
138
|
|
|
114
|
-
**
|
|
139
|
+
**3. Create Service Instance**
|
|
115
140
|
|
|
116
141
|
`ONVIFClient` provides several main services that can be accessed via the following methods:
|
|
117
142
|
|
|
@@ -130,7 +155,7 @@ device = client.devicemgmt() # Device Management (Core)
|
|
|
130
155
|
media = client.media() # Media
|
|
131
156
|
```
|
|
132
157
|
|
|
133
|
-
**
|
|
158
|
+
**4. Get Device Information**
|
|
134
159
|
|
|
135
160
|
Retrieve basic information about the device, such as manufacturer, model, firmware version, and serial number using `devicemgmt()` service:
|
|
136
161
|
|
|
@@ -140,7 +165,7 @@ print(info)
|
|
|
140
165
|
# Example output: {'Manufacturer': '..', 'Model': '..', 'FirmwareVersion': '..', 'SerialNumber': '..'}
|
|
141
166
|
```
|
|
142
167
|
|
|
143
|
-
**
|
|
168
|
+
**5. Get RTSP URL**
|
|
144
169
|
|
|
145
170
|
Retrieve the RTSP stream URL for live video streaming from the device using `media()` service:
|
|
146
171
|
|
|
@@ -173,6 +198,7 @@ This library includes a powerful command-line interface (CLI) for interacting wi
|
|
|
173
198
|
|
|
174
199
|
### Features
|
|
175
200
|
|
|
201
|
+
- **Device Discovery:** Automatic ONVIF device discovery on local network using WS-Discovery protocol.
|
|
176
202
|
- **Interactive Shell:** A user-friendly shell with tab completion, command history, and colorized output.
|
|
177
203
|
- **Direct Command Execution:** Run ONVIF commands directly from the terminal for scripting and automation.
|
|
178
204
|
- **Automatic Discovery:** Automatically detects available services on the device.
|
|
@@ -211,11 +237,12 @@ This library includes a powerful command-line interface (CLI) for interacting wi
|
|
|
211
237
|
<summary><b>1. Direct CLI</b></summary>
|
|
212
238
|
|
|
213
239
|
```bash
|
|
214
|
-
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--
|
|
215
|
-
[--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
|
|
240
|
+
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--search SEARCH] [--timeout TIMEOUT] [--https]
|
|
241
|
+
[--no-verify] [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
|
|
242
|
+
[--health-check-interval HEALTH_CHECK_INTERVAL] [--version]
|
|
216
243
|
[service] [method] [params ...]
|
|
217
244
|
|
|
218
|
-
ONVIF Terminal Client — v0.1.
|
|
245
|
+
ONVIF Terminal Client — v0.1.7
|
|
219
246
|
https://github.com/nirsimetri/onvif-python
|
|
220
247
|
|
|
221
248
|
positional arguments:
|
|
@@ -232,6 +259,8 @@ options:
|
|
|
232
259
|
--password PASSWORD, -p PASSWORD
|
|
233
260
|
Password for authentication
|
|
234
261
|
--discover, -d Discover ONVIF devices on the network using WS-Discovery
|
|
262
|
+
--search SEARCH, -s SEARCH
|
|
263
|
+
Filter discovered devices by types or scopes (case-insensitive substring match)
|
|
235
264
|
--timeout TIMEOUT Connection timeout in seconds (default: 10)
|
|
236
265
|
--https Use HTTPS instead of HTTP
|
|
237
266
|
--no-verify Disable SSL certificate verification
|
|
@@ -251,6 +280,11 @@ Examples:
|
|
|
251
280
|
onvif media GetProfiles --discover --username admin
|
|
252
281
|
onvif -d -i
|
|
253
282
|
|
|
283
|
+
# Discover with filtering
|
|
284
|
+
onvif --discover --search ptz --interactive
|
|
285
|
+
onvif -d -s "C210" -i
|
|
286
|
+
onvif -d -s "audio_encoder" -u admin -p admin123 -i
|
|
287
|
+
|
|
254
288
|
# Direct command execution
|
|
255
289
|
onvif devicemgmt GetCapabilities Category=All --host 192.168.1.17 --port 8000 --username admin --password admin123
|
|
256
290
|
onvif ptz ContinuousMove ProfileToken=Profile_1 Velocity={"PanTilt": {"x": -0.1, "y": 0}} --host 192.168.1.17 --port 8000 --username admin --password admin123
|
|
@@ -272,7 +306,7 @@ Examples:
|
|
|
272
306
|
<summary><b>2. Interactive Shell</b></summary>
|
|
273
307
|
|
|
274
308
|
```bash
|
|
275
|
-
ONVIF Interactive Shell
|
|
309
|
+
ONVIF Interactive Shell — v0.1.7
|
|
276
310
|
https://github.com/nirsimetri/onvif-python
|
|
277
311
|
|
|
278
312
|
Basic Commands:
|
|
@@ -405,6 +439,10 @@ onvif --discover --username admin --password admin123 --interactive
|
|
|
405
439
|
# Short form
|
|
406
440
|
onvif -d -u admin -p admin123 -i
|
|
407
441
|
|
|
442
|
+
# Discover with search filter
|
|
443
|
+
onvif --discover --search "C210" --interactive
|
|
444
|
+
onvif -d -s ptz -u admin -p admin123 -i
|
|
445
|
+
|
|
408
446
|
# Discover and interactive (will prompt for credentials)
|
|
409
447
|
onvif -d -i
|
|
410
448
|
```
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://app.codacy.com/gh/nirsimetri/onvif-python/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
|
4
4
|
[](https://deepwiki.com/nirsimetri/onvif-python)
|
|
5
|
-
[](https://pypi.org/project/onvif-python/)
|
|
6
6
|
[](https://clickpy.clickhouse.com/dashboard/onvif-python)
|
|
7
7
|
<br>
|
|
8
8
|
[](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml)
|
|
@@ -54,9 +54,33 @@ pip install .
|
|
|
54
54
|
> [!TIP]
|
|
55
55
|
> 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).
|
|
56
56
|
|
|
57
|
-
Below are simple examples to help you get started with the ONVIF Python library. These demonstrate how to connect to
|
|
57
|
+
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.
|
|
58
58
|
|
|
59
|
-
**1.
|
|
59
|
+
**1. Discover ONVIF Devices (Optional)**
|
|
60
|
+
|
|
61
|
+
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:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from onvif import ONVIFDiscovery
|
|
65
|
+
|
|
66
|
+
# Create discovery instance
|
|
67
|
+
discovery = ONVIFDiscovery(timeout=5)
|
|
68
|
+
|
|
69
|
+
# Discover devices
|
|
70
|
+
devices = discovery.discover()
|
|
71
|
+
|
|
72
|
+
# Or with
|
|
73
|
+
# Discover with search filter by types or scopes (case-insensitive substring match)
|
|
74
|
+
devices = discovery.discover(search="Profile/Streaming")
|
|
75
|
+
|
|
76
|
+
# Display discovered devices
|
|
77
|
+
for device in devices:
|
|
78
|
+
print(f"Found device at {device['host']}:{device['port']}")
|
|
79
|
+
print(f" Scopes: {device.get('scopes', [])}")
|
|
80
|
+
print(f" XAddrs: {device['xaddrs']}")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**2. Initialize the ONVIFClient**
|
|
60
84
|
|
|
61
85
|
Create an instance of `ONVIFClient` by providing your device's IP address, port, username, and password:
|
|
62
86
|
|
|
@@ -73,7 +97,7 @@ client = ONVIFClient(
|
|
|
73
97
|
)
|
|
74
98
|
```
|
|
75
99
|
|
|
76
|
-
**
|
|
100
|
+
**3. Create Service Instance**
|
|
77
101
|
|
|
78
102
|
`ONVIFClient` provides several main services that can be accessed via the following methods:
|
|
79
103
|
|
|
@@ -92,7 +116,7 @@ device = client.devicemgmt() # Device Management (Core)
|
|
|
92
116
|
media = client.media() # Media
|
|
93
117
|
```
|
|
94
118
|
|
|
95
|
-
**
|
|
119
|
+
**4. Get Device Information**
|
|
96
120
|
|
|
97
121
|
Retrieve basic information about the device, such as manufacturer, model, firmware version, and serial number using `devicemgmt()` service:
|
|
98
122
|
|
|
@@ -102,7 +126,7 @@ print(info)
|
|
|
102
126
|
# Example output: {'Manufacturer': '..', 'Model': '..', 'FirmwareVersion': '..', 'SerialNumber': '..'}
|
|
103
127
|
```
|
|
104
128
|
|
|
105
|
-
**
|
|
129
|
+
**5. Get RTSP URL**
|
|
106
130
|
|
|
107
131
|
Retrieve the RTSP stream URL for live video streaming from the device using `media()` service:
|
|
108
132
|
|
|
@@ -135,6 +159,7 @@ This library includes a powerful command-line interface (CLI) for interacting wi
|
|
|
135
159
|
|
|
136
160
|
### Features
|
|
137
161
|
|
|
162
|
+
- **Device Discovery:** Automatic ONVIF device discovery on local network using WS-Discovery protocol.
|
|
138
163
|
- **Interactive Shell:** A user-friendly shell with tab completion, command history, and colorized output.
|
|
139
164
|
- **Direct Command Execution:** Run ONVIF commands directly from the terminal for scripting and automation.
|
|
140
165
|
- **Automatic Discovery:** Automatically detects available services on the device.
|
|
@@ -173,11 +198,12 @@ This library includes a powerful command-line interface (CLI) for interacting wi
|
|
|
173
198
|
<summary><b>1. Direct CLI</b></summary>
|
|
174
199
|
|
|
175
200
|
```bash
|
|
176
|
-
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--
|
|
177
|
-
[--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
|
|
201
|
+
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--search SEARCH] [--timeout TIMEOUT] [--https]
|
|
202
|
+
[--no-verify] [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
|
|
203
|
+
[--health-check-interval HEALTH_CHECK_INTERVAL] [--version]
|
|
178
204
|
[service] [method] [params ...]
|
|
179
205
|
|
|
180
|
-
ONVIF Terminal Client — v0.1.
|
|
206
|
+
ONVIF Terminal Client — v0.1.7
|
|
181
207
|
https://github.com/nirsimetri/onvif-python
|
|
182
208
|
|
|
183
209
|
positional arguments:
|
|
@@ -194,6 +220,8 @@ options:
|
|
|
194
220
|
--password PASSWORD, -p PASSWORD
|
|
195
221
|
Password for authentication
|
|
196
222
|
--discover, -d Discover ONVIF devices on the network using WS-Discovery
|
|
223
|
+
--search SEARCH, -s SEARCH
|
|
224
|
+
Filter discovered devices by types or scopes (case-insensitive substring match)
|
|
197
225
|
--timeout TIMEOUT Connection timeout in seconds (default: 10)
|
|
198
226
|
--https Use HTTPS instead of HTTP
|
|
199
227
|
--no-verify Disable SSL certificate verification
|
|
@@ -213,6 +241,11 @@ Examples:
|
|
|
213
241
|
onvif media GetProfiles --discover --username admin
|
|
214
242
|
onvif -d -i
|
|
215
243
|
|
|
244
|
+
# Discover with filtering
|
|
245
|
+
onvif --discover --search ptz --interactive
|
|
246
|
+
onvif -d -s "C210" -i
|
|
247
|
+
onvif -d -s "audio_encoder" -u admin -p admin123 -i
|
|
248
|
+
|
|
216
249
|
# Direct command execution
|
|
217
250
|
onvif devicemgmt GetCapabilities Category=All --host 192.168.1.17 --port 8000 --username admin --password admin123
|
|
218
251
|
onvif ptz ContinuousMove ProfileToken=Profile_1 Velocity={"PanTilt": {"x": -0.1, "y": 0}} --host 192.168.1.17 --port 8000 --username admin --password admin123
|
|
@@ -234,7 +267,7 @@ Examples:
|
|
|
234
267
|
<summary><b>2. Interactive Shell</b></summary>
|
|
235
268
|
|
|
236
269
|
```bash
|
|
237
|
-
ONVIF Interactive Shell
|
|
270
|
+
ONVIF Interactive Shell — v0.1.7
|
|
238
271
|
https://github.com/nirsimetri/onvif-python
|
|
239
272
|
|
|
240
273
|
Basic Commands:
|
|
@@ -367,6 +400,10 @@ onvif --discover --username admin --password admin123 --interactive
|
|
|
367
400
|
# Short form
|
|
368
401
|
onvif -d -u admin -p admin123 -i
|
|
369
402
|
|
|
403
|
+
# Discover with search filter
|
|
404
|
+
onvif --discover --search "C210" --interactive
|
|
405
|
+
onvif -d -s ptz -u admin -p admin123 -i
|
|
406
|
+
|
|
370
407
|
# Discover and interactive (will prompt for credentials)
|
|
371
408
|
onvif -d -i
|
|
372
409
|
```
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
from .client import ONVIFClient
|
|
4
4
|
from .operator import ONVIFOperator, CacheMode
|
|
5
|
-
from .utils import
|
|
5
|
+
from .utils import (
|
|
6
|
+
ONVIFWSDL,
|
|
7
|
+
ONVIFOperationException,
|
|
8
|
+
ONVIFErrorHandler,
|
|
9
|
+
ZeepPatcher,
|
|
10
|
+
ONVIFDiscovery,
|
|
11
|
+
)
|
|
6
12
|
from .cli import main as ONVIFCLI
|
|
7
13
|
|
|
8
14
|
__all__ = [
|
|
@@ -14,4 +20,5 @@ __all__ = [
|
|
|
14
20
|
"ONVIFErrorHandler",
|
|
15
21
|
"ZeepPatcher",
|
|
16
22
|
"ONVIFCLI",
|
|
23
|
+
"ONVIFDiscovery",
|
|
17
24
|
]
|
|
@@ -191,7 +191,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
191
191
|
" / __ \\/ | / / | / / _/ ____/",
|
|
192
192
|
" / / / / |/ /| | / // // /_ ",
|
|
193
193
|
"/ /_/ / /| / | |/ // // __/ ",
|
|
194
|
-
"\\____/_/ |_/ |___/___/_/ v0.1.
|
|
194
|
+
"\\____/_/ |_/ |___/___/_/ v0.1.7",
|
|
195
195
|
" ",
|
|
196
196
|
]
|
|
197
197
|
|
|
@@ -240,25 +240,27 @@ class InteractiveShell(cmd.Cmd):
|
|
|
240
240
|
while not self._stop_health_check.is_set():
|
|
241
241
|
sock = None
|
|
242
242
|
try:
|
|
243
|
-
|
|
244
|
-
(self.args.host, self.args.port), timeout=5.0
|
|
245
|
-
)
|
|
246
|
-
|
|
247
|
-
# If HTTPS, perform a short TLS handshake check
|
|
243
|
+
# For HTTPS, use ssl.create_connection for proper TLS handling
|
|
248
244
|
if getattr(self.args, "https", False):
|
|
249
245
|
context = ssl.create_default_context()
|
|
250
246
|
context.minimum_version = ssl.TLSVersion.TLSv1_2
|
|
251
247
|
context.check_hostname = False
|
|
252
248
|
context.verify_mode = ssl.CERT_NONE
|
|
253
249
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
250
|
+
# Use ssl.create_connection instead of wrapping existing socket
|
|
251
|
+
sock = context.wrap_socket(
|
|
252
|
+
socket.socket(socket.AF_INET, socket.SOCK_STREAM),
|
|
253
|
+
server_hostname=self.args.host,
|
|
254
|
+
)
|
|
255
|
+
sock.settimeout(5.0)
|
|
256
|
+
sock.connect((self.args.host, self.args.port))
|
|
257
|
+
else:
|
|
258
|
+
# For HTTP, simple TCP connection check
|
|
259
|
+
sock = socket.create_connection(
|
|
260
|
+
(self.args.host, self.args.port), timeout=5.0
|
|
261
|
+
)
|
|
260
262
|
|
|
261
|
-
#
|
|
263
|
+
# Connection successful
|
|
262
264
|
pass
|
|
263
265
|
|
|
264
266
|
except (
|
|
@@ -368,7 +370,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
368
370
|
|
|
369
371
|
return parts
|
|
370
372
|
|
|
371
|
-
def _display_grid(self, items
|
|
373
|
+
def _display_grid(self, items):
|
|
372
374
|
"""Display items in grid format matching TAB completion (vertical layout)"""
|
|
373
375
|
if not items:
|
|
374
376
|
return
|
|
@@ -393,7 +395,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
393
395
|
|
|
394
396
|
# Column width calculation: use same algorithm as cmd.Cmd.columnize()
|
|
395
397
|
# Python's columnize uses: maxlen + 2 if maxlen > 0 else 2
|
|
396
|
-
col_width = longest_length +
|
|
398
|
+
col_width = longest_length + 2 if longest_length > 0 else 2
|
|
397
399
|
|
|
398
400
|
# Calculate number of columns that fit
|
|
399
401
|
num_cols = max(1, term_width // col_width)
|
|
@@ -661,28 +663,17 @@ class InteractiveShell(cmd.Cmd):
|
|
|
661
663
|
print("^C")
|
|
662
664
|
line = ""
|
|
663
665
|
|
|
664
|
-
# Handle TAB completion on empty line
|
|
665
|
-
if line == "\t":
|
|
666
|
-
print() # Newline before grid
|
|
667
|
-
if self.current_service:
|
|
668
|
-
self._display_grid(get_service_methods(self.current_service))
|
|
669
|
-
else:
|
|
670
|
-
services = get_device_available_services(self.client)
|
|
671
|
-
commands = self.base_commands
|
|
672
|
-
self._display_grid(services + commands)
|
|
673
|
-
line = "" # Reset line to show prompt again
|
|
674
|
-
|
|
675
666
|
line = self.precmd(line)
|
|
676
667
|
stop = self.onecmd(line)
|
|
677
668
|
stop = self.postcmd(stop, line)
|
|
678
669
|
|
|
679
|
-
def columnize(self,
|
|
670
|
+
def columnize(self, items, displaywidth=80):
|
|
680
671
|
"""Override columnize to use grid format for TAB completion"""
|
|
681
|
-
if not
|
|
672
|
+
if not items:
|
|
682
673
|
return
|
|
683
674
|
|
|
684
675
|
# Use our grid display for TAB completion with coloring enabled
|
|
685
|
-
self._display_grid(
|
|
676
|
+
self._display_grid(items)
|
|
686
677
|
|
|
687
678
|
def print_topics(self, header, cmds, cmdlen, maxcol):
|
|
688
679
|
"""Override print_topics to use grid format for TAB completion"""
|
|
@@ -694,7 +685,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
694
685
|
self.stdout.write("%s\n" % str(header))
|
|
695
686
|
|
|
696
687
|
# Use our grid display for TAB completion with coloring enabled
|
|
697
|
-
self._display_grid(cmds
|
|
688
|
+
self._display_grid(cmds)
|
|
698
689
|
|
|
699
690
|
def do_capabilities(self, line):
|
|
700
691
|
"""Show device capabilities in service format"""
|
|
@@ -933,7 +924,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
933
924
|
return
|
|
934
925
|
|
|
935
926
|
if not operation_name:
|
|
936
|
-
print(
|
|
927
|
+
print("Usage: type <operation_name>")
|
|
937
928
|
return
|
|
938
929
|
|
|
939
930
|
if not hasattr(self.current_service, operation_name):
|
|
@@ -1394,7 +1385,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1394
1385
|
super().do_help(line)
|
|
1395
1386
|
else:
|
|
1396
1387
|
help_text = f"""
|
|
1397
|
-
{colorize('ONVIF Interactive Shell
|
|
1388
|
+
{colorize('ONVIF Interactive Shell — v0.1.7', 'cyan')}\n{colorize('https://github.com/nirsimetri/onvif-python', 'white')}
|
|
1398
1389
|
|
|
1399
1390
|
{colorize('Basic Commands:', 'yellow')}
|
|
1400
1391
|
capabilities, caps - Show device capabilities
|