onvif-python 0.2.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

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/cli/interactive.py CHANGED
@@ -194,7 +194,7 @@ class InteractiveShell(cmd.Cmd):
194
194
  " / __ \\/ | / / | / / _/ ____/",
195
195
  " / / / / |/ /| | / // // /_ ",
196
196
  "/ /_/ / /| / | |/ // // __/ ",
197
- "\\____/_/ |_/ |___/___/_/ v0.2.0",
197
+ "\\____/_/ |_/ |___/___/_/ v0.2.1",
198
198
  " ",
199
199
  ]
200
200
 
@@ -1400,7 +1400,7 @@ class InteractiveShell(cmd.Cmd):
1400
1400
  super().do_help(line)
1401
1401
  else:
1402
1402
  help_text = f"""
1403
- {colorize('ONVIF Interactive Shell — v0.2.0', 'cyan')}\n{colorize('https://github.com/nirsimetri/onvif-python', 'white')}
1403
+ {colorize('ONVIF Interactive Shell — v0.2.1', 'cyan')}\n{colorize('https://github.com/nirsimetri/onvif-python', 'white')}
1404
1404
 
1405
1405
  {colorize('Basic Commands:', 'yellow')}
1406
1406
  capabilities, caps - Show device capabilities
onvif/cli/main.py CHANGED
@@ -21,7 +21,7 @@ def create_parser():
21
21
  """Create argument parser for ONVIF CLI"""
22
22
  parser = argparse.ArgumentParser(
23
23
  prog="onvif",
24
- description=f"{colorize('ONVIF Terminal Client', 'yellow')} — v0.2.0\nhttps://github.com/nirsimetri/onvif-python",
24
+ description=f"{colorize('ONVIF Terminal Client', 'yellow')} — v0.2.1\nhttps://github.com/nirsimetri/onvif-python",
25
25
  formatter_class=argparse.RawDescriptionHelpFormatter,
26
26
  epilog=f"""
27
27
  Examples:
@@ -198,10 +198,14 @@ def search_products(search_term: str, page: int = 1, per_page: int = 20) -> None
198
198
  WHERE LOWER(model) LIKE LOWER(?)
199
199
  OR LOWER(post_title) LIKE LOWER(?)
200
200
  OR LOWER(company_name) LIKE LOWER(?)
201
+ OR LOWER(product_category) LIKE LOWER(?)
201
202
  """
202
203
 
203
204
  search_pattern = f"%{search_term}%"
204
- cursor.execute(count_query, (search_pattern, search_pattern, search_pattern))
205
+ cursor.execute(
206
+ count_query,
207
+ (search_pattern, search_pattern, search_pattern, search_pattern),
208
+ )
205
209
  total_count = cursor.fetchone()[0]
206
210
 
207
211
  if total_count == 0:
@@ -229,12 +233,21 @@ def search_products(search_term: str, page: int = 1, per_page: int = 20) -> None
229
233
  WHERE LOWER(model) LIKE LOWER(?)
230
234
  OR LOWER(post_title) LIKE LOWER(?)
231
235
  OR LOWER(company_name) LIKE LOWER(?)
236
+ OR LOWER(product_category) LIKE LOWER(?)
232
237
  ORDER BY test_date DESC
233
238
  LIMIT ? OFFSET ?
234
239
  """
235
240
 
236
241
  cursor.execute(
237
- query, (search_pattern, search_pattern, search_pattern, per_page, offset)
242
+ query,
243
+ (
244
+ search_pattern,
245
+ search_pattern,
246
+ search_pattern,
247
+ search_pattern,
248
+ per_page,
249
+ offset,
250
+ ),
238
251
  )
239
252
  results = cursor.fetchall()
240
253
 
@@ -448,7 +461,7 @@ def main():
448
461
 
449
462
  # Show ONVIF CLI version
450
463
  if args.version:
451
- print(colorize("0.2.0", "yellow"))
464
+ print(colorize("0.2.1", "yellow"))
452
465
  sys.exit(0)
453
466
 
454
467
  # Handle product search
onvif/operator.py CHANGED
@@ -15,6 +15,7 @@ from zeep.wsse.username import UsernameToken
15
15
  from .utils import ONVIFOperationException, ZeepPatcher
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
+ logger.addHandler(logging.NullHandler())
18
19
 
19
20
 
20
21
  class CacheMode(Enum):
@@ -194,7 +195,6 @@ class ONVIFOperator:
194
195
  try:
195
196
  func = getattr(self.service, method)
196
197
  except AttributeError as e:
197
- logger.error(f"Method {method} not found in {self.service_name} service")
198
198
  raise ONVIFOperationException(operation=method, original_exception=e)
199
199
 
200
200
  try:
@@ -207,10 +207,8 @@ class ONVIFOperator:
207
207
  return result
208
208
 
209
209
  except Fault as e:
210
- logger.error(f"SOAP Fault in {self.service_name}.{method}: {e}")
211
210
  raise ONVIFOperationException(operation=method, original_exception=e)
212
211
  except Exception as e:
213
- logger.error(f"ONVIF call error in {self.service_name}.{method}: {e}")
214
212
  raise ONVIFOperationException(operation=method, original_exception=e)
215
213
 
216
214
  def create_type(self, type_name: str):
onvif/utils/discovery.py CHANGED
@@ -8,6 +8,7 @@ from lxml import etree
8
8
  from typing import List, Dict, Any, Optional
9
9
 
10
10
  logger = logging.getLogger(__name__)
11
+ logger.addHandler(logging.NullHandler())
11
12
 
12
13
 
13
14
  class ONVIFDiscovery:
@@ -5,6 +5,7 @@ from zeep.exceptions import Fault
5
5
  from .exceptions import ONVIFOperationException
6
6
 
7
7
  logger = logging.getLogger(__name__)
8
+ logger.addHandler(logging.NullHandler())
8
9
 
9
10
 
10
11
  class ONVIFErrorHandler:
onvif/utils/service.py CHANGED
@@ -4,6 +4,7 @@ import logging
4
4
  from .exceptions import ONVIFOperationException
5
5
 
6
6
  logger = logging.getLogger(__name__)
7
+ logger.addHandler(logging.NullHandler())
7
8
 
8
9
 
9
10
  def _is_zeep_object(obj):
@@ -40,13 +41,6 @@ class ONVIFService:
40
41
  3. Is not a private method (doesn't start with underscore)
41
42
  4. Is not an internal attribute (like 'operator')
42
43
 
43
- Benefits:
44
- 1. **DRY Principle**: No need to repeat error handling in every method
45
- 2. **Consistency**: All ONVIF operations behave the same way
46
- 3. **Maintainability**: Error handling logic in one place
47
- 4. **Debuggability**: Always know which operation failed
48
- 5. **Transparency**: No boilerplate code in service implementations
49
-
50
44
  Notes:
51
45
  - This is an abstract base class - don't instantiate directly
52
46
  - Subclasses must implement their own __init__ and ONVIF methods
@@ -113,11 +107,13 @@ class ONVIFService:
113
107
  return result
114
108
  except ONVIFOperationException as oe:
115
109
  # Re-raise ONVIF exceptions as-is
116
- logger.error(f"ONVIF operation exception in {name}: {oe}")
110
+ service_name = getattr(self.operator, "service_name", "Unknown")
111
+ logger.error(f"{service_name}.{name}: {oe}")
117
112
  raise
118
113
  except Exception as e:
119
114
  # Convert any other exception (including TypeError) to ONVIFOperationException
120
- logger.error(f"ONVIF operation exception in {name}: {e}")
115
+ service_name = getattr(self.operator, "service_name", "Unknown")
116
+ logger.error(f"{service_name}.{name}: {e}")
121
117
  raise ONVIFOperationException(name, e)
122
118
 
123
119
  return wrapped_method
onvif/utils/wsdl.py CHANGED
@@ -4,6 +4,7 @@ import os
4
4
  import logging
5
5
 
6
6
  logger = logging.getLogger(__name__)
7
+ logger.addHandler(logging.NullHandler())
7
8
 
8
9
 
9
10
  class ONVIFWSDL:
@@ -5,6 +5,7 @@ from zeep import Plugin
5
5
  from lxml import etree
6
6
 
7
7
  logger = logging.getLogger(__name__)
8
+ logger.addHandler(logging.NullHandler())
8
9
 
9
10
 
10
11
  class XMLCapturePlugin(Plugin):
onvif/utils/zeep.py CHANGED
@@ -6,6 +6,7 @@ from zeep.xsd.elements.any import Any
6
6
  from zeep.xsd.utils import max_occurs_iter
7
7
 
8
8
  logger = logging.getLogger(__name__)
9
+ logger.addHandler(logging.NullHandler())
9
10
 
10
11
 
11
12
  class ZeepPatcher:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onvif-python
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: A modern Python library for ONVIF-compliant devices
5
5
  Author-email: Nirsimetri Technologies® <open@nirsimetri.com>
6
6
  Maintainer: Kaburagi
@@ -47,7 +47,7 @@ Dynamic: license-file
47
47
 
48
48
  [![Codacy grade](https://img.shields.io/codacy/grade/bff08a94e4d447b690cea49c6594826d?label=Code%20Quality&logo=codacy)](https://app.codacy.com/gh/nirsimetri/onvif-python/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
49
49
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/nirsimetri/onvif-python)
50
- [![PyPI](https://img.shields.io/badge/PyPI-0.2.0-orange?logo=archive)](https://pypi.org/project/onvif-python/)
50
+ [![PyPI](https://img.shields.io/badge/PyPI-0.2.1-orange?logo=archive)](https://pypi.org/project/onvif-python/)
51
51
  [![Downloads](https://img.shields.io/pypi/dm/onvif-python?label=Downloads&color=red)](https://clickpy.clickhouse.com/dashboard/onvif-python)
52
52
  <br>
53
53
  [![Build](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml/badge.svg?branch=main)](https://github.com/nirsimetri/onvif-python/actions/workflows/python-app.yml)
@@ -356,7 +356,7 @@ usage: onvif [-h] [--host HOST] [--port PORT] [--username USERNAME] [--password
356
356
  [--no-verify] [--no-patch] [--interactive] [--debug] [--wsdl WSDL] [--cache {all,db,mem,none}] [--health-check-interval HEALTH_CHECK_INTERVAL] [--version]
357
357
  [service] [method] [params ...]
358
358
 
359
- ONVIF Terminal Client — v0.2.0
359
+ ONVIF Terminal Client — v0.2.1
360
360
  https://github.com/nirsimetri/onvif-python
361
361
 
362
362
  positional arguments:
@@ -429,7 +429,7 @@ Examples:
429
429
  <summary><b>2. Interactive Shell</b></summary>
430
430
 
431
431
  ```bash
432
- ONVIF Interactive Shell — v0.2.0
432
+ ONVIF Interactive Shell — v0.2.1
433
433
  https://github.com/nirsimetri/onvif-python
434
434
 
435
435
  Basic Commands:
@@ -1,10 +1,10 @@
1
1
  onvif/__init__.py,sha256=BjW2KsafIGzybY_IeffeAPdmDDXuxA6G4uo5sl42Dtw,463
2
2
  onvif/client.py,sha256=ld5Gm7B-1XvNNcfS-FAILrnKs8bPbbXGpnKbU-7Vmrw,26198
3
- onvif/operator.py,sha256=mJAWb5KBRxClUeervV347eE3UQzYe0ydwGmNo6qbfNg,14175
3
+ onvif/operator.py,sha256=fBaoWYC3ZVFdgd2S_cmztWiLAA-HaWwSflq278YNlTs,13970
4
4
  onvif/cli/__init__.py,sha256=y3hc-mo-Iwwxf8m5vo9P_0m2ISzGuOy-jaRPkdRY05A,68
5
5
  onvif/cli/__main__.py,sha256=IZyZcevWVKE1BzdFY53a3MjOOfybncGVVXQ_7lZ3TOQ,165
6
- onvif/cli/interactive.py,sha256=oIn45T2HEFYx54X5iOhXMJBRla4ywmS94bSMfSFStOk,59756
7
- onvif/cli/main.py,sha256=-LsBme1PTQSDxZSt216H9FmbjWDQXchgt9dksg87D-A,27017
6
+ onvif/cli/interactive.py,sha256=76Eh407wIPOzdudxqEzfls9ntLcCN_l9-JLFj29AXDE,59756
7
+ onvif/cli/main.py,sha256=pBIEdsT2y1B-9mCMRNnSZ_W5fr4t8suCqmBdSxzDCoQ,27312
8
8
  onvif/cli/utils.py,sha256=FSu_fZGAMQTLb4h9HzNSgz8vHtLD8Mc540WSKlyVPHQ,54962
9
9
  onvif/db/companies.db,sha256=yJ8bSHfGpxNnA5NRBhYOFS_1Pix-KgH8GnUFV3ytzPo,270336
10
10
  onvif/db/products.db,sha256=4BVPfy6i6pLMLQyfue238uRp6_NIDodu4QXd9iCoooY,81559552
@@ -46,13 +46,13 @@ onvif/services/security/keystore.py,sha256=P9QYieCAZ3yf5Gq6DZKpG832XD-rNVateFxlZ
46
46
  onvif/services/security/mediasigning.py,sha256=7ia_NIdLM3kwZwwOM95WfR0TTXkZSYCt6j8wL5Vl7zI,1361
47
47
  onvif/services/security/tlsserver.py,sha256=UO_0VHtbu0Zx1cOsJePtEwPbmYL0RHyRhoInCWIzx_M,3412
48
48
  onvif/utils/__init__.py,sha256=IKQcaVblxuCyFzg0wFRuGyRcVboYpqjNBdp6_iExSTM,467
49
- onvif/utils/discovery.py,sha256=kfotZTUGlMBoQ6QUvK1dBorrZKgM8aEkJ0qf__emQD8,14724
50
- onvif/utils/error_handlers.py,sha256=eTV4PfFnu-cJf4THVrSHKXUB1MfDyYJURk0pbd4UxgQ,4810
49
+ onvif/utils/discovery.py,sha256=YO44KiQhfcyUECNrRe4qe03DSh14GGVByu1W5ekbAXU,14765
50
+ onvif/utils/error_handlers.py,sha256=MwPNfUeDA6d_nNZ01P0Ut67ERBYVvjsYrRsQhIo28yc,4851
51
51
  onvif/utils/exceptions.py,sha256=5DxvqKAL7w038qPFeWmtkR5F3jWK0nz0qerzsOQPh0k,7788
52
- onvif/utils/service.py,sha256=DsrsUeMwRRhCkc1znFZKK5EeoBkXfST7z3ngp-86Kp0,12917
53
- onvif/utils/wsdl.py,sha256=Rc75XQX1F0bn7XiF7oyRTtzVhOPSkznNQkOP2dY3CNw,27209
54
- onvif/utils/xml_capture.py,sha256=xQ1N7HjXuypkykof3pdDlQqdt0h9OfSqeWhBBrmTSBE,8246
55
- onvif/utils/zeep.py,sha256=m8R0o5G9ycOvrEEngNMUzG8Y39NrWuzgkoYSbgRP-DY,28552
52
+ onvif/utils/service.py,sha256=VTCOY5PMjaY9KgCznDomTcPLVIorIRnqBPd7VCoLxAM,12722
53
+ onvif/utils/wsdl.py,sha256=9VqJwxjyrz_gtNQ5IHPQ0pjek6Y0aOOkencWXkUGKp4,27250
54
+ onvif/utils/xml_capture.py,sha256=pZF-14QUG4gFcfZDvG6ykVEMI0xLNgUv4rtzNdR1GNI,8287
55
+ onvif/utils/zeep.py,sha256=NFNL2f7Nrr6-CQyQ02n3jMCZ73EEPNct9IgAXzBgVk4,28593
56
56
  onvif/wsdl/LICENSE.md,sha256=O0J5vlcNSuEulS5rESOZWYy-IEnH4QeJkQ4ebZZNkSQ,16439
57
57
  onvif/wsdl/ver10/actionengine.wsdl,sha256=mQCRdRMdh517EUkDCKEfBHl_GvX9dPABqtgwU9K8FWE,55762
58
58
  onvif/wsdl/ver10/analyticsdevice.wsdl,sha256=JCd2pab5RAgoPm_26Q3l6sda8cGkam4dsXeluJ4euyA,30999
@@ -112,9 +112,9 @@ onvif/wsdl/ver20/util/federated_search_documentation.html,sha256=GR6a4SPBsRDisaW
112
112
  onvif/wsdl/ver20/util/fedsearch-docu-viewer.xsl,sha256=8eP-uMZgsTtuU5WaVyCzs_DJZqWIFD7iRz_5-3ComPg,325
113
113
  onvif/wsdl/ver20/util/onvif-wsdl-viewer.xsl,sha256=Emauxs6rh69IxlxlU3k_LEH_i3SsRbwIKUk-VcMlVgk,94525
114
114
  onvif/wsdl/ver20/util/operationIndex.html,sha256=mUsAGgNUFCIQjVV9Rx_O5YUNW3EdWNhUkAbBY-xVMhQ,39290
115
- onvif_python-0.2.0.dist-info/licenses/LICENSE.md,sha256=ya8FumJeUkFWwCMkG9KdMxHWRWMNhtI3vHzzAWPQS8s,1091
116
- onvif_python-0.2.0.dist-info/METADATA,sha256=MuiXP34N2RDLa5cBhBu3cx4zvqVmxsW33iTGPDWCgUY,60787
117
- onvif_python-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
118
- onvif_python-0.2.0.dist-info/entry_points.txt,sha256=7xUdI64yzWh7YfNPQDKCW9cT8XIgWuNCloikP9-yjqY,46
119
- onvif_python-0.2.0.dist-info/top_level.txt,sha256=MqCi1uJmIvtVFJDz2IxLbpwq6FwDtWhqrWQtKwLaQg4,6
120
- onvif_python-0.2.0.dist-info/RECORD,,
115
+ onvif_python-0.2.1.dist-info/licenses/LICENSE.md,sha256=ya8FumJeUkFWwCMkG9KdMxHWRWMNhtI3vHzzAWPQS8s,1091
116
+ onvif_python-0.2.1.dist-info/METADATA,sha256=rR-QwCLigV-WgAtXUbTBaRrddC-XXkhPBiwNMVBU2uE,60787
117
+ onvif_python-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
118
+ onvif_python-0.2.1.dist-info/entry_points.txt,sha256=7xUdI64yzWh7YfNPQDKCW9cT8XIgWuNCloikP9-yjqY,46
119
+ onvif_python-0.2.1.dist-info/top_level.txt,sha256=MqCi1uJmIvtVFJDz2IxLbpwq6FwDtWhqrWQtKwLaQg4,6
120
+ onvif_python-0.2.1.dist-info/RECORD,,