viso-sdk-python 1.1.24__tar.gz → 1.1.25__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.
Files changed (147) hide show
  1. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/CHANGELOG.md +6 -0
  2. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/PKG-INFO +4 -6
  3. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/setup.py +3 -5
  4. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_redis_wrapper.py +48 -51
  5. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/_version.c +9 -9
  6. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/_version.py +1 -1
  7. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/frame_reader.c +2730 -1783
  8. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/frame_reader.py +45 -10
  9. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/redis_wrapper.c +1329 -1131
  10. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/redis_wrapper.py +15 -25
  11. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/viso_data.c +151 -163
  12. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/viso_data.py +2 -2
  13. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk_python.egg-info/PKG-INFO +4 -6
  14. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/AUTHORS +0 -0
  15. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/COPYING +0 -0
  16. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/MANIFEST.in +0 -0
  17. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/README.md +0 -0
  18. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/Makefile +0 -0
  19. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/__init__.py +0 -0
  20. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/conf.py +0 -0
  21. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/ext/__init__.py +0 -0
  22. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/ext/docstrings.py +0 -0
  23. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/ext/manager_tmpl.j2 +0 -0
  24. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/index.rst +0 -0
  25. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/make.bat +0 -0
  26. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/modules.rst +0 -0
  27. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk._version.rst +0 -0
  28. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.constants.constants.rst +0 -0
  29. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.constants.modules.rst +0 -0
  30. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.constants.rst +0 -0
  31. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.constants.variables.rst +0 -0
  32. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.edge.common.rst +0 -0
  33. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.edge.rst +0 -0
  34. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.logging.logger.rst +0 -0
  35. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.logging.rst +0 -0
  36. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.model.download.rst +0 -0
  37. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.model.rst +0 -0
  38. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.mqtt.mqtt_wrapper.rst +0 -0
  39. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.mqtt.rst +0 -0
  40. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.mqtt.utils.rst +0 -0
  41. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.nodered.flow.rst +0 -0
  42. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.nodered.rst +0 -0
  43. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.redis.redis_wrapper.rst +0 -0
  44. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.redis.rst +0 -0
  45. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.rst +0 -0
  46. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.status.rst +0 -0
  47. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/docs/source/viso_sdk.status.status_logger.rst +0 -0
  48. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/pyproject.toml +0 -0
  49. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/requirements-dev.txt +0 -0
  50. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/requirements-docker.txt +0 -0
  51. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/requirements-docs.txt +0 -0
  52. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/requirements-lint.txt +0 -0
  53. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/requirements-test.txt +0 -0
  54. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/requirements.txt +0 -0
  55. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/setup.cfg +0 -0
  56. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/__init__.py +0 -0
  57. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/conftest.py +0 -0
  58. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/fixtures/flow.json +0 -0
  59. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/integration/__init__.py +0 -0
  60. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/integration/test_status.py +0 -0
  61. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/meta/__init__.py +0 -0
  62. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/meta/test_ensure_type_hints.py +0 -0
  63. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/smoke/__init__.py +0 -0
  64. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/smoke/test_dists.py +0 -0
  65. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/__init__.py +0 -0
  66. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_flow.py +0 -0
  67. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_log_id.py +0 -0
  68. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_logger.py +0 -0
  69. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_model_fetch.py +0 -0
  70. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_nms.py +0 -0
  71. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_object.py +0 -0
  72. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_polygon_roi_manager.py +0 -0
  73. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_redis_utils.py +0 -0
  74. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_rollingq.py +0 -0
  75. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_stream_cleanup.py +0 -0
  76. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_trace_malloc.py +0 -0
  77. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tests/unit/test_viso_data.py +0 -0
  78. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/tox.ini +0 -0
  79. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/__init__.c +0 -0
  80. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/__init__.py +0 -0
  81. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/constants/__init__.c +0 -0
  82. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/constants/__init__.py +0 -0
  83. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/constants/constants.c +0 -0
  84. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/constants/constants.py +0 -0
  85. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/constants/modules.c +0 -0
  86. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/constants/modules.py +0 -0
  87. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/constants/variables.c +0 -0
  88. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/constants/variables.py +0 -0
  89. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/debug/__init__.c +0 -0
  90. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/debug/__init__.py +0 -0
  91. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/debug/trace_malloc.c +0 -0
  92. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/debug/trace_malloc.py +0 -0
  93. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/detection/__init__.c +0 -0
  94. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/detection/__init__.py +0 -0
  95. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/detection/model_utils.c +0 -0
  96. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/detection/model_utils.py +0 -0
  97. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/detection/nms.c +0 -0
  98. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/detection/nms.py +0 -0
  99. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/detection/object.c +0 -0
  100. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/detection/object.py +0 -0
  101. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/edge/__init__.c +0 -0
  102. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/edge/__init__.py +0 -0
  103. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/edge/common.c +0 -0
  104. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/edge/common.py +0 -0
  105. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/logging/__init__.c +0 -0
  106. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/logging/__init__.py +0 -0
  107. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/logging/log_id.c +0 -0
  108. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/logging/log_id.py +0 -0
  109. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/logging/logger.c +0 -0
  110. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/logging/logger.py +0 -0
  111. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/model/__init__.c +0 -0
  112. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/model/__init__.py +0 -0
  113. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/model/fetch.c +0 -0
  114. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/model/fetch.py +0 -0
  115. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/mqtt/__init__.c +0 -0
  116. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/mqtt/__init__.py +0 -0
  117. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/mqtt/mqtt_wrapper.c +0 -0
  118. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/mqtt/mqtt_wrapper.py +0 -0
  119. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/mqtt/utils.c +0 -0
  120. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/mqtt/utils.py +0 -0
  121. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/nodered/__init__.c +0 -0
  122. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/nodered/__init__.py +0 -0
  123. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/nodered/flow.c +0 -0
  124. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/nodered/flow.py +0 -0
  125. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/py.typed +0 -0
  126. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/__init__.c +0 -0
  127. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/__init__.py +0 -0
  128. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/stream_cleanup.c +0 -0
  129. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/stream_cleanup.py +0 -0
  130. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/utils.c +0 -0
  131. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/redis/utils.py +0 -0
  132. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/roi/__init__.c +0 -0
  133. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/roi/__init__.py +0 -0
  134. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/roi/polygon_roi_manager.c +0 -0
  135. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/roi/polygon_roi_manager.py +0 -0
  136. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/status/__init__.c +0 -0
  137. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/status/__init__.py +0 -0
  138. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/status/status_logger.c +0 -0
  139. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/status/status_logger.py +0 -0
  140. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/structures/__init__.c +0 -0
  141. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/structures/__init__.py +0 -0
  142. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/structures/rollingq.c +0 -0
  143. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk/structures/rollingq.py +0 -0
  144. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk_python.egg-info/SOURCES.txt +0 -0
  145. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk_python.egg-info/dependency_links.txt +0 -0
  146. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk_python.egg-info/requires.txt +0 -0
  147. {viso_sdk_python-1.1.24 → viso_sdk_python-1.1.25}/viso_sdk_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,12 @@
1
1
  # Changelog
2
2
 
3
3
  <!--next-version-placeholder-->
4
+ ## v1.1.25
5
+ ### Performance
6
+ - replace stdlib `json` with `orjson` in `parse_viso_data`
7
+ - replace Redis polling with pub/sub blocking in `FrameReader`
8
+ - pipeline SET + PUBLISH into a single round-trip in `redis_wrapper`
9
+
4
10
  ## v1.1.24
5
11
  ### Features
6
12
  - add `FrameReader` to centralise Redis frame consumption — moves the read→dedup→decode pipeline into a single SDK class; dedup is now checked on the raw dict before base64 decode and JPEG decompress, so duplicate polls at high poll rates are effectively free
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: viso-sdk-python
3
- Version: 1.1.24
3
+ Version: 1.1.25
4
4
  Summary: VisoSDK: A Python SDK for use in Viso containers
5
5
  Home-page: https://gitlab.com/TopKamera/03_edge/Base/viso-sdk-python-public.git
6
6
  Author: support@viso.ai
@@ -14,12 +14,10 @@ Classifier: Natural Language :: English
14
14
  Classifier: Operating System :: POSIX
15
15
  Classifier: Programming Language :: Python
16
16
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.6
18
- Classifier: Programming Language :: Python :: 3.7
19
- Classifier: Programming Language :: Python :: 3.8
20
- Classifier: Programming Language :: Python :: 3.9
21
17
  Classifier: Programming Language :: Python :: 3.10
22
- Requires-Python: >=3.6.0
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Requires-Python: >=3.10
23
21
  Description-Content-Type: text/markdown
24
22
  License-File: COPYING
25
23
  License-File: AUTHORS
@@ -63,7 +63,7 @@ setup(
63
63
  "orjson>=3.9.0"
64
64
  ],
65
65
  package_data={"viso_sdk": ["assets/*", "assets/*/*"]},
66
- python_requires=">=3.6.0",
66
+ python_requires=">=3.10",
67
67
  entry_points={},
68
68
  # dependency_links=["https://www.piwheels.org/simple"],
69
69
  classifiers=[
@@ -75,11 +75,9 @@ setup(
75
75
  "Operating System :: POSIX",
76
76
  "Programming Language :: Python",
77
77
  "Programming Language :: Python :: 3",
78
- "Programming Language :: Python :: 3.6",
79
- "Programming Language :: Python :: 3.7",
80
- "Programming Language :: Python :: 3.8",
81
- "Programming Language :: Python :: 3.9",
82
78
  "Programming Language :: Python :: 3.10",
79
+ "Programming Language :: Python :: 3.11",
80
+ "Programming Language :: Python :: 3.12",
83
81
  ],
84
82
  ext_modules=cythonize("viso_sdk/**/*.py", compiler_directives={"language_level": "3"}) if USE_CYTHON else [],
85
83
  # options={"bdist_wheel": {"universal": True}},
@@ -9,82 +9,83 @@ from viso_sdk.redis.redis_wrapper import RedisWrapper
9
9
 
10
10
 
11
11
  @pytest.fixture
12
- def mock_client():
13
- return MagicMock()
12
+ def mock_pipe():
13
+ pipe = MagicMock()
14
+ pipe.execute.return_value = [True, 1]
15
+ return pipe
14
16
 
15
17
 
16
18
  @pytest.fixture
17
- def wrapper(mock_client):
18
- with patch("viso_sdk.redis.redis_wrapper.redis.StrictRedis", return_value=mock_client):
19
+ def wrapper(mock_pipe):
20
+ client = MagicMock()
21
+ client.pipeline.return_value.__enter__.return_value = mock_pipe
22
+ client.pipeline.return_value.__exit__.return_value = False
23
+ with patch("viso_sdk.redis.redis_wrapper.redis.StrictRedis", return_value=client):
19
24
  rw = RedisWrapper(thread=False)
20
- return rw, mock_client
25
+ return rw, client, mock_pipe
21
26
 
22
27
 
23
28
  class TestWriteData:
24
29
  def test_write_string(self, wrapper):
25
- rw, client = wrapper
26
- client.set.return_value = True
30
+ rw, client, pipe = wrapper
27
31
  result = rw.write_data("my_key", "hello")
28
32
  assert result is True
29
- client.set.assert_called_once_with("my_key", "hello", ex=None)
33
+ pipe.set.assert_called_once_with("my_key", "hello", ex=None)
30
34
 
31
35
  def test_write_dict_serialised_as_json(self, wrapper):
32
- rw, client = wrapper
33
- client.set.return_value = True
36
+ rw, client, pipe = wrapper
34
37
  rw.write_data("my_key", {"a": 1, "b": 2})
35
- call_args = client.set.call_args[0]
38
+ call_args = pipe.set.call_args[0]
36
39
  assert json.loads(call_args[1]) == {"a": 1, "b": 2}
37
40
 
38
41
  def test_write_with_ttl(self, wrapper):
39
- rw, client = wrapper
40
- client.set.return_value = True
42
+ rw, client, pipe = wrapper
41
43
  rw.write_data("my_key", "val", ttl=60)
42
- client.set.assert_called_once_with("my_key", "val", ex=60)
44
+ pipe.set.assert_called_once_with("my_key", "val", ex=60)
43
45
 
44
46
  def test_publishes_notification_on_successful_write(self, wrapper):
45
- rw, client = wrapper
46
- client.set.return_value = True
47
+ rw, client, pipe = wrapper
47
48
  rw.write_data("my_key", "hello")
48
- client.publish.assert_called_once_with("my_key_notify", "1")
49
+ pipe.publish.assert_called_once_with("my_key_notify", "1")
49
50
 
50
- def test_does_not_publish_when_write_fails(self, wrapper):
51
- rw, client = wrapper
52
- client.set.return_value = False
53
- rw.write_data("my_key", "hello")
54
- client.publish.assert_not_called()
51
+ def test_returns_false_when_set_fails(self, wrapper):
52
+ rw, client, pipe = wrapper
53
+ pipe.execute.return_value = [False, 0]
54
+ result = rw.write_data("my_key", "hello")
55
+ assert result is False
55
56
 
56
57
  def test_handles_publish_error_gracefully(self, wrapper):
57
- rw, client = wrapper
58
- client.set.return_value = True
59
- client.publish.side_effect = Exception("publish failed")
58
+ # A publish server-side error appears as an exception in the execute()
59
+ # result list — it does not abort the pipeline or change the set result.
60
+ rw, client, pipe = wrapper
61
+ pipe.execute.return_value = [True, Exception("publish failed")]
60
62
  result = rw.write_data("my_key", "hello")
61
- # Should still return True even if publish fails
62
63
  assert result is True
63
- client.publish.assert_called_once_with("my_key_notify", "1")
64
+ pipe.publish.assert_called_once_with("my_key_notify", "1")
64
65
 
65
66
 
66
67
  class TestReadData:
67
68
  def test_returns_raw_bytes(self, wrapper):
68
- rw, client = wrapper
69
+ rw, client, pipe = wrapper
69
70
  client.get.return_value = b"raw"
70
71
  assert rw.read_data("key") == b"raw"
71
72
  client.get.assert_called_once_with("key")
72
73
 
73
74
  def test_returns_none_when_key_missing(self, wrapper):
74
- rw, client = wrapper
75
+ rw, client, pipe = wrapper
75
76
  client.get.return_value = None
76
77
  assert rw.read_data("missing") is None
77
78
 
78
79
 
79
80
  class TestReadVisoData:
80
81
  def test_decodes_json_bytes(self, wrapper):
81
- rw, client = wrapper
82
+ rw, client, pipe = wrapper
82
83
  client.get.return_value = b'{"result": [1, 2]}'
83
84
  result = rw.read_viso_data("key")
84
85
  assert result == {"result": [1, 2]}
85
86
 
86
87
  def test_returns_none_on_redis_error(self, wrapper):
87
- rw, client = wrapper
88
+ rw, client, pipe = wrapper
88
89
  client.get.side_effect = Exception("connection refused")
89
90
  result = rw.read_viso_data("key")
90
91
  assert result is None
@@ -92,54 +93,50 @@ class TestReadVisoData:
92
93
 
93
94
  class TestDeleteData:
94
95
  def test_delete_returns_true_on_success(self, wrapper):
95
- rw, client = wrapper
96
+ rw, client, pipe = wrapper
96
97
  client.delete.return_value = 1
97
98
  assert rw.delete_data("key") is True
98
99
  client.delete.assert_called_once_with("key")
99
100
 
100
101
  def test_delete_returns_false_when_key_not_found(self, wrapper):
101
- rw, client = wrapper
102
+ rw, client, pipe = wrapper
102
103
  client.delete.return_value = 0
103
104
  assert rw.delete_data("missing") is False
104
105
 
105
106
 
106
107
  class TestWriteVisoData:
107
108
  def test_sync_write_when_thread_disabled(self, wrapper):
108
- rw, client = wrapper
109
- client.set.return_value = True
109
+ rw, client, pipe = wrapper
110
110
  result = rw.write_viso_data({"frame": None}, "key")
111
111
  assert result is True
112
112
 
113
113
  def test_write_none_deletes_key(self, wrapper):
114
- rw, client = wrapper
114
+ rw, client, pipe = wrapper
115
115
  client.delete.return_value = 1
116
116
  rw.write_viso_data(None, "key")
117
117
  client.delete.assert_called_once_with("key")
118
118
 
119
119
  def test_publishes_notification_on_successful_write(self, wrapper):
120
- rw, client = wrapper
121
- client.set.return_value = True
120
+ rw, client, pipe = wrapper
122
121
  rw.write_viso_data({"frame": None, "result": []}, "viso_key")
123
- client.publish.assert_called_once_with("viso_key_notify", "1")
122
+ pipe.publish.assert_called_once_with("viso_key_notify", "1")
124
123
 
125
- def test_does_not_publish_when_write_fails(self, wrapper):
126
- rw, client = wrapper
127
- client.set.return_value = False
128
- rw.write_viso_data({"frame": None}, "viso_key")
129
- client.publish.assert_not_called()
124
+ def test_returns_false_when_set_fails(self, wrapper):
125
+ rw, client, pipe = wrapper
126
+ pipe.execute.return_value = [False, 0]
127
+ result = rw.write_viso_data({"frame": None}, "viso_key")
128
+ assert result is False
130
129
 
131
130
  def test_handles_publish_error_gracefully(self, wrapper):
132
- rw, client = wrapper
133
- client.set.return_value = True
134
- client.publish.side_effect = Exception("publish failed")
131
+ rw, client, pipe = wrapper
132
+ pipe.execute.return_value = [True, Exception("publish failed")]
135
133
  result = rw.write_viso_data({"frame": None}, "viso_key")
136
- # Should still return True even if publish fails
137
134
  assert result is True
138
- client.publish.assert_called_once_with("viso_key_notify", "1")
135
+ pipe.publish.assert_called_once_with("viso_key_notify", "1")
139
136
 
140
137
  def test_no_publish_when_deleting_with_none(self, wrapper):
141
- rw, client = wrapper
138
+ rw, client, pipe = wrapper
142
139
  client.delete.return_value = 1
143
140
  rw.write_viso_data(None, "key")
144
- # Should not publish when deleting
145
141
  client.publish.assert_not_called()
142
+ pipe.publish.assert_not_called()
@@ -1994,7 +1994,7 @@ static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_stati
1994
1994
  #endif
1995
1995
  /* #### Code section: constant_name_defines ### */
1996
1996
  #define __pyx_kp_u_ __pyx_string_tab[0]
1997
- #define __pyx_kp_u_1_1_24 __pyx_string_tab[1]
1997
+ #define __pyx_kp_u_1_1_25 __pyx_string_tab[1]
1998
1998
  #define __pyx_kp_u_Copyright_2020 __pyx_string_tab[2]
1999
1999
  #define __pyx_kp_u_Viso_ai_team __pyx_string_tab[3]
2000
2000
  #define __pyx_kp_u__2 __pyx_string_tab[4]
@@ -2605,16 +2605,16 @@ __Pyx_RefNannySetupContext("PyInit__version", 0);
2605
2605
  * __license__ = "LGPL3"
2606
2606
  * __title__ = "viso-sdk-python" # <<<<<<<<<<<<<<
2607
2607
  *
2608
- * __version__ = "1.1.24"
2608
+ * __version__ = "1.1.25"
2609
2609
  */
2610
2610
  if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_title, __pyx_mstate_global->__pyx_kp_u_viso_sdk_python) < (0)) __PYX_ERR(0, 15, __pyx_L1_error)
2611
2611
 
2612
2612
  /* "viso_sdk/_version.py":17
2613
2613
  * __title__ = "viso-sdk-python"
2614
2614
  *
2615
- * __version__ = "1.1.24" # <<<<<<<<<<<<<<
2615
+ * __version__ = "1.1.25" # <<<<<<<<<<<<<<
2616
2616
  */
2617
- if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_version, __pyx_mstate_global->__pyx_kp_u_1_1_24) < (0)) __PYX_ERR(0, 17, __pyx_L1_error)
2617
+ if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_version, __pyx_mstate_global->__pyx_kp_u_1_1_25) < (0)) __PYX_ERR(0, 17, __pyx_L1_error)
2618
2618
 
2619
2619
  /* "viso_sdk/_version.py":1
2620
2620
  * """ # <<<<<<<<<<<<<<
@@ -2689,23 +2689,23 @@ static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) {
2689
2689
  {
2690
2690
  const struct { const unsigned int length: 5; } index[] = {{1},{6},{15},{12},{1},{18},{26},{15},{5},{7},{10},{18},{13},{8},{8},{7},{9},{8},{11},{8},{10},{8},{3},{2},{4},{12},{10},{8},{9},{11},{4}};
2691
2691
  #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (242 bytes) */
2692
- const char* const cstring = "BZh91AY&SY\315\371f>\000\000\007\337\200@\000@\003|\005\350\204A\000\277\357\377\2400\000\315[\r&\246#(\360S\312\000\320z\023\001\0214\332\023\023L\200\000\000\003S\324\332\246\232\206\231\244=L\2324\r4hL\213\374\257+\275\327. \300\370\360\361k\217\252lmpbg\332\357\013\215&@\206\037\202\221\314\234\247\306\232\0024A\001\002\210\014o]\346\006\361\3621u\357\3131\235K\320\300\260\330\207@\327\237\232\032\004J\026\355\232b\3335[\021\302\255\312D\240(9\001\t\021\315F\365b\351\013\006\204E\255\332.V\252\221\334\236\350=\363bd\253ae5\270K\206\020\322\266?\256HJ\0312c>\014\205\241\021\336\245\310\201 `\2049\245\234\334)\304k\217K\007\352\323AG\325\354\"\317\245\270\273\222)\302\204\206o\3131\360";
2692
+ const char* const cstring = "BZh91AY&SY\375\235,\225\000\000\007\337\200@\000@\003z\005\350\204A\000\277\357\377\2400\000\315[\r&\246#(\360S\312\000\320z\023\001\0214\332\023\023L\200\000\000\003S\324\332\246\232\206\231\244=L\2324\r4hL\213\374\257+\275\327. \300\370\360\361k\217\252lmpbg\332\357\013\215&@\206\037\202\221\314\234\247\306\232\0024A\001\002\210\014o]\346\006\361\3621u\357\3131\235K\320\300\260\330\207@\327\237\232\032\004J\026\355\232b\3335[\021\302\255\312D\240(9\001\t\021\315F\365b\351\013\006\204E\255\332.V\252\221\334\236\350=\363bd\253ae5\270K\206\020\322\266?\256HJ\0312c>\014\205\241\021\336\245\310\201 `\2049\245\234\334)\304k\217K\007\352\323AG\325\354\"\317\245\270\273\222)\302\204\207\354\351d\250";
2693
2693
  PyObject *data = __Pyx_DecompressString(cstring, 242, 2);
2694
2694
  if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error)
2695
2695
  const char* const bytes = __Pyx_PyBytes_AsString(data);
2696
2696
  #if !CYTHON_ASSUME_SAFE_MACROS
2697
2697
  if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) }
2698
2698
  #endif
2699
- #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (195 bytes) */
2700
- const char* const cstring = "x\3325\216\275n\3030\014\204_\305/`!q;\006\375A\207,\031:e%\030\211\216\211\310\242#Q)\374\366\245\343x\272\303}8\036\335\336\355]\367\376#\323\234\371:h\323\355\272]{\346\"\016\271Q\302\361\363\352\274d\203\230\276\036\257|\323\357cs\340\324\313\006>\026mK\270\265\323\254\203\244\323\361\367\364\206\2272\241\016\000X-\313\000>r\"\340\004\232\321\323\005\375\315\262\355\0010_3\004\316\001\225\224G2\233p$\000\032\221\243q\3509\322\242\221=\245\362\264\206\322S%\324\025\256\235$\177\362\232\277W\214kXH\003\365X\243\255)\225e\023\224u\355=(\027\026;6\023\346\1777\017m\353";
2701
- PyObject *data = __Pyx_DecompressString(cstring, 195, 1);
2699
+ #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (196 bytes) */
2700
+ const char* const cstring = "x\3325\216\275n\3030\014\204_\305/`!q\321-\350\017:d\311\320)+\301HtLD\026\035\211J\341\267/\035\307\323\035\356\303\361\350\366n\357\272\367\037\231\346\314\327A\233n\327\355\3323\027q\310\215\022\216\237W\347%\033\304\364\365x\345\233~\037\233\003\247^6\360\261h[\302\255\235f\035$\235\216\277\2477\274\224\tu\000\300jY\006\360\221\023\001'\320\214\236.\350o\226m\017\200\371\232!p\016\250\244<\222\331\204#\001\320\210\034\215C\317\221\026\215\354)\225\2475\224\236*\241\256p\355$\371\223\327\374\275b\\\303B\032\250\307\032mM\251,\233\240\254k\357A\271\260\330\261\2310\377\0038(m\354";
2701
+ PyObject *data = __Pyx_DecompressString(cstring, 196, 1);
2702
2702
  if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error)
2703
2703
  const char* const bytes = __Pyx_PyBytes_AsString(data);
2704
2704
  #if !CYTHON_ASSUME_SAFE_MACROS
2705
2705
  if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) }
2706
2706
  #endif
2707
2707
  #else /* compression: none (287 bytes) */
2708
- const char* const bytes = ".1.1.24Copyright 2020-Viso.ai team?g.corrigan@viso.ai viso.ai AG <info@viso.ai>viso-sdk-pythonLGPL3abspath__author__cline_in_traceback__copyright___cur_dirdatetimedirname__email____file____license____main____module____name__nowospath__qualname__setdefault__test____title____version__year";
2708
+ const char* const bytes = ".1.1.25Copyright 2020-Viso.ai team?g.corrigan@viso.ai viso.ai AG <info@viso.ai>viso-sdk-pythonLGPL3abspath__author__cline_in_traceback__copyright___cur_dirdatetimedirname__email____file____license____main____module____name__nowospath__qualname__setdefault__test____title____version__year";
2709
2709
  PyObject *data = NULL;
2710
2710
  CYTHON_UNUSED_VAR(__Pyx_DecompressString);
2711
2711
  #endif
@@ -14,4 +14,4 @@ __email__ = "g.corrigan@viso.ai"
14
14
  __license__ = "LGPL3"
15
15
  __title__ = "viso-sdk-python"
16
16
 
17
- __version__ = "1.1.24"
17
+ __version__ = "1.1.25"