matrice-streaming 0.1.73__tar.gz → 0.1.76__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.
- matrice_streaming-0.1.76/MANIFEST.in +4 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/PKG-INFO +5 -4
- matrice_streaming-0.1.76/build-config.json +18 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/pyproject.toml +23 -7
- matrice_streaming-0.1.76/setup.py +87 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/client/client.py +6 -5
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/client/client_utils.py +6 -5
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/deployment/camera_manager.py +46 -45
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/deployment/deployment.py +9 -8
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/deployment/inference_pipeline.py +14 -13
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/deployment/streaming_gateway_manager.py +15 -11
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/__init__.py +32 -9
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/async_camera_worker.py +43 -41
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/async_ffmpeg_worker.py +39 -37
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/camera_streamer.py +9 -7
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/device_detection.py +8 -8
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/encoder_manager.py +5 -3
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/encoding_pool_manager.py +2 -2
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_camera_streamer.py +8 -6
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_config.py +2 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/ffmpeg_worker_manager.py +4 -4
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/frame_processor.py +2 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_camera_streamer.py +13 -11
- matrice_streaming-0.1.76/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_rtp_demuxer.py +763 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker.py +39 -37
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/gstreamer_worker_manager.py +3 -1
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/message_builder.py +2 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/nvdec.py +512 -104
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/nvdec_worker_manager.py +80 -41
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/platform_pipelines.py +3 -1
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/retry_manager.py +8 -6
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/stream_statistics.py +20 -18
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/video_capture_manager.py +12 -12
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/camera_streamer/worker_manager.py +7 -5
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/dynamic_camera_manager.py +506 -38
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/event_listener.py +2 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/metrics_reporter.py +14 -13
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/streaming_action.py +21 -17
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/streaming_gateway.py +39 -40
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/streaming_gateway_utils.py +9 -7
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/streaming_status_listener.py +2 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76/src}/matrice_streaming.egg-info/PKG-INFO +5 -4
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76/src}/matrice_streaming.egg-info/SOURCES.txt +7 -8
- matrice_streaming-0.1.73/matrice_streaming.egg-info/not-zip-safe +0 -1
- matrice_streaming-0.1.73/setup.py +0 -322
- matrice_streaming-0.1.73/src/matrice_streaming/deployment/todo.txt +0 -1
- matrice_streaming-0.1.73/src/matrice_streaming/streaming_gateway/camera_streamer/ARCHITECTURE.md +0 -324
- matrice_streaming-0.1.73/src/matrice_streaming/streaming_gateway/debug/README.md +0 -486
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/LICENSE.txt +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/README.md +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/setup.cfg +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/__init__.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/client/__init__.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/deployment/__init__.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/py.typed +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/__init__.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/debug/__init__.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/debug/benchmark.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/debug/debug_gstreamer_gateway.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/debug/debug_stream_backend.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/debug/debug_streaming_gateway.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/debug/debug_utils.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/debug/example_debug_streaming.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/streaming_gateway/debug/test_videoplayback.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76/src}/matrice_streaming.egg-info/dependency_links.txt +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76/src}/matrice_streaming.egg-info/top_level.txt +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_async_infrastructure.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_batch_auto_calculation.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_batching_verification.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_e2e_production.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_flatten_binary.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_gstreamer_integration.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_msgpack_fix.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_phase1_unit.py +0 -0
- {matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/tests/test_phase2_scaling.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
|
-
Name:
|
|
3
|
-
Version: 0.1.
|
|
2
|
+
Name: matrice-streaming
|
|
3
|
+
Version: 0.1.76
|
|
4
4
|
Summary: Common server utilities for Matrice.ai services
|
|
5
5
|
Author-email: "Matrice.ai" <dipendra@matrice.ai>
|
|
6
|
-
License
|
|
7
|
-
Keywords: matrice,
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: matrice,streaming,video,utilities
|
|
8
8
|
Classifier: Development Status :: 4 - Beta
|
|
9
9
|
Classifier: Intended Audience :: Developers
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
@@ -12,6 +12,7 @@ Classifier: Operating System :: POSIX :: Linux
|
|
|
12
12
|
Classifier: Operating System :: Microsoft :: Windows
|
|
13
13
|
Classifier: Operating System :: MacOS
|
|
14
14
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
16
|
Classifier: Programming Language :: Python :: 3.8
|
|
16
17
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"versions": {
|
|
3
|
+
"test_pypi_dev": "0.1.69",
|
|
4
|
+
"test_pypi": "0.1.58",
|
|
5
|
+
"pypi": "0.1.76"
|
|
6
|
+
},
|
|
7
|
+
"build": {
|
|
8
|
+
"enable_mypyc": true,
|
|
9
|
+
"python_versions": ["3.8", "3.9", "3.10", "3.11", "3.12"]
|
|
10
|
+
},
|
|
11
|
+
"platforms": {
|
|
12
|
+
"linux_x86_64": true,
|
|
13
|
+
"linux_arm64": false,
|
|
14
|
+
"windows_x64": false,
|
|
15
|
+
"macos_x64": false,
|
|
16
|
+
"macos_arm64": false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = [
|
|
2
|
+
requires = [
|
|
3
|
+
"setuptools>=65.0.0",
|
|
4
|
+
"wheel",
|
|
5
|
+
"mypy[mypyc]>=1.0",
|
|
6
|
+
"types-requests",
|
|
7
|
+
"types-python-dateutil",
|
|
8
|
+
]
|
|
3
9
|
build-backend = "setuptools.build_meta"
|
|
4
10
|
|
|
5
11
|
[project]
|
|
6
|
-
name = "
|
|
12
|
+
name = "matrice-streaming"
|
|
7
13
|
dynamic = ["version"]
|
|
8
14
|
description = "Common server utilities for Matrice.ai services"
|
|
9
15
|
readme = "README.md"
|
|
10
16
|
authors = [{ name = "Matrice.ai", email = "dipendra@matrice.ai" }]
|
|
11
|
-
license = "MIT"
|
|
12
|
-
requires-python = ">=3.8
|
|
13
|
-
keywords = ["matrice", "
|
|
17
|
+
license = {text = "MIT"}
|
|
18
|
+
requires-python = ">=3.8"
|
|
19
|
+
keywords = ["matrice", "streaming", "video", "utilities"]
|
|
14
20
|
classifiers = [
|
|
15
21
|
"Development Status :: 4 - Beta",
|
|
16
22
|
"Intended Audience :: Developers",
|
|
@@ -19,6 +25,7 @@ classifiers = [
|
|
|
19
25
|
"Operating System :: Microsoft :: Windows",
|
|
20
26
|
"Operating System :: MacOS",
|
|
21
27
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
22
29
|
"Programming Language :: Python :: 3.8",
|
|
23
30
|
"Programming Language :: Python :: 3.9",
|
|
24
31
|
"Programming Language :: Python :: 3.10",
|
|
@@ -26,7 +33,16 @@ classifiers = [
|
|
|
26
33
|
"Programming Language :: Python :: 3.12",
|
|
27
34
|
"Typing :: Typed",
|
|
28
35
|
]
|
|
36
|
+
dependencies = []
|
|
37
|
+
|
|
38
|
+
[tool.setuptools]
|
|
39
|
+
package-dir = {"" = "src"}
|
|
29
40
|
|
|
41
|
+
[tool.setuptools.packages.find]
|
|
42
|
+
where = ["src"]
|
|
30
43
|
|
|
31
|
-
|
|
32
|
-
|
|
44
|
+
[tool.mypy]
|
|
45
|
+
follow_imports = "skip"
|
|
46
|
+
ignore_missing_imports = true
|
|
47
|
+
warn_unused_ignores = false
|
|
48
|
+
show_error_codes = true
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Setup script with optional mypyc compilation."""
|
|
2
|
+
import os
|
|
3
|
+
import glob
|
|
4
|
+
from setuptools import setup, find_packages
|
|
5
|
+
from typing import List
|
|
6
|
+
|
|
7
|
+
# =============================================================================
|
|
8
|
+
# CONFIGURATION
|
|
9
|
+
# =============================================================================
|
|
10
|
+
|
|
11
|
+
# Environment variables control build behavior
|
|
12
|
+
ENABLE_MYPYC = os.environ.get("ENABLE_MYPYC", "").lower() in ("true", "1", "yes")
|
|
13
|
+
|
|
14
|
+
# Source directory
|
|
15
|
+
SRC_DIR = "src"
|
|
16
|
+
PACKAGE_NAME = "matrice_streaming"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def get_version() -> str:
|
|
20
|
+
"""Get version from environment or default."""
|
|
21
|
+
return os.environ.get("PACKAGE_VERSION", "0.0.0.dev0")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def discover_modules() -> List[str]:
|
|
25
|
+
"""Discover all Python modules for mypyc compilation."""
|
|
26
|
+
modules = []
|
|
27
|
+
package_dir = os.path.join(SRC_DIR, PACKAGE_NAME)
|
|
28
|
+
|
|
29
|
+
for py_file in glob.glob(f"{package_dir}/**/*.py", recursive=True):
|
|
30
|
+
# Skip __init__.py, test files, and debug files
|
|
31
|
+
basename = os.path.basename(py_file)
|
|
32
|
+
if basename.startswith("_") or "test" in basename.lower():
|
|
33
|
+
continue
|
|
34
|
+
# Skip debug directory (not performance critical)
|
|
35
|
+
if "debug" in py_file.replace("\\", "/"):
|
|
36
|
+
continue
|
|
37
|
+
modules.append(py_file)
|
|
38
|
+
|
|
39
|
+
return modules
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_ext_modules():
|
|
43
|
+
"""Get extension modules for mypyc compilation."""
|
|
44
|
+
if not ENABLE_MYPYC:
|
|
45
|
+
print("=" * 60)
|
|
46
|
+
print("Building PURE PYTHON package (mypyc disabled)")
|
|
47
|
+
print("=" * 60)
|
|
48
|
+
return []
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
from mypyc.build import mypycify
|
|
52
|
+
except ImportError:
|
|
53
|
+
print("WARNING: mypyc not available, building pure Python package")
|
|
54
|
+
return []
|
|
55
|
+
|
|
56
|
+
print("=" * 60)
|
|
57
|
+
print("Building MYPYC COMPILED package")
|
|
58
|
+
print("=" * 60)
|
|
59
|
+
|
|
60
|
+
modules = discover_modules()
|
|
61
|
+
print(f"Compiling {len(modules)} modules with mypyc")
|
|
62
|
+
|
|
63
|
+
mypyc_options = [
|
|
64
|
+
"--follow-imports=skip",
|
|
65
|
+
"--ignore-missing-imports",
|
|
66
|
+
"--disable-error-code=annotation-unchecked",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
return mypycify(mypyc_options + modules, opt_level="3")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# =============================================================================
|
|
73
|
+
# SETUP
|
|
74
|
+
# =============================================================================
|
|
75
|
+
|
|
76
|
+
setup(
|
|
77
|
+
name=PACKAGE_NAME.replace("_", "-"),
|
|
78
|
+
version=get_version(),
|
|
79
|
+
packages=find_packages(where=SRC_DIR),
|
|
80
|
+
package_dir={"": SRC_DIR},
|
|
81
|
+
ext_modules=get_ext_modules(),
|
|
82
|
+
python_requires=">=3.8",
|
|
83
|
+
include_package_data=True,
|
|
84
|
+
package_data={
|
|
85
|
+
PACKAGE_NAME: ["py.typed", "**/*.pyi"],
|
|
86
|
+
},
|
|
87
|
+
)
|
{matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/client/client.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Module providing client functionality."""
|
|
2
|
+
from __future__ import annotations
|
|
2
3
|
|
|
3
4
|
import time
|
|
4
5
|
import logging
|
|
@@ -40,8 +41,8 @@ class MatriceDeployClient:
|
|
|
40
41
|
self,
|
|
41
42
|
session,
|
|
42
43
|
deployment_id: str,
|
|
43
|
-
auth_key: str = None,
|
|
44
|
-
create_deployment_config: Dict = None,
|
|
44
|
+
auth_key: Optional[str] = None,
|
|
45
|
+
create_deployment_config: Optional[Dict] = None,
|
|
45
46
|
):
|
|
46
47
|
"""Initialize MatriceDeployClient.
|
|
47
48
|
|
|
@@ -69,7 +70,7 @@ class MatriceDeployClient:
|
|
|
69
70
|
self.rpc = self.session.rpc
|
|
70
71
|
self.deployment_id = deployment_id
|
|
71
72
|
self.auth_key = auth_key
|
|
72
|
-
self.index_to_category = {}
|
|
73
|
+
self.index_to_category = {} # type: ignore[var-annotated]
|
|
73
74
|
self.last_refresh_time = time.time()
|
|
74
75
|
self.create_deployment_config = create_deployment_config
|
|
75
76
|
|
|
@@ -177,7 +178,7 @@ class MatriceDeployClient:
|
|
|
177
178
|
)
|
|
178
179
|
if wait_for_deployment:
|
|
179
180
|
self.wait_for_deployment(max_wait_time)
|
|
180
|
-
self.__init__(
|
|
181
|
+
self.__init__( # type: ignore[misc]
|
|
181
182
|
session=self.session,
|
|
182
183
|
deployment_id=deployment_id,
|
|
183
184
|
)
|
|
@@ -224,7 +225,7 @@ class MatriceDeployClient:
|
|
|
224
225
|
)
|
|
225
226
|
if resp.get("success"):
|
|
226
227
|
self.auth_key = resp["data"]["key"]
|
|
227
|
-
return self.auth_key
|
|
228
|
+
return self.auth_key # type: ignore[return-value]
|
|
228
229
|
else:
|
|
229
230
|
raise RuntimeError(f"Failed to create auth key: {resp}")
|
|
230
231
|
except Exception as exc:
|
{matrice_streaming-0.1.73 → matrice_streaming-0.1.76}/src/matrice_streaming/client/client_utils.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Module providing client_utils functionality."""
|
|
2
|
+
from __future__ import annotations
|
|
2
3
|
|
|
3
4
|
import json
|
|
4
5
|
import logging
|
|
@@ -15,7 +16,7 @@ import httpx
|
|
|
15
16
|
class ClientUtils:
|
|
16
17
|
"""Utility class for making inference requests to model servers."""
|
|
17
18
|
|
|
18
|
-
def __init__(self, clients: List[Dict] = None):
|
|
19
|
+
def __init__(self, clients: Optional[List[Dict]] = None):
|
|
19
20
|
"""Initialize HTTP clients."""
|
|
20
21
|
self.http_client = httpx.Client(timeout=360, follow_redirects=True)
|
|
21
22
|
self.async_client = httpx.AsyncClient(timeout=360, follow_redirects=True)
|
|
@@ -62,7 +63,7 @@ class ClientUtils:
|
|
|
62
63
|
|
|
63
64
|
def _prepare_request_data(
|
|
64
65
|
self,
|
|
65
|
-
auth_key: str = None,
|
|
66
|
+
auth_key: Optional[str] = None,
|
|
66
67
|
input_path: Optional[str] = None,
|
|
67
68
|
input_bytes: Optional[bytes] = None,
|
|
68
69
|
input_url: Optional[str] = None,
|
|
@@ -96,7 +97,7 @@ class ClientUtils:
|
|
|
96
97
|
if input_path:
|
|
97
98
|
files["input"] = open(input_path, "rb")
|
|
98
99
|
elif input_bytes:
|
|
99
|
-
files["input"] = input_bytes
|
|
100
|
+
files["input"] = input_bytes # type: ignore[assignment]
|
|
100
101
|
|
|
101
102
|
data = {"auth_key": auth_key, "apply_post_processing": str(apply_post_processing).lower()}
|
|
102
103
|
if input_url:
|
|
@@ -302,7 +303,7 @@ class ClientUtils:
|
|
|
302
303
|
|
|
303
304
|
def inference(
|
|
304
305
|
self,
|
|
305
|
-
auth_key: str = None,
|
|
306
|
+
auth_key: Optional[str] = None,
|
|
306
307
|
input_path: Optional[str] = None,
|
|
307
308
|
input_bytes: Optional[bytes] = None,
|
|
308
309
|
input_url: Optional[str] = None,
|
|
@@ -357,7 +358,7 @@ class ClientUtils:
|
|
|
357
358
|
|
|
358
359
|
async def async_inference(
|
|
359
360
|
self,
|
|
360
|
-
auth_key: str = None,
|
|
361
|
+
auth_key: Optional[str] = None,
|
|
361
362
|
input_path: Optional[str] = None,
|
|
362
363
|
input_bytes: Optional[bytes] = None,
|
|
363
364
|
input_url: Optional[str] = None,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Module providing camera manager functionality for deployments."""
|
|
2
|
+
from __future__ import annotations
|
|
2
3
|
|
|
3
4
|
import logging
|
|
4
5
|
from typing import Dict, List, Optional, Tuple
|
|
@@ -77,7 +78,7 @@ class CameraLocationConfig:
|
|
|
77
78
|
if self.account_number:
|
|
78
79
|
data["accountNumber"] = self.account_number
|
|
79
80
|
if self.location_info:
|
|
80
|
-
data["locationInfo"] = self.location_info.to_dict()
|
|
81
|
+
data["locationInfo"] = self.location_info.to_dict() # type: ignore[assignment]
|
|
81
82
|
if self.id:
|
|
82
83
|
data["_id"] = self.id
|
|
83
84
|
|
|
@@ -217,7 +218,7 @@ class CameraGroupConfig:
|
|
|
217
218
|
id=data.get("_id") or data.get("id") or data.get("ID"),
|
|
218
219
|
camera_group_name=data.get("cameraGroupName") or data.get("name") or data.get("Name") or "",
|
|
219
220
|
streaming_gateway_id=data.get("streamingGatewayId") or data.get("idService") or data.get("IDService") or "",
|
|
220
|
-
default_stream_settings=default_settings,
|
|
221
|
+
default_stream_settings=default_settings, # type: ignore[arg-type]
|
|
221
222
|
account_number=data.get("accountNumber"),
|
|
222
223
|
location_id=data.get("locationId"),
|
|
223
224
|
created_at=data.get("createdAt") or data.get("CreatedAt"),
|
|
@@ -283,7 +284,7 @@ class CameraConfig:
|
|
|
283
284
|
if self.simulation_video_path:
|
|
284
285
|
data["simulationVideoPath"] = self.simulation_video_path
|
|
285
286
|
if self.custom_stream_settings:
|
|
286
|
-
data["customStreamSettings"] = self.custom_stream_settings
|
|
287
|
+
data["customStreamSettings"] = self.custom_stream_settings # type: ignore[assignment]
|
|
287
288
|
if self.id:
|
|
288
289
|
data["_id"] = self.id
|
|
289
290
|
|
|
@@ -301,7 +302,7 @@ class CameraConfig:
|
|
|
301
302
|
|
|
302
303
|
instance = cls(
|
|
303
304
|
id=data.get("ID") or data.get("id") or data.get("_id"),
|
|
304
|
-
camera_group_id=camera_group_id,
|
|
305
|
+
camera_group_id=camera_group_id, # type: ignore[arg-type]
|
|
305
306
|
camera_name=data.get("CameraName") or data.get("cameraName") or "",
|
|
306
307
|
protocol_type=data.get("protocolType") or data.get("ProtocolType") or "RTSP",
|
|
307
308
|
camera_feed_path=data.get("cameraFeedPath") or data.get("CameraFeedPath"),
|
|
@@ -351,7 +352,7 @@ class CameraConfig:
|
|
|
351
352
|
}
|
|
352
353
|
|
|
353
354
|
for api_key, attr_name in custom_mapping.items():
|
|
354
|
-
if api_key in self.custom_stream_settings and self.custom_stream_settings[api_key]:
|
|
355
|
+
if self.custom_stream_settings and api_key in self.custom_stream_settings and self.custom_stream_settings[api_key]:
|
|
355
356
|
effective[attr_name] = self.custom_stream_settings[api_key]
|
|
356
357
|
|
|
357
358
|
return StreamSettings(**effective)
|
|
@@ -394,7 +395,7 @@ class Camera:
|
|
|
394
395
|
```
|
|
395
396
|
"""
|
|
396
397
|
|
|
397
|
-
def __init__(self, session, config: CameraConfig = None, camera_id: str = None):
|
|
398
|
+
def __init__(self, session, config: Optional[CameraConfig] = None, camera_id: Optional[str] = None):
|
|
398
399
|
"""
|
|
399
400
|
Initialize a Camera instance.
|
|
400
401
|
|
|
@@ -467,7 +468,7 @@ class Camera:
|
|
|
467
468
|
self.config.camera_group_id = value
|
|
468
469
|
|
|
469
470
|
@property
|
|
470
|
-
def custom_stream_settings(self) -> Dict:
|
|
471
|
+
def custom_stream_settings(self) -> Optional[Dict]:
|
|
471
472
|
"""Get the custom stream settings."""
|
|
472
473
|
return self.config.custom_stream_settings if self.config else {}
|
|
473
474
|
|
|
@@ -492,7 +493,7 @@ class Camera:
|
|
|
492
493
|
error_msg = resp.get("message") if resp else "No response received"
|
|
493
494
|
raise ValueError(f"Failed to load camera: {error_msg}")
|
|
494
495
|
|
|
495
|
-
def save(self, account_number: str = None) -> Tuple[Optional[Dict], Optional[str], str]:
|
|
496
|
+
def save(self, account_number: str = None) -> Tuple[Optional[Dict], Optional[str], str]: # type: ignore[assignment]
|
|
496
497
|
"""
|
|
497
498
|
Save the camera configuration to the backend (create new).
|
|
498
499
|
|
|
@@ -554,7 +555,7 @@ class Camera:
|
|
|
554
555
|
if self.config.simulation_video_path:
|
|
555
556
|
payload["simulationVideoPath"] = self.config.simulation_video_path
|
|
556
557
|
if self.config.custom_stream_settings:
|
|
557
|
-
payload["customStreamSettings"] = self.config.custom_stream_settings
|
|
558
|
+
payload["customStreamSettings"] = self.config.custom_stream_settings # type: ignore[assignment]
|
|
558
559
|
|
|
559
560
|
resp = self.rpc.put(path=path, payload=payload)
|
|
560
561
|
|
|
@@ -588,17 +589,17 @@ class Camera:
|
|
|
588
589
|
|
|
589
590
|
def get_stream_url(self) -> str:
|
|
590
591
|
"""Get the camera stream URL."""
|
|
591
|
-
if not self.config.id:
|
|
592
|
+
if not self.config or not self.config.id:
|
|
592
593
|
return ""
|
|
593
594
|
if self.config.is_stream_url:
|
|
594
|
-
return self.config.stream_url
|
|
595
|
+
return self.config.stream_url or ""
|
|
595
596
|
|
|
596
597
|
resp = self.rpc.get(f"/v1/inference/get_stream_url/{self.config.id}")
|
|
597
598
|
if resp and resp.get("success") and resp.get("data"):
|
|
598
599
|
self.config.stream_url = resp.get("data", {}).get("streamUrl")
|
|
599
600
|
self.config.is_stream_url = True
|
|
600
601
|
|
|
601
|
-
return self.config.stream_url
|
|
602
|
+
return self.config.stream_url or ""
|
|
602
603
|
|
|
603
604
|
def get_effective_stream_settings(
|
|
604
605
|
self, group_defaults: StreamSettings
|
|
@@ -729,7 +730,7 @@ class CameraGroup:
|
|
|
729
730
|
```
|
|
730
731
|
"""
|
|
731
732
|
|
|
732
|
-
def __init__(self, session, config: CameraGroupConfig = None, group_id: str = None):
|
|
733
|
+
def __init__(self, session, config: Optional[CameraGroupConfig] = None, group_id: Optional[str] = None):
|
|
733
734
|
"""
|
|
734
735
|
Initialize a CameraGroup.
|
|
735
736
|
|
|
@@ -743,7 +744,7 @@ class CameraGroup:
|
|
|
743
744
|
|
|
744
745
|
self.session = session
|
|
745
746
|
self.rpc = session.rpc
|
|
746
|
-
self._cameras = [] # Cache for cameras in this group
|
|
747
|
+
self._cameras: list = [] # Cache for cameras in this group
|
|
747
748
|
|
|
748
749
|
if group_id:
|
|
749
750
|
# Load existing group
|
|
@@ -843,7 +844,7 @@ class CameraGroup:
|
|
|
843
844
|
error_msg = resp.get("message") if resp else "No response received"
|
|
844
845
|
raise ValueError(f"Failed to load camera group: {error_msg}")
|
|
845
846
|
|
|
846
|
-
def save(self, account_number: str = None) -> Tuple[Optional[Dict], Optional[str], str]:
|
|
847
|
+
def save(self, account_number: str = None) -> Tuple[Optional[Dict], Optional[str], str]: # type: ignore[assignment]
|
|
847
848
|
"""
|
|
848
849
|
Save the camera group configuration to the backend (create new).
|
|
849
850
|
|
|
@@ -901,9 +902,9 @@ class CameraGroup:
|
|
|
901
902
|
path = f"/v1/inference/update_camera_group/{self.config.id}"
|
|
902
903
|
payload = {
|
|
903
904
|
"cameraGroupName": self.config.camera_group_name,
|
|
904
|
-
"defaultStreamSettings": self.config.default_stream_settings.to_dict()
|
|
905
|
+
"defaultStreamSettings": self.config.default_stream_settings.to_dict() # type: ignore[union-attr]
|
|
905
906
|
}
|
|
906
|
-
|
|
907
|
+
|
|
907
908
|
if self.config.location_id:
|
|
908
909
|
payload["locationId"] = self.config.location_id
|
|
909
910
|
|
|
@@ -978,7 +979,7 @@ class CameraGroup:
|
|
|
978
979
|
return camera_instance, None, message
|
|
979
980
|
|
|
980
981
|
def get_cameras(
|
|
981
|
-
self, page: int = 1, limit: int = 10, search: str = None
|
|
982
|
+
self, page: int = 1, limit: int = 10, search: str = None # type: ignore[assignment]
|
|
982
983
|
) -> Tuple[Optional[List["Camera"]], Optional[str], str]:
|
|
983
984
|
"""
|
|
984
985
|
Get all cameras in this camera group.
|
|
@@ -1159,7 +1160,7 @@ class CameraLocation:
|
|
|
1159
1160
|
```
|
|
1160
1161
|
"""
|
|
1161
1162
|
|
|
1162
|
-
def __init__(self, session, config: CameraLocationConfig = None, location_id: str = None):
|
|
1163
|
+
def __init__(self, session, config: Optional[CameraLocationConfig] = None, location_id: Optional[str] = None):
|
|
1163
1164
|
"""
|
|
1164
1165
|
Initialize a CameraLocation instance.
|
|
1165
1166
|
|
|
@@ -1235,7 +1236,7 @@ class CameraLocation:
|
|
|
1235
1236
|
error_msg = resp.get("message") if resp else "No response received"
|
|
1236
1237
|
raise ValueError(f"Failed to load location: {error_msg}")
|
|
1237
1238
|
|
|
1238
|
-
def save(self, account_number: str = None) -> Tuple[Optional[Dict], Optional[str], str]:
|
|
1239
|
+
def save(self, account_number: str = None) -> Tuple[Optional[Dict], Optional[str], str]: # type: ignore[assignment]
|
|
1239
1240
|
"""
|
|
1240
1241
|
Save the location configuration to the backend (create new).
|
|
1241
1242
|
|
|
@@ -1287,7 +1288,7 @@ class CameraLocation:
|
|
|
1287
1288
|
}
|
|
1288
1289
|
|
|
1289
1290
|
if self.config.location_info:
|
|
1290
|
-
payload["locationInfo"] = self.config.location_info.to_dict()
|
|
1291
|
+
payload["locationInfo"] = self.config.location_info.to_dict() # type: ignore[assignment]
|
|
1291
1292
|
|
|
1292
1293
|
resp = self.rpc.put(path=path, payload=payload)
|
|
1293
1294
|
|
|
@@ -1383,7 +1384,7 @@ class CameraManager:
|
|
|
1383
1384
|
```
|
|
1384
1385
|
"""
|
|
1385
1386
|
|
|
1386
|
-
def __init__(self, session, service_id: str = None, account_number: str = None):
|
|
1387
|
+
def __init__(self, session, service_id: Optional[str] = None, account_number: Optional[str] = None):
|
|
1387
1388
|
"""
|
|
1388
1389
|
Initialize the CameraManager client.
|
|
1389
1390
|
|
|
@@ -1430,7 +1431,7 @@ class CameraManager:
|
|
|
1430
1431
|
location = CameraLocation(self.session, config)
|
|
1431
1432
|
|
|
1432
1433
|
# Save to backend
|
|
1433
|
-
result, error, message = location.save(account_number=self.account_number)
|
|
1434
|
+
result, error, message = location.save(account_number=self.account_number) # type: ignore[arg-type]
|
|
1434
1435
|
|
|
1435
1436
|
if error:
|
|
1436
1437
|
return None, error, message
|
|
@@ -1594,7 +1595,7 @@ class CameraManager:
|
|
|
1594
1595
|
}
|
|
1595
1596
|
|
|
1596
1597
|
if config.location_info:
|
|
1597
|
-
payload["locationInfo"] = config.location_info.to_dict()
|
|
1598
|
+
payload["locationInfo"] = config.location_info.to_dict() # type: ignore[assignment]
|
|
1598
1599
|
|
|
1599
1600
|
resp = self.rpc.put(path=path, payload=payload)
|
|
1600
1601
|
return self.handle_response(
|
|
@@ -1630,10 +1631,10 @@ class CameraManager:
|
|
|
1630
1631
|
topic_name: str,
|
|
1631
1632
|
topic_type: str,
|
|
1632
1633
|
status: str,
|
|
1633
|
-
ip_address: str = None,
|
|
1634
|
-
port: int = None,
|
|
1635
|
-
app_deployment_id: str = None,
|
|
1636
|
-
consuming_app_deployment_ids: List[str] = None
|
|
1634
|
+
ip_address: Optional[str] = None,
|
|
1635
|
+
port: Optional[int] = None,
|
|
1636
|
+
app_deployment_id: Optional[str] = None,
|
|
1637
|
+
consuming_app_deployment_ids: Optional[List[str]] = None
|
|
1637
1638
|
) -> Tuple[Optional[Dict], Optional[str], str]:
|
|
1638
1639
|
"""
|
|
1639
1640
|
Create a camera stream topic.
|
|
@@ -1798,7 +1799,7 @@ class CameraManager:
|
|
|
1798
1799
|
camera_group_instance = CameraGroup(self.session, group)
|
|
1799
1800
|
|
|
1800
1801
|
# Save to backend
|
|
1801
|
-
result, error, message = camera_group_instance.save(account_number=self.account_number)
|
|
1802
|
+
result, error, message = camera_group_instance.save(account_number=self.account_number) # type: ignore[arg-type]
|
|
1802
1803
|
|
|
1803
1804
|
if error:
|
|
1804
1805
|
return None, error, message
|
|
@@ -1827,7 +1828,7 @@ class CameraManager:
|
|
|
1827
1828
|
return None, str(e), "Failed to retrieve camera group"
|
|
1828
1829
|
|
|
1829
1830
|
def get_camera_groups(
|
|
1830
|
-
self, page: int = 1, limit: int = 10
|
|
1831
|
+
self, page: int = 1, limit: int = 10, search: Optional[str] = None
|
|
1831
1832
|
) -> Tuple[Optional[List["CameraGroup"]], Optional[str], str]:
|
|
1832
1833
|
"""
|
|
1833
1834
|
Get all camera groups for the account.
|
|
@@ -1972,9 +1973,9 @@ class CameraManager:
|
|
|
1972
1973
|
path = f"/v1/inference/update_camera_group/{group_id}"
|
|
1973
1974
|
payload = {
|
|
1974
1975
|
"cameraGroupName": group.camera_group_name,
|
|
1975
|
-
"defaultStreamSettings": group.default_stream_settings.to_dict()
|
|
1976
|
+
"defaultStreamSettings": group.default_stream_settings.to_dict() # type: ignore[union-attr]
|
|
1976
1977
|
}
|
|
1977
|
-
|
|
1978
|
+
|
|
1978
1979
|
if group.location_id:
|
|
1979
1980
|
payload["locationId"] = group.location_id
|
|
1980
1981
|
|
|
@@ -2026,10 +2027,10 @@ class CameraManager:
|
|
|
2026
2027
|
camera_instance = Camera(self.session, camera_config)
|
|
2027
2028
|
|
|
2028
2029
|
# Save to backend
|
|
2029
|
-
result, error, message = camera_instance.save(account_number=self.account_number)
|
|
2030
|
+
result, error, message = camera_instance.save(account_number=self.account_number) # type: ignore[arg-type]
|
|
2030
2031
|
|
|
2031
2032
|
if error:
|
|
2032
|
-
return result, error, message
|
|
2033
|
+
return result, error, message # type: ignore[return-value]
|
|
2033
2034
|
|
|
2034
2035
|
return camera_instance, None, message
|
|
2035
2036
|
|
|
@@ -2055,7 +2056,7 @@ class CameraManager:
|
|
|
2055
2056
|
return None, str(e), "Failed to retrieve camera"
|
|
2056
2057
|
|
|
2057
2058
|
def list_camera_configs(
|
|
2058
|
-
self, page: int = 1, limit: int = 10, search: str = None, group_id: str = None
|
|
2059
|
+
self, page: int = 1, limit: int = 10, search: Optional[str] = None, group_id: Optional[str] = None
|
|
2059
2060
|
) -> Tuple[Optional[List[Dict]], Optional[str], str]:
|
|
2060
2061
|
"""
|
|
2061
2062
|
List all camera configs for account (updated to use account-based approach).
|
|
@@ -2069,13 +2070,13 @@ class CameraManager:
|
|
|
2069
2070
|
# Use account-based camera stream endpoint
|
|
2070
2071
|
if group_id:
|
|
2071
2072
|
# Get cameras for specific group using new API
|
|
2072
|
-
return self.get_cameras(group_id=group_id, limit=limit)
|
|
2073
|
+
return self.get_cameras(group_id=group_id, limit=limit) # type: ignore[return-value]
|
|
2073
2074
|
else:
|
|
2074
2075
|
# Get all cameras for account using paginated endpoint
|
|
2075
2076
|
path = f"/v1/inference/all_camera_streams_pag/{self.account_number}"
|
|
2076
2077
|
params = {"page": page, "limit": limit}
|
|
2077
2078
|
if search:
|
|
2078
|
-
params["search"] = search
|
|
2079
|
+
params["search"] = search # type: ignore[assignment]
|
|
2079
2080
|
|
|
2080
2081
|
resp = self.rpc.get(path=path, params=params)
|
|
2081
2082
|
|
|
@@ -2101,7 +2102,7 @@ class CameraManager:
|
|
|
2101
2102
|
return [], None, message
|
|
2102
2103
|
|
|
2103
2104
|
def get_cameras(
|
|
2104
|
-
self, page: int = 1, limit: int = 10, search: str = None, group_id: str = None
|
|
2105
|
+
self, page: int = 1, limit: int = 10, search: Optional[str] = None, group_id: Optional[str] = None
|
|
2105
2106
|
) -> Tuple[Optional[List["Camera"]], Optional[str], str]:
|
|
2106
2107
|
"""
|
|
2107
2108
|
Get all cameras for a specific deployment.
|
|
@@ -2130,7 +2131,7 @@ class CameraManager:
|
|
|
2130
2131
|
return None, error, message
|
|
2131
2132
|
|
|
2132
2133
|
camera_instances = []
|
|
2133
|
-
for config_data in cameras:
|
|
2134
|
+
for config_data in cameras: # type: ignore[union-attr]
|
|
2134
2135
|
try:
|
|
2135
2136
|
camera_config = CameraConfig.from_dict(config_data)
|
|
2136
2137
|
if group_id and camera_config.camera_group_id != group_id:
|
|
@@ -2167,7 +2168,7 @@ class CameraManager:
|
|
|
2167
2168
|
result, error, message = self.handle_response(
|
|
2168
2169
|
resp, "Stream URL retrieved successfully", "Failed to retrieve stream URL"
|
|
2169
2170
|
)
|
|
2170
|
-
return result, error, message
|
|
2171
|
+
return result, error, message # type: ignore[return-value]
|
|
2171
2172
|
|
|
2172
2173
|
def update_camera(
|
|
2173
2174
|
self, camera_id: str, camera_config: CameraConfig
|
|
@@ -2264,7 +2265,7 @@ class CameraManager:
|
|
|
2264
2265
|
# Fallback to direct deletion if Camera object doesn't have delete method
|
|
2265
2266
|
camera_id = getattr(camera, 'id', None)
|
|
2266
2267
|
if camera_id:
|
|
2267
|
-
result, del_error, del_message = self.delete_camera_by_id(camera_id)
|
|
2268
|
+
result, del_error, del_message = self.delete_camera_by_id(camera_id) # type: ignore[attr-defined]
|
|
2268
2269
|
if del_error:
|
|
2269
2270
|
failed_deletions.append(f"Camera {camera_id}: {del_error}")
|
|
2270
2271
|
else:
|
|
@@ -2340,9 +2341,9 @@ class CameraManager:
|
|
|
2340
2341
|
return None, error_msg, "Failed to create any cameras"
|
|
2341
2342
|
else:
|
|
2342
2343
|
# Partial success
|
|
2343
|
-
return created_cameras, error_msg, f"Created {len(created_cameras)} cameras with some failures"
|
|
2344
|
+
return created_cameras, error_msg, f"Created {len(created_cameras)} cameras with some failures" # type: ignore[return-value]
|
|
2344
2345
|
|
|
2345
|
-
return created_cameras, None, f"Successfully created {len(created_cameras)} cameras"
|
|
2346
|
+
return created_cameras, None, f"Successfully created {len(created_cameras)} cameras" # type: ignore[return-value]
|
|
2346
2347
|
|
|
2347
2348
|
def _validate_camera_group(self, group: CameraGroupConfig) -> Tuple[bool, str]:
|
|
2348
2349
|
"""
|
|
@@ -2443,7 +2444,7 @@ class CameraManager:
|
|
|
2443
2444
|
return self.get_camera_by_id(config_id)
|
|
2444
2445
|
|
|
2445
2446
|
def get_camera_configs(
|
|
2446
|
-
self, page: int = 1, limit: int = 10, search: str = None, group_id: str = None
|
|
2447
|
+
self, page: int = 1, limit: int = 10, search: Optional[str] = None, group_id: Optional[str] = None
|
|
2447
2448
|
) -> Tuple[Optional[List["Camera"]], Optional[str], str]:
|
|
2448
2449
|
"""Legacy method - use get_cameras instead."""
|
|
2449
2450
|
return self.get_cameras(page, limit, search, group_id)
|
|
@@ -2482,4 +2483,4 @@ class CameraManager:
|
|
|
2482
2483
|
if error:
|
|
2483
2484
|
return None, error, message
|
|
2484
2485
|
|
|
2485
|
-
return {"cameras": [cam.config.to_dict() for cam in cameras]}, None, message
|
|
2486
|
+
return {"cameras": [cam.config.to_dict() for cam in cameras]}, None, message # type: ignore[union-attr]
|