onvif-python 0.2.11__tar.gz → 0.3.0__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.2.11/onvif_python.egg-info → onvif_python-0.3.0}/PKG-INFO +23 -23
- {onvif_python-0.2.11 → onvif_python-0.3.0}/README.md +21 -21
- onvif_python-0.3.0/onvif/__init__.py +25 -0
- onvif_python-0.3.0/onvif/cli/__init__.py +5 -0
- onvif_python-0.3.0/onvif/cli/__main__.py +7 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/cli/interactive.py +53 -45
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/cli/main.py +28 -16
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/cli/utils.py +32 -139
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/client.py +116 -94
- onvif_python-0.3.0/onvif/meta.py +6 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/operator.py +80 -30
- onvif_python-0.3.0/onvif/services/__init__.py +79 -0
- onvif_python-0.3.0/onvif/services/accesscontrol.py +290 -0
- onvif_python-0.3.0/onvif/services/accessrules.py +126 -0
- onvif_python-0.3.0/onvif/services/actionengine.py +107 -0
- onvif_python-0.3.0/onvif/services/analytics/analytics.py +122 -0
- onvif_python-0.3.0/onvif/services/analytics/ruleengine.py +76 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/services/analyticsdevice.py +57 -23
- onvif_python-0.3.0/onvif/services/appmgmt.py +72 -0
- onvif_python-0.3.0/onvif/services/authenticationbehavior.py +217 -0
- onvif_python-0.3.0/onvif/services/credential.py +319 -0
- onvif_python-0.3.0/onvif/services/deviceio.py +322 -0
- onvif_python-0.3.0/onvif/services/devicemgmt.py +965 -0
- onvif_python-0.3.0/onvif/services/display.py +130 -0
- onvif_python-0.3.0/onvif/services/doorcontrol.py +265 -0
- onvif_python-0.3.0/onvif/services/events/events.py +85 -0
- onvif_python-0.3.0/onvif/services/events/notification.py +72 -0
- onvif_python-0.3.0/onvif/services/events/pausable_subscription.py +72 -0
- onvif_python-0.3.0/onvif/services/events/pullpoint.py +78 -0
- onvif_python-0.3.0/onvif/services/events/subscription.py +52 -0
- onvif_python-0.3.0/onvif/services/imaging.py +141 -0
- onvif_python-0.3.0/onvif/services/media.py +884 -0
- onvif_python-0.3.0/onvif/services/media2.py +664 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/services/provisioning.py +21 -8
- onvif_python-0.3.0/onvif/services/ptz.py +378 -0
- onvif_python-0.3.0/onvif/services/receiver.py +92 -0
- onvif_python-0.3.0/onvif/services/recording.py +287 -0
- onvif_python-0.3.0/onvif/services/replay.py +58 -0
- onvif_python-0.3.0/onvif/services/schedule.py +180 -0
- onvif_python-0.3.0/onvif/services/search.py +401 -0
- onvif_python-0.3.0/onvif/services/security/advancedsecurity.py +33 -0
- onvif_python-0.3.0/onvif/services/security/authorizationserver.py +51 -0
- onvif_python-0.3.0/onvif/services/security/dot1x.py +159 -0
- onvif_python-0.3.0/onvif/services/security/jwt.py +35 -0
- onvif_python-0.3.0/onvif/services/security/keystore.py +610 -0
- onvif_python-0.3.0/onvif/services/security/mediasigning.py +76 -0
- onvif_python-0.3.0/onvif/services/security/tlsserver.py +260 -0
- onvif_python-0.3.0/onvif/services/thermal.py +86 -0
- onvif_python-0.3.0/onvif/services/uplink.py +54 -0
- onvif_python-0.3.0/onvif/utils/__init__.py +21 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/utils/discovery.py +1 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/utils/error_handlers.py +22 -16
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/utils/exceptions.py +1 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/utils/service.py +5 -8
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/utils/wsdl.py +4 -3
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/utils/zeep.py +4 -3
- {onvif_python-0.2.11 → onvif_python-0.3.0/onvif_python.egg-info}/PKG-INFO +23 -23
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif_python.egg-info/SOURCES.txt +1 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif_python.egg-info/requires.txt +1 -1
- {onvif_python-0.2.11 → onvif_python-0.3.0}/pyproject.toml +34 -2
- {onvif_python-0.2.11 → onvif_python-0.3.0}/setup.py +2 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/tests/test_client.py +24 -24
- {onvif_python-0.2.11 → onvif_python-0.3.0}/tests/test_core.py +63 -34
- {onvif_python-0.2.11 → onvif_python-0.3.0}/tests/test_error_handlers.py +22 -22
- {onvif_python-0.2.11 → onvif_python-0.3.0}/tests/test_exceptions.py +21 -21
- onvif_python-0.2.11/onvif/__init__.py +0 -33
- onvif_python-0.2.11/onvif/cli/__init__.py +0 -5
- onvif_python-0.2.11/onvif/cli/__main__.py +0 -7
- onvif_python-0.2.11/onvif/services/__init__.py +0 -79
- onvif_python-0.2.11/onvif/services/accesscontrol.py +0 -121
- onvif_python-0.2.11/onvif/services/accessrules.py +0 -52
- onvif_python-0.2.11/onvif/services/actionengine.py +0 -51
- onvif_python-0.2.11/onvif/services/analytics/analytics.py +0 -65
- onvif_python-0.2.11/onvif/services/analytics/ruleengine.py +0 -49
- onvif_python-0.2.11/onvif/services/appmgmt.py +0 -45
- onvif_python-0.2.11/onvif/services/authenticationbehavior.py +0 -88
- onvif_python-0.2.11/onvif/services/credential.py +0 -164
- onvif_python-0.2.11/onvif/services/deviceio.py +0 -170
- onvif_python-0.2.11/onvif/services/devicemgmt.py +0 -425
- onvif_python-0.2.11/onvif/services/display.py +0 -67
- onvif_python-0.2.11/onvif/services/doorcontrol.py +0 -98
- onvif_python-0.2.11/onvif/services/events/events.py +0 -46
- onvif_python-0.2.11/onvif/services/events/notification.py +0 -38
- onvif_python-0.2.11/onvif/services/events/pausable_subscription.py +0 -31
- onvif_python-0.2.11/onvif/services/events/pullpoint.py +0 -33
- onvif_python-0.2.11/onvif/services/events/subscription.py +0 -25
- onvif_python-0.2.11/onvif/services/imaging.py +0 -69
- onvif_python-0.2.11/onvif/services/media.py +0 -429
- onvif_python-0.2.11/onvif/services/media2.py +0 -340
- onvif_python-0.2.11/onvif/services/ptz.py +0 -192
- onvif_python-0.2.11/onvif/services/receiver.py +0 -51
- onvif_python-0.2.11/onvif/services/recording.py +0 -171
- onvif_python-0.2.11/onvif/services/replay.py +0 -35
- onvif_python-0.2.11/onvif/services/schedule.py +0 -87
- onvif_python-0.2.11/onvif/services/search.py +0 -218
- onvif_python-0.2.11/onvif/services/security/advancedsecurity.py +0 -24
- onvif_python-0.2.11/onvif/services/security/authorizationserver.py +0 -36
- onvif_python-0.2.11/onvif/services/security/dot1x.py +0 -47
- onvif_python-0.2.11/onvif/services/security/jwt.py +0 -26
- onvif_python-0.2.11/onvif/services/security/keystore.py +0 -213
- onvif_python-0.2.11/onvif/services/security/mediasigning.py +0 -35
- onvif_python-0.2.11/onvif/services/security/tlsserver.py +0 -87
- onvif_python-0.2.11/onvif/services/thermal.py +0 -59
- onvif_python-0.2.11/onvif/services/uplink.py +0 -33
- onvif_python-0.2.11/onvif/utils/__init__.py +0 -21
- {onvif_python-0.2.11 → onvif_python-0.3.0}/LICENSE.md +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/MANIFEST.in +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/db/companies.db +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/db/products.db +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/utils/parser.py +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/utils/xml_capture.py +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/LICENSE.md +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/b-2.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/bf-2.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/bw-2.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/include +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/mpqf.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/r-2.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/rw-2.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/soap-envelope +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/t-1.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/ws-addr.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/xml.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/schema/common/xmlmime +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/accesscontrol/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/accessrules/wsdl/accessrules.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/accessrules/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/actionengine.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/advancedsecurity/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/analyticsdevice.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/appmgmt/wsdl/appmgmt.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/appmgmt/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/authenticationbehavior/wsdl/authenticationbehavior.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/authenticationbehavior/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/credential/wsdl/credential.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/credential/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/device/wsdl/devicemgmt.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/deviceio.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/display/display.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/display/wsdl/index.htm +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/display.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/doorcontrol/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/events/wsdl/bw-2-vs-mod.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/events/wsdl/event-vs.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/events/wsdl/event.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/events/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/federatedsearch.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/media/wsdl/media.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/pacs/accesscontrol.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/pacs/doorcontrol.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/pacs/types.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/provisioning/wsdl/provisioning.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/receiver.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/recording.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/replay.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/schedule/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/schedule/wsdl/schedule.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/schema/common.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/schema/metadatastream.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/schema/onvif.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/search.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/thermal/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/thermal/wsdl/thermal.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/topics/topicns.xml +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/uplink/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver10/uplink/wsdl/uplink.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/analytics/humanbody.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/analytics/humanface.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/analytics/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/analytics/radiometry.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/analytics/rules.xsd +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/analytics/wsdl/analytics.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/analytics/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/imaging/wsdl/imaging.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/media/wsdl/index.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/media/wsdl/media.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/ptz/wsdl/ptz.wsdl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/util/federated_search_documentation.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/util/fedsearch-docu-viewer.xsl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/util/onvif-wsdl-viewer.xsl +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif/wsdl/ver20/util/operationIndex.html +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif_python.egg-info/dependency_links.txt +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif_python.egg-info/entry_points.txt +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/onvif_python.egg-info/top_level.txt +0 -0
- {onvif_python-0.2.11 → onvif_python-0.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: onvif-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: A modern Python library for ONVIF-compliant devices
|
|
5
5
|
Author-email: Nirsimetri Technologies® <open@nirsimetri.com>
|
|
6
6
|
Maintainer: Kaburagi
|
|
@@ -38,10 +38,10 @@ Requires-Dist: requests>=2.32.0
|
|
|
38
38
|
Provides-Extra: dev
|
|
39
39
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
40
40
|
Requires-Dist: black; extra == "dev"
|
|
41
|
-
Requires-Dist: flake8; extra == "dev"
|
|
42
41
|
Requires-Dist: mypy; extra == "dev"
|
|
43
42
|
Requires-Dist: isort; extra == "dev"
|
|
44
43
|
Requires-Dist: pylint; extra == "dev"
|
|
44
|
+
Requires-Dist: docformatter; extra == "dev"
|
|
45
45
|
Dynamic: license-file
|
|
46
46
|
|
|
47
47
|
<h1 align="center">ONVIF Python</h1>
|
|
@@ -49,7 +49,7 @@ Dynamic: license-file
|
|
|
49
49
|
<div align="center">
|
|
50
50
|
<a href="https://app.codacy.com/gh/nirsimetri/onvif-python/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img src="https://app.codacy.com/project/badge/Grade/bff08a94e4d447b690cea49c6594826d"/></a>
|
|
51
51
|
<a href="https://deepwiki.com/nirsimetri/onvif-python"><img alt="Ask DeepWiki" src="https://deepwiki.com/badge.svg"></a>
|
|
52
|
-
<a href="https://pypi.org/project/onvif-python/"><img alt="PyPI Version" src="https://img.shields.io/badge/PyPI-0.
|
|
52
|
+
<a href="https://pypi.org/project/onvif-python/"><img alt="PyPI Version" src="https://img.shields.io/badge/PyPI-0.3.0-orange?logo=archive&color=yellow"></a>
|
|
53
53
|
<a href="https://pepy.tech/projects/onvif-python"><img alt="Pepy Total Downloads" src="https://img.shields.io/pepy/dt/onvif-python?label=Downloads&color=red"></a>
|
|
54
54
|
<br>
|
|
55
55
|
<a href="https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml"><img alt="Build" src="https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml/badge.svg?branch=main"></a>
|
|
@@ -363,13 +363,12 @@ This library includes a powerful command-line interface (CLI) for interacting wi
|
|
|
363
363
|
<summary><b>1. Direct CLI</b></summary>
|
|
364
364
|
|
|
365
365
|
```bash
|
|
366
|
-
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover]
|
|
367
|
-
[--
|
|
368
|
-
[--
|
|
369
|
-
[--cache {all,db,mem,none}] [--health-check-interval HEALTH_CHECK_INTERVAL] [--output OUTPUT] [--version]
|
|
366
|
+
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--filter FILTER] [--interface INTERFACE] [--discovery-timeout DISCOVERY_TIMEOUT] [--search SEARCH]
|
|
367
|
+
[--page PAGE] [--per-page PER_PAGE] [--timeout TIMEOUT] [--https] [--no-verify] [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
|
|
368
|
+
[--health-check-interval HEALTH_CHECK_INTERVAL] [--output OUTPUT] [--version]
|
|
370
369
|
[service] [method] [params ...]
|
|
371
370
|
|
|
372
|
-
ONVIF Terminal Client — v0.
|
|
371
|
+
ONVIF Terminal Client — v0.3.0
|
|
373
372
|
https://github.com/nirsimetri/onvif-python
|
|
374
373
|
|
|
375
374
|
positional arguments:
|
|
@@ -390,11 +389,13 @@ options:
|
|
|
390
389
|
Filter discovered devices by types or scopes (case-insensitive substring match)
|
|
391
390
|
--interface INTERFACE, -if INTERFACE
|
|
392
391
|
Specify network interface IP for discovery (default: auto-detect)
|
|
392
|
+
--discovery-timeout DISCOVERY_TIMEOUT, -dt DISCOVERY_TIMEOUT
|
|
393
|
+
Discovery timeout in seconds (default: 4)
|
|
393
394
|
--search SEARCH, -s SEARCH
|
|
394
395
|
Search ONVIF products database by model or company (e.g., 'c210', 'hikvision')
|
|
395
396
|
--page PAGE Page number for search results (default: 1)
|
|
396
397
|
--per-page PER_PAGE Number of results per page (default: 20)
|
|
397
|
-
--timeout TIMEOUT
|
|
398
|
+
--timeout TIMEOUT ONVIF connection timeout in seconds (default: 10)
|
|
398
399
|
--https Use HTTPS instead of HTTP
|
|
399
400
|
--no-verify Disable SSL certificate verification
|
|
400
401
|
--no-patch Disable ZeepPatcher
|
|
@@ -402,13 +403,11 @@ options:
|
|
|
402
403
|
--debug Enable debug mode with XML capture
|
|
403
404
|
--wsdl WSDL Custom WSDL directory path
|
|
404
405
|
--cache {all,db,mem,none}
|
|
405
|
-
Caching mode for ONVIFClient (default: all). 'all': memory+disk, 'db': disk-only, 'mem':
|
|
406
|
-
memory-only, 'none': disabled.
|
|
406
|
+
Caching mode for ONVIFClient (default: all). 'all': memory+disk, 'db': disk-only, 'mem': memory-only, 'none': disabled.
|
|
407
407
|
--health-check-interval HEALTH_CHECK_INTERVAL, -hci HEALTH_CHECK_INTERVAL
|
|
408
408
|
Health check interval in seconds for interactive mode (default: 10)
|
|
409
409
|
--output OUTPUT, -o OUTPUT
|
|
410
|
-
Save command output to file. Supports .json, .xml extensions for format detection, or plain
|
|
411
|
-
text. XML format automatically enables debug mode for SOAP capture.
|
|
410
|
+
Save command output to file. Supports .json, .xml extensions for format detection, or plain text. XML format automatically enables debug mode for SOAP capture.
|
|
412
411
|
--version, -v Show ONVIF CLI version and exit
|
|
413
412
|
|
|
414
413
|
Examples:
|
|
@@ -453,7 +452,7 @@ Examples:
|
|
|
453
452
|
<summary><b>2. Interactive Shell</b></summary>
|
|
454
453
|
|
|
455
454
|
```bash
|
|
456
|
-
ONVIF Interactive Shell — v0.
|
|
455
|
+
ONVIF Interactive Shell — v0.3.0
|
|
457
456
|
https://github.com/nirsimetri/onvif-python
|
|
458
457
|
|
|
459
458
|
Basic Commands:
|
|
@@ -548,7 +547,7 @@ If you omit the username or password, you will be prompted to enter them securel
|
|
|
548
547
|
| `desc <method>` | Show documentation for a method |
|
|
549
548
|
| `store <name>` | Store the last result with a variable name |
|
|
550
549
|
| `show <name>` | Display a stored variable |
|
|
551
|
-
| `exit`
|
|
550
|
+
| `exit` | Exit the shell |
|
|
552
551
|
|
|
553
552
|
> [!IMPORTANT]
|
|
554
553
|
> 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.
|
|
@@ -743,8 +742,9 @@ The `ONVIFClient` class provides various configuration options to customize the
|
|
|
743
742
|
|-----------|------|----------|---------|-------------|
|
|
744
743
|
| `host` | `str` | ✅ Yes | - | IP address or hostname of the ONVIF device (e.g., `"192.168.1.17"`) |
|
|
745
744
|
| `port` | `int` | ✅ Yes | - | Port number for ONVIF service (common ports: `80`, `8000`, `8080`) |
|
|
746
|
-
| `username` | `str` |
|
|
747
|
-
| `password` | `str` |
|
|
745
|
+
| `username` | `str` | ❌ No | - | Username for device authentication |
|
|
746
|
+
| `password` | `str` | ❌ No | - | Password for device authentication |
|
|
747
|
+
| `http_digest` | `str` | ❌ No | `False` | `True` = use HTTP Digest / `False` = use WS-Usernametoken |
|
|
748
748
|
|
|
749
749
|
</details>
|
|
750
750
|
|
|
@@ -755,7 +755,7 @@ The `ONVIFClient` class provides various configuration options to customize the
|
|
|
755
755
|
|-----------|------|----------|---------|-------------|
|
|
756
756
|
| `timeout` | `int` | ❌ No | `10` | Connection timeout in seconds for SOAP requests |
|
|
757
757
|
| `use_https` | `bool` | ❌ No | `False` | Use HTTPS instead of HTTP for secure communication |
|
|
758
|
-
| `verify_ssl` | `bool` | ❌ No | `
|
|
758
|
+
| `verify_ssl` | `bool` | ❌ No | `False` | Verify SSL certificates when using HTTPS (set to `False` for self-signed certificates) |
|
|
759
759
|
|
|
760
760
|
</details>
|
|
761
761
|
|
|
@@ -1145,11 +1145,11 @@ Some ONVIF services have multiple bindings in the same WSDL. These typically inc
|
|
|
1145
1145
|
```python
|
|
1146
1146
|
client.security() # root binding
|
|
1147
1147
|
client.jwt() # sub-binding accessor
|
|
1148
|
-
client.authorizationserver(
|
|
1149
|
-
client.keystore(
|
|
1150
|
-
client.dot1x(
|
|
1151
|
-
client.tlsserver(
|
|
1152
|
-
client.mediasigning(
|
|
1148
|
+
client.authorizationserver() # ..
|
|
1149
|
+
client.keystore()
|
|
1150
|
+
client.dot1x()
|
|
1151
|
+
client.tlsserver()
|
|
1152
|
+
client.mediasigning()
|
|
1153
1153
|
```
|
|
1154
1154
|
|
|
1155
1155
|
3. **Analytics**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
<a href="https://app.codacy.com/gh/nirsimetri/onvif-python/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade"><img src="https://app.codacy.com/project/badge/Grade/bff08a94e4d447b690cea49c6594826d"/></a>
|
|
5
5
|
<a href="https://deepwiki.com/nirsimetri/onvif-python"><img alt="Ask DeepWiki" src="https://deepwiki.com/badge.svg"></a>
|
|
6
|
-
<a href="https://pypi.org/project/onvif-python/"><img alt="PyPI Version" src="https://img.shields.io/badge/PyPI-0.
|
|
6
|
+
<a href="https://pypi.org/project/onvif-python/"><img alt="PyPI Version" src="https://img.shields.io/badge/PyPI-0.3.0-orange?logo=archive&color=yellow"></a>
|
|
7
7
|
<a href="https://pepy.tech/projects/onvif-python"><img alt="Pepy Total Downloads" src="https://img.shields.io/pepy/dt/onvif-python?label=Downloads&color=red"></a>
|
|
8
8
|
<br>
|
|
9
9
|
<a href="https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml"><img alt="Build" src="https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml/badge.svg?branch=main"></a>
|
|
@@ -317,13 +317,12 @@ This library includes a powerful command-line interface (CLI) for interacting wi
|
|
|
317
317
|
<summary><b>1. Direct CLI</b></summary>
|
|
318
318
|
|
|
319
319
|
```bash
|
|
320
|
-
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover]
|
|
321
|
-
[--
|
|
322
|
-
[--
|
|
323
|
-
[--cache {all,db,mem,none}] [--health-check-interval HEALTH_CHECK_INTERVAL] [--output OUTPUT] [--version]
|
|
320
|
+
usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password PASSWORD] [--discover] [--filter FILTER] [--interface INTERFACE] [--discovery-timeout DISCOVERY_TIMEOUT] [--search SEARCH]
|
|
321
|
+
[--page PAGE] [--per-page PER_PAGE] [--timeout TIMEOUT] [--https] [--no-verify] [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}]
|
|
322
|
+
[--health-check-interval HEALTH_CHECK_INTERVAL] [--output OUTPUT] [--version]
|
|
324
323
|
[service] [method] [params ...]
|
|
325
324
|
|
|
326
|
-
ONVIF Terminal Client — v0.
|
|
325
|
+
ONVIF Terminal Client — v0.3.0
|
|
327
326
|
https://github.com/nirsimetri/onvif-python
|
|
328
327
|
|
|
329
328
|
positional arguments:
|
|
@@ -344,11 +343,13 @@ options:
|
|
|
344
343
|
Filter discovered devices by types or scopes (case-insensitive substring match)
|
|
345
344
|
--interface INTERFACE, -if INTERFACE
|
|
346
345
|
Specify network interface IP for discovery (default: auto-detect)
|
|
346
|
+
--discovery-timeout DISCOVERY_TIMEOUT, -dt DISCOVERY_TIMEOUT
|
|
347
|
+
Discovery timeout in seconds (default: 4)
|
|
347
348
|
--search SEARCH, -s SEARCH
|
|
348
349
|
Search ONVIF products database by model or company (e.g., 'c210', 'hikvision')
|
|
349
350
|
--page PAGE Page number for search results (default: 1)
|
|
350
351
|
--per-page PER_PAGE Number of results per page (default: 20)
|
|
351
|
-
--timeout TIMEOUT
|
|
352
|
+
--timeout TIMEOUT ONVIF connection timeout in seconds (default: 10)
|
|
352
353
|
--https Use HTTPS instead of HTTP
|
|
353
354
|
--no-verify Disable SSL certificate verification
|
|
354
355
|
--no-patch Disable ZeepPatcher
|
|
@@ -356,13 +357,11 @@ options:
|
|
|
356
357
|
--debug Enable debug mode with XML capture
|
|
357
358
|
--wsdl WSDL Custom WSDL directory path
|
|
358
359
|
--cache {all,db,mem,none}
|
|
359
|
-
Caching mode for ONVIFClient (default: all). 'all': memory+disk, 'db': disk-only, 'mem':
|
|
360
|
-
memory-only, 'none': disabled.
|
|
360
|
+
Caching mode for ONVIFClient (default: all). 'all': memory+disk, 'db': disk-only, 'mem': memory-only, 'none': disabled.
|
|
361
361
|
--health-check-interval HEALTH_CHECK_INTERVAL, -hci HEALTH_CHECK_INTERVAL
|
|
362
362
|
Health check interval in seconds for interactive mode (default: 10)
|
|
363
363
|
--output OUTPUT, -o OUTPUT
|
|
364
|
-
Save command output to file. Supports .json, .xml extensions for format detection, or plain
|
|
365
|
-
text. XML format automatically enables debug mode for SOAP capture.
|
|
364
|
+
Save command output to file. Supports .json, .xml extensions for format detection, or plain text. XML format automatically enables debug mode for SOAP capture.
|
|
366
365
|
--version, -v Show ONVIF CLI version and exit
|
|
367
366
|
|
|
368
367
|
Examples:
|
|
@@ -407,7 +406,7 @@ Examples:
|
|
|
407
406
|
<summary><b>2. Interactive Shell</b></summary>
|
|
408
407
|
|
|
409
408
|
```bash
|
|
410
|
-
ONVIF Interactive Shell — v0.
|
|
409
|
+
ONVIF Interactive Shell — v0.3.0
|
|
411
410
|
https://github.com/nirsimetri/onvif-python
|
|
412
411
|
|
|
413
412
|
Basic Commands:
|
|
@@ -502,7 +501,7 @@ If you omit the username or password, you will be prompted to enter them securel
|
|
|
502
501
|
| `desc <method>` | Show documentation for a method |
|
|
503
502
|
| `store <name>` | Store the last result with a variable name |
|
|
504
503
|
| `show <name>` | Display a stored variable |
|
|
505
|
-
| `exit`
|
|
504
|
+
| `exit` | Exit the shell |
|
|
506
505
|
|
|
507
506
|
> [!IMPORTANT]
|
|
508
507
|
> 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.
|
|
@@ -697,8 +696,9 @@ The `ONVIFClient` class provides various configuration options to customize the
|
|
|
697
696
|
|-----------|------|----------|---------|-------------|
|
|
698
697
|
| `host` | `str` | ✅ Yes | - | IP address or hostname of the ONVIF device (e.g., `"192.168.1.17"`) |
|
|
699
698
|
| `port` | `int` | ✅ Yes | - | Port number for ONVIF service (common ports: `80`, `8000`, `8080`) |
|
|
700
|
-
| `username` | `str` |
|
|
701
|
-
| `password` | `str` |
|
|
699
|
+
| `username` | `str` | ❌ No | - | Username for device authentication |
|
|
700
|
+
| `password` | `str` | ❌ No | - | Password for device authentication |
|
|
701
|
+
| `http_digest` | `str` | ❌ No | `False` | `True` = use HTTP Digest / `False` = use WS-Usernametoken |
|
|
702
702
|
|
|
703
703
|
</details>
|
|
704
704
|
|
|
@@ -709,7 +709,7 @@ The `ONVIFClient` class provides various configuration options to customize the
|
|
|
709
709
|
|-----------|------|----------|---------|-------------|
|
|
710
710
|
| `timeout` | `int` | ❌ No | `10` | Connection timeout in seconds for SOAP requests |
|
|
711
711
|
| `use_https` | `bool` | ❌ No | `False` | Use HTTPS instead of HTTP for secure communication |
|
|
712
|
-
| `verify_ssl` | `bool` | ❌ No | `
|
|
712
|
+
| `verify_ssl` | `bool` | ❌ No | `False` | Verify SSL certificates when using HTTPS (set to `False` for self-signed certificates) |
|
|
713
713
|
|
|
714
714
|
</details>
|
|
715
715
|
|
|
@@ -1099,11 +1099,11 @@ Some ONVIF services have multiple bindings in the same WSDL. These typically inc
|
|
|
1099
1099
|
```python
|
|
1100
1100
|
client.security() # root binding
|
|
1101
1101
|
client.jwt() # sub-binding accessor
|
|
1102
|
-
client.authorizationserver(
|
|
1103
|
-
client.keystore(
|
|
1104
|
-
client.dot1x(
|
|
1105
|
-
client.tlsserver(
|
|
1106
|
-
client.mediasigning(
|
|
1102
|
+
client.authorizationserver() # ..
|
|
1103
|
+
client.keystore()
|
|
1104
|
+
client.dot1x()
|
|
1105
|
+
client.tlsserver()
|
|
1106
|
+
client.mediasigning()
|
|
1107
1107
|
```
|
|
1108
1108
|
|
|
1109
1109
|
3. **Analytics**
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""ONVIF Python"""
|
|
2
|
+
|
|
3
|
+
from onvif.cli import main as ONVIFCLI
|
|
4
|
+
from onvif.client import ONVIFClient
|
|
5
|
+
from onvif.operator import CacheMode
|
|
6
|
+
from onvif.utils import (
|
|
7
|
+
ONVIFWSDL,
|
|
8
|
+
ONVIFDiscovery,
|
|
9
|
+
ONVIFErrorHandler,
|
|
10
|
+
ONVIFOperationException,
|
|
11
|
+
ONVIFParser,
|
|
12
|
+
ZeepPatcher,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"ONVIFClient",
|
|
17
|
+
"CacheMode",
|
|
18
|
+
"ONVIFWSDL",
|
|
19
|
+
"ONVIFOperationException",
|
|
20
|
+
"ONVIFErrorHandler",
|
|
21
|
+
"ZeepPatcher",
|
|
22
|
+
"ONVIFCLI",
|
|
23
|
+
"ONVIFDiscovery",
|
|
24
|
+
"ONVIFParser",
|
|
25
|
+
]
|
|
@@ -17,10 +17,7 @@ from typing import Any
|
|
|
17
17
|
from requests.exceptions import RequestException
|
|
18
18
|
from zeep.exceptions import Fault, TransportError
|
|
19
19
|
|
|
20
|
-
from
|
|
21
|
-
from ..client import ONVIFClient
|
|
22
|
-
from ..utils.exceptions import ONVIFOperationException
|
|
23
|
-
from .utils import (
|
|
20
|
+
from onvif.cli.utils import (
|
|
24
21
|
colorize,
|
|
25
22
|
format_capabilities_as_services,
|
|
26
23
|
format_services_list,
|
|
@@ -31,10 +28,13 @@ from .utils import (
|
|
|
31
28
|
get_service_required_args,
|
|
32
29
|
parse_json_params,
|
|
33
30
|
)
|
|
31
|
+
from onvif.client import ONVIFClient
|
|
32
|
+
from onvif.meta import __repository__, __version__
|
|
33
|
+
from onvif.utils.exceptions import ONVIFOperationException
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class InteractiveShell(cmd.Cmd):
|
|
37
|
-
"""Interactive ONVIF CLI shell"""
|
|
37
|
+
"""Interactive ONVIF CLI shell."""
|
|
38
38
|
|
|
39
39
|
def __init__(self, client: ONVIFClient, args):
|
|
40
40
|
super().__init__()
|
|
@@ -432,7 +432,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
432
432
|
print(line)
|
|
433
433
|
|
|
434
434
|
def _resolve_stored_reference(self, reference: str):
|
|
435
|
-
"""Resolve stored data reference like 'profiles[0].token' or 'profiles.Token'
|
|
435
|
+
"""Resolve stored data reference like 'profiles[0].token' or 'profiles.Token'.
|
|
436
436
|
|
|
437
437
|
Args:
|
|
438
438
|
reference: String reference like 'profiles[0]' or 'profiles.Token'
|
|
@@ -440,7 +440,6 @@ class InteractiveShell(cmd.Cmd):
|
|
|
440
440
|
Returns:
|
|
441
441
|
Resolved value or None if not found
|
|
442
442
|
"""
|
|
443
|
-
|
|
444
443
|
# Parse the reference - e.g., "profiles[0].token" or "services.Namespace"
|
|
445
444
|
# Split by dots and brackets
|
|
446
445
|
parts = re.split(r"\.|\[|\]", reference)
|
|
@@ -484,7 +483,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
484
483
|
return current
|
|
485
484
|
|
|
486
485
|
def _substitute_stored_references(self, params_str: str) -> str:
|
|
487
|
-
"""Substitute $variable references in parameter string with stored data
|
|
486
|
+
"""Substitute $variable references in parameter string with stored data.
|
|
488
487
|
|
|
489
488
|
Args:
|
|
490
489
|
params_str: Parameter string that may contain $variable references
|
|
@@ -492,7 +491,6 @@ class InteractiveShell(cmd.Cmd):
|
|
|
492
491
|
Returns:
|
|
493
492
|
Parameter string with substituted values
|
|
494
493
|
"""
|
|
495
|
-
|
|
496
494
|
# Find all $variable references (e.g., $profiles[0].token)
|
|
497
495
|
pattern = (
|
|
498
496
|
r"\$([a-zA-Z_][a-zA-Z0-9_]*(?:\[[0-9]+\])?(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)"
|
|
@@ -518,14 +516,15 @@ class InteractiveShell(cmd.Cmd):
|
|
|
518
516
|
return re.sub(pattern, replace_reference, params_str)
|
|
519
517
|
|
|
520
518
|
def update_prompt(self):
|
|
521
|
-
"""Update command prompt based on current context"""
|
|
519
|
+
"""Update command prompt based on current context."""
|
|
522
520
|
if self.current_service_name:
|
|
523
521
|
self.prompt = f"{self.args.username}@{self.args.host}:{self.args.port}/{self.current_service_name} > "
|
|
524
522
|
else:
|
|
525
523
|
self.prompt = f"{self.args.username}@{self.args.host}:{self.args.port} > "
|
|
526
524
|
|
|
527
525
|
def onecmd(self, line):
|
|
528
|
-
"""Override onecmd to handle service method calls without showing cmd.Cmd
|
|
526
|
+
"""Override onecmd to handle service method calls without showing cmd.Cmd
|
|
527
|
+
traceback."""
|
|
529
528
|
line = line.strip()
|
|
530
529
|
if not line:
|
|
531
530
|
return self.emptyline()
|
|
@@ -560,7 +559,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
560
559
|
return super().onecmd(line)
|
|
561
560
|
|
|
562
561
|
def default(self, line):
|
|
563
|
-
"""Handle unknown commands"""
|
|
562
|
+
"""Handle unknown commands."""
|
|
564
563
|
available_services = get_device_available_services(self.client)
|
|
565
564
|
|
|
566
565
|
# Check if it's a service call (with or without arguments)
|
|
@@ -594,7 +593,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
594
593
|
print(f"Type {colorize('help', 'white')} for available commands")
|
|
595
594
|
|
|
596
595
|
def get_suggestions(self, partial_cmd: str) -> list[str]:
|
|
597
|
-
"""Get command suggestions based on partial input"""
|
|
596
|
+
"""Get command suggestions based on partial input."""
|
|
598
597
|
suggestions = []
|
|
599
598
|
|
|
600
599
|
if self.current_service:
|
|
@@ -623,7 +622,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
623
622
|
return suggestions[:5] # Limit to 5 suggestions
|
|
624
623
|
|
|
625
624
|
def completenames(self, text: str, *ignored) -> list[str]:
|
|
626
|
-
"""Tab completion for command names"""
|
|
625
|
+
"""Tab completion for command names."""
|
|
627
626
|
if self.current_service:
|
|
628
627
|
# Complete method names in service mode
|
|
629
628
|
methods = get_service_methods(self.current_service)
|
|
@@ -646,7 +645,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
646
645
|
return completions
|
|
647
646
|
|
|
648
647
|
def cmdloop(self, intro=None):
|
|
649
|
-
"""Override cmdloop to handle TAB completion manually"""
|
|
648
|
+
"""Override cmdloop to handle TAB completion manually."""
|
|
650
649
|
if intro is not None:
|
|
651
650
|
self.intro = intro
|
|
652
651
|
if self.intro:
|
|
@@ -670,7 +669,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
670
669
|
stop = self.postcmd(stop, line)
|
|
671
670
|
|
|
672
671
|
def columnize(self, list, displaywidth=80):
|
|
673
|
-
"""Override columnize to use grid format for TAB completion"""
|
|
672
|
+
"""Override columnize to use grid format for TAB completion."""
|
|
674
673
|
if not list:
|
|
675
674
|
return
|
|
676
675
|
|
|
@@ -678,7 +677,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
678
677
|
self._display_grid(list)
|
|
679
678
|
|
|
680
679
|
def print_topics(self, header, cmds, cmdlen, maxcol):
|
|
681
|
-
"""Override print_topics to use grid format for TAB completion"""
|
|
680
|
+
"""Override print_topics to use grid format for TAB completion."""
|
|
682
681
|
if not cmds:
|
|
683
682
|
return
|
|
684
683
|
|
|
@@ -690,7 +689,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
690
689
|
self._display_grid(cmds)
|
|
691
690
|
|
|
692
691
|
def do_capabilities(self, line): # pylint: disable=unused-argument
|
|
693
|
-
"""Show device capabilities in service format"""
|
|
692
|
+
"""Show device capabilities in service format."""
|
|
694
693
|
try:
|
|
695
694
|
if hasattr(self.client, "capabilities") and self.client.capabilities:
|
|
696
695
|
result = self.client.capabilities
|
|
@@ -713,7 +712,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
713
712
|
print(f"{colorize('Error:', 'red')} {e}")
|
|
714
713
|
|
|
715
714
|
def do_services(self, line): # pylint: disable=unused-argument
|
|
716
|
-
"""Show available services in service format"""
|
|
715
|
+
"""Show available services in service format."""
|
|
717
716
|
try:
|
|
718
717
|
if hasattr(self.client, "services") and self.client.services:
|
|
719
718
|
result = self.client.services
|
|
@@ -736,7 +735,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
736
735
|
print(f"{colorize('Error:', 'red')} {e}")
|
|
737
736
|
|
|
738
737
|
def do_enter_service(self, line):
|
|
739
|
-
"""Enter service mode with optional arguments for services that require them"""
|
|
738
|
+
"""Enter service mode with optional arguments for services that require them."""
|
|
740
739
|
# Parse service name and arguments
|
|
741
740
|
parts = line.split(None, 1)
|
|
742
741
|
service_name = parts[0] if parts else ""
|
|
@@ -835,7 +834,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
835
834
|
traceback.print_exc()
|
|
836
835
|
|
|
837
836
|
def do_ls(self, line): # pylint: disable=unused-argument
|
|
838
|
-
"""List available commands/services like TAB completion"""
|
|
837
|
+
"""List available commands/services like TAB completion."""
|
|
839
838
|
if self.current_service:
|
|
840
839
|
# In service mode - show available methods
|
|
841
840
|
methods = get_service_methods(self.current_service)
|
|
@@ -859,7 +858,10 @@ class InteractiveShell(cmd.Cmd):
|
|
|
859
858
|
print("No commands available")
|
|
860
859
|
|
|
861
860
|
def do_desc(self, line):
|
|
862
|
-
"""Describes a method from its WSDL documentation.
|
|
861
|
+
"""Describes a method from its WSDL documentation.
|
|
862
|
+
|
|
863
|
+
Usage: desc <method_name>
|
|
864
|
+
"""
|
|
863
865
|
method_name = line.strip()
|
|
864
866
|
|
|
865
867
|
if not self.current_service:
|
|
@@ -911,14 +913,17 @@ class InteractiveShell(cmd.Cmd):
|
|
|
911
913
|
def complete_desc(
|
|
912
914
|
self, text, line, begidx, endidx
|
|
913
915
|
): # pylint: disable=unused-argument
|
|
914
|
-
"""Autocomplete method names for desc command"""
|
|
916
|
+
"""Autocomplete method names for desc command."""
|
|
915
917
|
if not self.current_service:
|
|
916
918
|
return []
|
|
917
919
|
methods = get_service_methods(self.current_service)
|
|
918
920
|
return [m for m in methods if m.lower().startswith(text.lower())]
|
|
919
921
|
|
|
920
922
|
def do_type(self, line):
|
|
921
|
-
"""Show input and output types for a method.
|
|
923
|
+
"""Show input and output types for a method.
|
|
924
|
+
|
|
925
|
+
Usage: type <method_name>
|
|
926
|
+
"""
|
|
922
927
|
method_name = line.strip()
|
|
923
928
|
|
|
924
929
|
if not self.current_service:
|
|
@@ -944,8 +949,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
944
949
|
if type_info:
|
|
945
950
|
# Helper function to display parameters recursively with tree-style indentation
|
|
946
951
|
def display_params(params, prefix_lines=None, is_root_level=False):
|
|
947
|
-
"""
|
|
948
|
-
Display parameters with tree-style formatting.
|
|
952
|
+
"""Display parameters with tree-style formatting.
|
|
949
953
|
|
|
950
954
|
Args:
|
|
951
955
|
params: List of parameter dictionaries
|
|
@@ -1003,7 +1007,10 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1003
1007
|
# Display parameter name with tree structure, prefix, occurrence, and type
|
|
1004
1008
|
# Only add semicolon separator if there's an occurrence label
|
|
1005
1009
|
separator = ";" if occurs else ""
|
|
1006
|
-
param_line =
|
|
1010
|
+
param_line = (
|
|
1011
|
+
f"{current_prefix}{tree_branch}{prefix_symbol}{colorize(param['name'], 'white')}"
|
|
1012
|
+
f"{occurs}{separator} {colorize(type_str, 'cyan')}"
|
|
1013
|
+
)
|
|
1007
1014
|
print(param_line)
|
|
1008
1015
|
|
|
1009
1016
|
# Display documentation if available
|
|
@@ -1076,7 +1083,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1076
1083
|
def complete_type(
|
|
1077
1084
|
self, text, line, begidx, endidx
|
|
1078
1085
|
): # pylint: disable=unused-argument
|
|
1079
|
-
"""Autocomplete method names for type command"""
|
|
1086
|
+
"""Autocomplete method names for type command."""
|
|
1080
1087
|
if not self.current_service:
|
|
1081
1088
|
return []
|
|
1082
1089
|
methods = get_service_methods(self.current_service)
|
|
@@ -1095,12 +1102,12 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1095
1102
|
def complete_cd(
|
|
1096
1103
|
self, text, line, begidx, endidx
|
|
1097
1104
|
): # pylint: disable=unused-argument
|
|
1098
|
-
"""Autocomplete service names for cd command"""
|
|
1105
|
+
"""Autocomplete service names for cd command."""
|
|
1099
1106
|
services = get_device_available_services(self.client)
|
|
1100
1107
|
return [s for s in services if s.lower().startswith(text.lower())]
|
|
1101
1108
|
|
|
1102
1109
|
def do_pwd(self, line): # pylint: disable=unused-argument
|
|
1103
|
-
"""Show current service context"""
|
|
1110
|
+
"""Show current service context."""
|
|
1104
1111
|
if self.current_service_name:
|
|
1105
1112
|
print(
|
|
1106
1113
|
f"{colorize('Current service:', 'yellow')} {colorize(self.current_service_name, 'cyan')}"
|
|
@@ -1111,7 +1118,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1111
1118
|
)
|
|
1112
1119
|
|
|
1113
1120
|
def do_shortcuts(self, line): # pylint: disable=unused-argument
|
|
1114
|
-
"""Show available shortcuts"""
|
|
1121
|
+
"""Show available shortcuts."""
|
|
1115
1122
|
shortcuts = f"""
|
|
1116
1123
|
{colorize('Available Shortcuts:', 'cyan')}
|
|
1117
1124
|
|
|
@@ -1160,14 +1167,14 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1160
1167
|
|
|
1161
1168
|
def do_store(self, line):
|
|
1162
1169
|
"""Store last result with a name: store <name>"""
|
|
1163
|
-
|
|
1164
1170
|
if not line:
|
|
1165
1171
|
print("Usage: store <name>")
|
|
1166
1172
|
return
|
|
1167
1173
|
# Only allow valid Python variable names
|
|
1168
1174
|
if not re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", line):
|
|
1169
1175
|
print(
|
|
1170
|
-
f"{colorize('Error:', 'red')} Invalid name '{line}'.
|
|
1176
|
+
f"{colorize('Error:', 'red')} Invalid name '{line}'. "
|
|
1177
|
+
"Only letters, numbers, and underscores allowed, and must not start with a number."
|
|
1171
1178
|
)
|
|
1172
1179
|
return
|
|
1173
1180
|
# Must be unique
|
|
@@ -1209,11 +1216,12 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1209
1216
|
def complete_rm(
|
|
1210
1217
|
self, text, line, begidx, endidx
|
|
1211
1218
|
): # pylint: disable=unused-argument
|
|
1212
|
-
"""Autocomplete stored variable names for rm command"""
|
|
1219
|
+
"""Autocomplete stored variable names for rm command."""
|
|
1213
1220
|
return [name for name in self.stored_data if name.startswith(text)]
|
|
1214
1221
|
|
|
1215
1222
|
def do_show(self, line):
|
|
1216
|
-
"""Show stored data: show <name> or show <name>.<attribute> or show
|
|
1223
|
+
"""Show stored data: show <name> or show <name>.<attribute> or show
|
|
1224
|
+
<name>[index]"""
|
|
1217
1225
|
if not line:
|
|
1218
1226
|
print(colorize("Stored data:", "green"))
|
|
1219
1227
|
for name in self.stored_data:
|
|
@@ -1235,7 +1243,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1235
1243
|
print(f"{colorize('Error:', 'red')} Cannot resolve '{line}'")
|
|
1236
1244
|
|
|
1237
1245
|
def complete_show(self, text, line, begidx, endidx):
|
|
1238
|
-
"""Autocomplete stored variable names for show command"""
|
|
1246
|
+
"""Autocomplete stored variable names for show command."""
|
|
1239
1247
|
# Get the part being completed
|
|
1240
1248
|
parts = line.split()
|
|
1241
1249
|
if len(parts) <= 1 or (len(parts) == 2 and not line.endswith(" ")):
|
|
@@ -1244,18 +1252,18 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1244
1252
|
return []
|
|
1245
1253
|
|
|
1246
1254
|
def do_clear(self, line): # pylint: disable=unused-argument
|
|
1247
|
-
"""Clear terminal screen"""
|
|
1255
|
+
"""Clear terminal screen."""
|
|
1248
1256
|
# Clear screen for both Windows and Unix-like systems
|
|
1249
1257
|
os.system("cls" if os.name == "nt" else "clear")
|
|
1250
1258
|
|
|
1251
1259
|
def do_cls(self, line): # pylint: disable=unused-argument
|
|
1252
|
-
"""Clear stored data"""
|
|
1260
|
+
"""Clear stored data."""
|
|
1253
1261
|
self.stored_data.clear()
|
|
1254
1262
|
self.stored_metadata.clear()
|
|
1255
1263
|
print(f"{colorize('Cleared all stored data', 'yellow')}")
|
|
1256
1264
|
|
|
1257
1265
|
def do_info(self, line): # pylint: disable=unused-argument
|
|
1258
|
-
"""Show connection and device information"""
|
|
1266
|
+
"""Show connection and device information."""
|
|
1259
1267
|
# Build connection and CLI options info
|
|
1260
1268
|
options_info = []
|
|
1261
1269
|
|
|
@@ -1305,7 +1313,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1305
1313
|
print() # Extra newline for spacing
|
|
1306
1314
|
|
|
1307
1315
|
def execute_service_method(self, method_name, params_str):
|
|
1308
|
-
"""Execute a method on the current service"""
|
|
1316
|
+
"""Execute a method on the current service."""
|
|
1309
1317
|
if not self.current_service:
|
|
1310
1318
|
print(f"{colorize('Error:', 'red')} Not in service mode")
|
|
1311
1319
|
return
|
|
@@ -1359,7 +1367,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1359
1367
|
traceback.print_exc()
|
|
1360
1368
|
|
|
1361
1369
|
def do_debug(self, line): # pylint: disable=unused-argument
|
|
1362
|
-
"""Show debug information"""
|
|
1370
|
+
"""Show debug information."""
|
|
1363
1371
|
if self.client.xml_plugin:
|
|
1364
1372
|
if self._last_method and self._last_operation_timestamp:
|
|
1365
1373
|
print(f"{colorize('Last Operation:', 'cyan')}")
|
|
@@ -1379,16 +1387,16 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1379
1387
|
)
|
|
1380
1388
|
|
|
1381
1389
|
def do_exit(self, line): # pylint: disable=unused-argument
|
|
1382
|
-
"""Exit the shell"""
|
|
1390
|
+
"""Exit the shell."""
|
|
1383
1391
|
self._stop_health_check.set()
|
|
1384
1392
|
print(colorize("Goodbye!", "cyan"))
|
|
1385
1393
|
return True
|
|
1386
1394
|
|
|
1387
1395
|
def emptyline(self):
|
|
1388
|
-
"""Handle empty line"""
|
|
1396
|
+
"""Handle empty line."""
|
|
1389
1397
|
|
|
1390
1398
|
def do_help(self, line):
|
|
1391
|
-
"""Show help information"""
|
|
1399
|
+
"""Show help information."""
|
|
1392
1400
|
if line:
|
|
1393
1401
|
super().do_help(line)
|
|
1394
1402
|
else:
|
|
@@ -1462,7 +1470,7 @@ class InteractiveShell(cmd.Cmd):
|
|
|
1462
1470
|
print(help_text)
|
|
1463
1471
|
|
|
1464
1472
|
def run(self):
|
|
1465
|
-
"""Run the interactive shell"""
|
|
1473
|
+
"""Run the interactive shell."""
|
|
1466
1474
|
try:
|
|
1467
1475
|
self.cmdloop()
|
|
1468
1476
|
except KeyboardInterrupt:
|