nedo-vision-worker 1.2.9__py3-none-any.whl → 1.3.0__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.
- nedo_vision_worker/__init__.py +1 -1
- nedo_vision_worker/repositories/PPEDetectionRepository.py +21 -7
- nedo_vision_worker/repositories/RestrictedAreaRepository.py +20 -6
- nedo_vision_worker/worker/DataSenderWorker.py +52 -3
- nedo_vision_worker/worker/PPEDetectionManager.py +31 -3
- nedo_vision_worker/worker/RestrictedAreaManager.py +32 -3
- {nedo_vision_worker-1.2.9.dist-info → nedo_vision_worker-1.3.0.dist-info}/METADATA +1 -1
- {nedo_vision_worker-1.2.9.dist-info → nedo_vision_worker-1.3.0.dist-info}/RECORD +11 -11
- {nedo_vision_worker-1.2.9.dist-info → nedo_vision_worker-1.3.0.dist-info}/WHEEL +0 -0
- {nedo_vision_worker-1.2.9.dist-info → nedo_vision_worker-1.3.0.dist-info}/entry_points.txt +0 -0
- {nedo_vision_worker-1.2.9.dist-info → nedo_vision_worker-1.3.0.dist-info}/top_level.txt +0 -0
nedo_vision_worker/__init__.py
CHANGED
|
@@ -19,19 +19,22 @@ class PPEDetectionRepository:
|
|
|
19
19
|
os.makedirs(self.storage_dir, exist_ok=True)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def
|
|
22
|
+
def get_latest_detections(self, limit: int = 50) -> list:
|
|
23
23
|
"""
|
|
24
|
-
Retrieves the latest
|
|
24
|
+
Retrieves the latest PPE detections ordered by the 'created_at' timestamp.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
limit (int): Maximum number of detections to retrieve. Default is 50.
|
|
25
28
|
|
|
26
29
|
Returns:
|
|
27
|
-
list: A list of
|
|
30
|
+
list: A list of PPE detection dictionaries.
|
|
28
31
|
"""
|
|
29
32
|
try:
|
|
30
33
|
latest_detections = (
|
|
31
34
|
self.session.query(PPEDetectionEntity)
|
|
32
35
|
.options(joinedload(PPEDetectionEntity.ppe_labels))
|
|
33
36
|
.order_by(asc(PPEDetectionEntity.created_at))
|
|
34
|
-
.limit(
|
|
37
|
+
.limit(limit)
|
|
35
38
|
.all()
|
|
36
39
|
)
|
|
37
40
|
|
|
@@ -67,9 +70,22 @@ class PPEDetectionRepository:
|
|
|
67
70
|
|
|
68
71
|
except SQLAlchemyError as e:
|
|
69
72
|
self.session.rollback()
|
|
70
|
-
logging.error(f"❌ Database error while retrieving
|
|
73
|
+
logging.error(f"❌ Database error while retrieving detections: {e}")
|
|
71
74
|
return []
|
|
72
75
|
|
|
76
|
+
def get_total_pending_count(self) -> int:
|
|
77
|
+
"""
|
|
78
|
+
Returns the total count of pending PPE detections in the database.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
int: Total count of pending detections.
|
|
82
|
+
"""
|
|
83
|
+
try:
|
|
84
|
+
return self.session.query(PPEDetectionEntity).count()
|
|
85
|
+
except SQLAlchemyError as e:
|
|
86
|
+
logging.error(f"❌ Error counting pending detections: {e}")
|
|
87
|
+
return 0
|
|
88
|
+
|
|
73
89
|
def delete_records_from_db(self, detection_data: list):
|
|
74
90
|
"""
|
|
75
91
|
Deletes PPE detection records from the database based on detection data.
|
|
@@ -103,7 +119,6 @@ class PPEDetectionRepository:
|
|
|
103
119
|
if os.path.exists(image_path):
|
|
104
120
|
try:
|
|
105
121
|
os.remove(image_path)
|
|
106
|
-
logging.info(f"Deleted image file: {image_path}")
|
|
107
122
|
except OSError as e:
|
|
108
123
|
logging.warning(f"Failed to delete image file {image_path}: {e}")
|
|
109
124
|
else:
|
|
@@ -117,7 +132,6 @@ class PPEDetectionRepository:
|
|
|
117
132
|
if os.path.exists(image_tile_path):
|
|
118
133
|
try:
|
|
119
134
|
os.remove(image_tile_path)
|
|
120
|
-
logging.info(f"Deleted image tile file: {image_tile_path}")
|
|
121
135
|
except OSError as e:
|
|
122
136
|
logging.warning(f"Failed to delete image tile file {image_tile_path}: {e}")
|
|
123
137
|
|
|
@@ -16,9 +16,12 @@ class RestrictedAreaRepository:
|
|
|
16
16
|
self.session: Session = self.db_manager.get_session("default")
|
|
17
17
|
os.makedirs(self.storage_dir, exist_ok=True)
|
|
18
18
|
|
|
19
|
-
def
|
|
19
|
+
def get_latest_violations(self, limit: int = 50) -> list:
|
|
20
20
|
"""
|
|
21
|
-
Retrieves the latest
|
|
21
|
+
Retrieves the latest restricted area violations ordered by the 'created_at' timestamp.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
limit (int): Maximum number of violations to retrieve. Default is 50.
|
|
22
25
|
|
|
23
26
|
Returns:
|
|
24
27
|
list: A list of dictionaries representing restricted area violations.
|
|
@@ -27,7 +30,7 @@ class RestrictedAreaRepository:
|
|
|
27
30
|
latest_violations = (
|
|
28
31
|
self.session.query(RestrictedAreaViolationEntity)
|
|
29
32
|
.order_by(asc(RestrictedAreaViolationEntity.created_at))
|
|
30
|
-
.limit(
|
|
33
|
+
.limit(limit)
|
|
31
34
|
.all()
|
|
32
35
|
)
|
|
33
36
|
|
|
@@ -51,9 +54,22 @@ class RestrictedAreaRepository:
|
|
|
51
54
|
|
|
52
55
|
except SQLAlchemyError as e:
|
|
53
56
|
self.session.rollback()
|
|
54
|
-
logging.error(f"❌ Database error while retrieving
|
|
57
|
+
logging.error(f"❌ Database error while retrieving violations: {e}")
|
|
55
58
|
return []
|
|
56
59
|
|
|
60
|
+
def get_total_pending_count(self) -> int:
|
|
61
|
+
"""
|
|
62
|
+
Returns the total count of pending restricted area violations in the database.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
int: Total count of pending violations.
|
|
66
|
+
"""
|
|
67
|
+
try:
|
|
68
|
+
return self.session.query(RestrictedAreaViolationEntity).count()
|
|
69
|
+
except SQLAlchemyError as e:
|
|
70
|
+
logging.error(f"❌ Error counting pending violations: {e}")
|
|
71
|
+
return 0
|
|
72
|
+
|
|
57
73
|
def delete_records_from_db(self, violation_data: list):
|
|
58
74
|
"""
|
|
59
75
|
Deletes restricted area violation records from the database based on the provided data.
|
|
@@ -81,7 +97,6 @@ class RestrictedAreaRepository:
|
|
|
81
97
|
if os.path.exists(image_path):
|
|
82
98
|
try:
|
|
83
99
|
os.remove(image_path)
|
|
84
|
-
logging.info(f"Deleted image file: {image_path}")
|
|
85
100
|
except OSError as e:
|
|
86
101
|
logging.warning(f"Failed to delete image file {image_path}: {e}")
|
|
87
102
|
else:
|
|
@@ -95,7 +110,6 @@ class RestrictedAreaRepository:
|
|
|
95
110
|
if os.path.exists(image_tile_path):
|
|
96
111
|
try:
|
|
97
112
|
os.remove(image_tile_path)
|
|
98
|
-
logging.info(f"Deleted image tile file: {image_tile_path}")
|
|
99
113
|
except OSError as e:
|
|
100
114
|
logging.warning(f"Failed to delete image tile file {image_tile_path}: {e}")
|
|
101
115
|
|
|
@@ -118,14 +118,63 @@ class DataSenderWorker:
|
|
|
118
118
|
try:
|
|
119
119
|
while not self.stop_event.is_set():
|
|
120
120
|
self.system_usage_manager.process_system_usage()
|
|
121
|
-
|
|
122
|
-
self.
|
|
121
|
+
|
|
122
|
+
ppe_pending = self._send_with_adaptive_interval(
|
|
123
|
+
self.ppe_detection_manager.send_ppe_detection_batch,
|
|
124
|
+
self.ppe_detection_manager.ppe_detection_repo.get_total_pending_count
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
violation_pending = self._send_with_adaptive_interval(
|
|
128
|
+
self.restricted_area_manager.send_violation_batch,
|
|
129
|
+
self.restricted_area_manager.repo.get_total_pending_count
|
|
130
|
+
)
|
|
131
|
+
|
|
123
132
|
self._process_image_upload()
|
|
124
133
|
self._process_dataset_frames()
|
|
125
|
-
|
|
134
|
+
|
|
135
|
+
sleep_time = self._calculate_sleep_interval(ppe_pending, violation_pending)
|
|
136
|
+
if sleep_time < self.send_interval and (ppe_pending + violation_pending) > 0:
|
|
137
|
+
logger.debug(f"⚡ [APP] Catch-up mode: {ppe_pending + violation_pending} pending, sleeping {sleep_time}s")
|
|
138
|
+
time.sleep(sleep_time)
|
|
126
139
|
except Exception as e:
|
|
127
140
|
logger.error("🚨 [APP] Unexpected error in main worker loop.", exc_info=True)
|
|
128
141
|
|
|
142
|
+
def _send_with_adaptive_interval(self, send_func, count_func):
|
|
143
|
+
"""Send data with adaptive interval based on backlog."""
|
|
144
|
+
try:
|
|
145
|
+
pending = count_func()
|
|
146
|
+
if pending > 0:
|
|
147
|
+
send_func()
|
|
148
|
+
return pending
|
|
149
|
+
except Exception as e:
|
|
150
|
+
logger.error(f"🚨 [APP] Error in adaptive sending: {e}", exc_info=True)
|
|
151
|
+
return 0
|
|
152
|
+
|
|
153
|
+
def _calculate_sleep_interval(self, ppe_pending: int, violation_pending: int) -> float:
|
|
154
|
+
"""
|
|
155
|
+
Calculate optimal sleep interval based on pending data.
|
|
156
|
+
Conservative approach to prevent server overload.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
ppe_pending: Number of pending PPE detections
|
|
160
|
+
violation_pending: Number of pending violations
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
float: Sleep interval in seconds
|
|
164
|
+
"""
|
|
165
|
+
total_pending = ppe_pending + violation_pending
|
|
166
|
+
|
|
167
|
+
if total_pending == 0:
|
|
168
|
+
return self.send_interval
|
|
169
|
+
elif total_pending < 50:
|
|
170
|
+
return self.send_interval
|
|
171
|
+
elif total_pending < 200:
|
|
172
|
+
return 3.0
|
|
173
|
+
elif total_pending < 500:
|
|
174
|
+
return 2.0
|
|
175
|
+
else:
|
|
176
|
+
return 1.5
|
|
177
|
+
|
|
129
178
|
def _run_worker_source_updater(self):
|
|
130
179
|
"""Dedicated loop for updating worker sources at a different interval."""
|
|
131
180
|
try:
|
|
@@ -50,14 +50,42 @@ class PPEDetectionManager:
|
|
|
50
50
|
|
|
51
51
|
logger.info("📡 [APP] PPE detection monitoring started.")
|
|
52
52
|
|
|
53
|
+
def _calculate_batch_size(self, pending_count: int) -> int:
|
|
54
|
+
"""
|
|
55
|
+
Calculates optimal batch size based on pending items.
|
|
56
|
+
Conservative limits to prevent server overload.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
pending_count (int): Number of pending detections
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
int: Optimal batch size
|
|
63
|
+
"""
|
|
64
|
+
if pending_count < 20:
|
|
65
|
+
return 10
|
|
66
|
+
elif pending_count < 100:
|
|
67
|
+
return 30
|
|
68
|
+
elif pending_count < 500:
|
|
69
|
+
return 50
|
|
70
|
+
else:
|
|
71
|
+
return 100
|
|
53
72
|
|
|
54
73
|
def send_ppe_detection_batch(self):
|
|
55
|
-
"""Sends a batch of collected PPE detection data to the server."""
|
|
74
|
+
"""Sends a batch of collected PPE detection data to the server with dynamic batch sizing."""
|
|
56
75
|
try:
|
|
57
|
-
|
|
76
|
+
pending_count = self.ppe_detection_repo.get_total_pending_count()
|
|
77
|
+
|
|
78
|
+
if pending_count == 0:
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
batch_size = self._calculate_batch_size(pending_count)
|
|
82
|
+
self.ppe_detection_data = self.ppe_detection_repo.get_latest_detections(batch_size)
|
|
83
|
+
|
|
58
84
|
if not self.ppe_detection_data:
|
|
59
85
|
return
|
|
60
86
|
|
|
87
|
+
logger.info(f"📤 [APP] Sending {len(self.ppe_detection_data)} PPE detections ({pending_count} pending)")
|
|
88
|
+
|
|
61
89
|
response = self.ppe_detection_client.send_upsert_batch(
|
|
62
90
|
worker_id=self.worker_id,
|
|
63
91
|
worker_source_id=self.worker_source_id,
|
|
@@ -66,7 +94,7 @@ class PPEDetectionManager:
|
|
|
66
94
|
)
|
|
67
95
|
|
|
68
96
|
if response.get("success"):
|
|
69
|
-
logger.info("✅ [APP] Successfully sent PPE
|
|
97
|
+
logger.info(f"✅ [APP] Successfully sent {len(self.ppe_detection_data)} PPE detections")
|
|
70
98
|
self.ppe_detection_data.clear()
|
|
71
99
|
else:
|
|
72
100
|
logger.error(f"❌ [APP] Failed to send PPE detection batch: {response.get('message')}")
|
|
@@ -50,13 +50,42 @@ class RestrictedAreaManager:
|
|
|
50
50
|
|
|
51
51
|
logger.info("📡 [APP] Restricted area violation monitoring started.")
|
|
52
52
|
|
|
53
|
+
def _calculate_batch_size(self, pending_count: int) -> int:
|
|
54
|
+
"""
|
|
55
|
+
Calculates optimal batch size based on pending items.
|
|
56
|
+
Conservative limits to prevent server overload.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
pending_count (int): Number of pending violations
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
int: Optimal batch size
|
|
63
|
+
"""
|
|
64
|
+
if pending_count < 20:
|
|
65
|
+
return 10
|
|
66
|
+
elif pending_count < 100:
|
|
67
|
+
return 30
|
|
68
|
+
elif pending_count < 500:
|
|
69
|
+
return 50
|
|
70
|
+
else:
|
|
71
|
+
return 100
|
|
72
|
+
|
|
53
73
|
def send_violation_batch(self):
|
|
54
|
-
"""Sends a batch of collected violation data to the server."""
|
|
74
|
+
"""Sends a batch of collected violation data to the server with dynamic batch sizing."""
|
|
55
75
|
try:
|
|
56
|
-
|
|
76
|
+
pending_count = self.repo.get_total_pending_count()
|
|
77
|
+
|
|
78
|
+
if pending_count == 0:
|
|
79
|
+
return
|
|
80
|
+
|
|
81
|
+
batch_size = self._calculate_batch_size(pending_count)
|
|
82
|
+
self.violations_data = self.repo.get_latest_violations(batch_size)
|
|
83
|
+
|
|
57
84
|
if not self.violations_data:
|
|
58
85
|
return
|
|
59
86
|
|
|
87
|
+
logger.info(f"📤 [APP] Sending {len(self.violations_data)} violations ({pending_count} pending)")
|
|
88
|
+
|
|
60
89
|
response = self.client.send_upsert_batch(
|
|
61
90
|
worker_id=self.worker_id,
|
|
62
91
|
worker_source_id=self.worker_source_id,
|
|
@@ -65,7 +94,7 @@ class RestrictedAreaManager:
|
|
|
65
94
|
)
|
|
66
95
|
|
|
67
96
|
if response.get("success"):
|
|
68
|
-
logger.info("✅ [APP] Successfully sent
|
|
97
|
+
logger.info(f"✅ [APP] Successfully sent {len(self.violations_data)} violations")
|
|
69
98
|
self.violations_data.clear()
|
|
70
99
|
else:
|
|
71
100
|
logger.error(f"❌ [APP] Failed to send restricted area violation batch: {response.get('message')}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nedo-vision-worker
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Nedo Vision Worker Service Library for AI Vision Processing
|
|
5
5
|
Author-email: Willy Achmat Fauzi <willy.achmat@gmail.com>
|
|
6
6
|
Maintainer-email: Willy Achmat Fauzi <willy.achmat@gmail.com>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
nedo_vision_worker/__init__.py,sha256=
|
|
1
|
+
nedo_vision_worker/__init__.py,sha256=lM4SwuHDgc4TdI91GAS_FS--pQKK2RFKliCp8sJY1-o,203
|
|
2
2
|
nedo_vision_worker/cli.py,sha256=ddWspJmSgVkcUYvRdkvTtMNuMTDvNCqLLuMVU9KE3Ik,7457
|
|
3
3
|
nedo_vision_worker/doctor.py,sha256=wNkpe8gLVd76Y_ViyK2h1ZFdqeSl37MnzZN5frWKu30,48410
|
|
4
4
|
nedo_vision_worker/worker_service.py,sha256=9zz8hKwDwqwpfS0KPQfftGJtRci0uj_wiwcr_TGf-E0,11039
|
|
@@ -40,8 +40,8 @@ nedo_vision_worker/protos/WorkerSourceService_pb2_grpc.py,sha256=23Zj3WSogfhmp_Y
|
|
|
40
40
|
nedo_vision_worker/protos/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
|
41
41
|
nedo_vision_worker/repositories/AIModelRepository.py,sha256=35cQ2EnJvMdArewumPrVIaiwueGy6cXU_g5J1Qcj6_Y,1415
|
|
42
42
|
nedo_vision_worker/repositories/DatasetSourceRepository.py,sha256=MOUbXY1-7WUPhY15aMpdXl6rl0afSvu3Cq8jNtp9nzM,8595
|
|
43
|
-
nedo_vision_worker/repositories/PPEDetectionRepository.py,sha256=
|
|
44
|
-
nedo_vision_worker/repositories/RestrictedAreaRepository.py,sha256=
|
|
43
|
+
nedo_vision_worker/repositories/PPEDetectionRepository.py,sha256=WYPrmMs3wSsaALR4ixsgMNOUbHbmYDGPbjMQdjSnIE4,6161
|
|
44
|
+
nedo_vision_worker/repositories/RestrictedAreaRepository.py,sha256=nk8DV5dkBfAm2AT8wY9la6yv6Q7pFi00YXLbvofqNkc,5158
|
|
45
45
|
nedo_vision_worker/repositories/WorkerSourcePipelineDebugRepository.py,sha256=kOlVEnPOoDRZdZIm8uWXlc89GMvBPI-36QyKecX7ucE,3350
|
|
46
46
|
nedo_vision_worker/repositories/WorkerSourcePipelineDetectionRepository.py,sha256=cbgg_7p0eNUIgCHoPDZBaRZ1b2Y68p_dfSxpvuGMtRE,1773
|
|
47
47
|
nedo_vision_worker/repositories/WorkerSourcePipelineRepository.py,sha256=xfmEvgnyt-DdfSApGyFfy0H0dXjFFkjeo4LMr0fVFXU,10053
|
|
@@ -80,22 +80,22 @@ nedo_vision_worker/util/SystemMonitor.py,sha256=2kkqj9mOlywAS2fHdN1TaIXSXvCApcIH
|
|
|
80
80
|
nedo_vision_worker/util/VideoProbeUtil.py,sha256=cF-vJ7hIDlXfEJby2a0s9tqwkPGVz_6B3Vv4D5pMmIw,12876
|
|
81
81
|
nedo_vision_worker/util/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
|
82
82
|
nedo_vision_worker/worker/CoreActionWorker.py,sha256=lb7zPY3yui6I3F4rX4Ii7JwpWZahLEO72rh3iWOgFmg,5441
|
|
83
|
-
nedo_vision_worker/worker/DataSenderWorker.py,sha256=
|
|
83
|
+
nedo_vision_worker/worker/DataSenderWorker.py,sha256=BNA5mL2guBVp0O5MKULEWd78dY32YjiyWZX7ECFjVFc,9089
|
|
84
84
|
nedo_vision_worker/worker/DataSyncWorker.py,sha256=LmDPt2J1frmXwuR46L6b0MjlFOHfgG-4_0MGQa78zF4,6288
|
|
85
85
|
nedo_vision_worker/worker/DatasetFrameSender.py,sha256=1SFYj8LJFNi-anBTapsbq8U_NGMM7mnoMKg9NeFAHys,8087
|
|
86
86
|
nedo_vision_worker/worker/DatasetFrameWorker.py,sha256=Hh_wZuMjwovxsEKFqXSuTRin9eYRBZCbcFKm3CKLMbE,19335
|
|
87
|
-
nedo_vision_worker/worker/PPEDetectionManager.py,sha256=
|
|
87
|
+
nedo_vision_worker/worker/PPEDetectionManager.py,sha256=sO0ygzUKNNkUsrv-QJk9b-r9QnTw80VsniD5--OQJi0,4569
|
|
88
88
|
nedo_vision_worker/worker/PipelineActionWorker.py,sha256=xgvryjKtEsMj4BKqWzDIaK_lFny-DfMCj5Y2DxHnWww,5651
|
|
89
89
|
nedo_vision_worker/worker/PipelineImageWorker.py,sha256=J8VBUG0cwcH3qOJp2zTl30B-XhmPFyvJLjxitKJYq0E,5642
|
|
90
90
|
nedo_vision_worker/worker/PipelinePreviewWorker.py,sha256=owFiBbktcOZkdImQeykZSeBIR2-mpt6HNkmYIkLRKzE,6397
|
|
91
91
|
nedo_vision_worker/worker/RabbitMQListener.py,sha256=9gR49MDplgpyb-D5HOH0K77-DJQFvhS2E7biL92SjSU,6950
|
|
92
|
-
nedo_vision_worker/worker/RestrictedAreaManager.py,sha256=
|
|
92
|
+
nedo_vision_worker/worker/RestrictedAreaManager.py,sha256=Y739KzbPzm2UF1a9oT3YEk7trfKqQjGUQ6MTwEDMkj4,4463
|
|
93
93
|
nedo_vision_worker/worker/SystemUsageManager.py,sha256=mkh4sT-HkIEY1CJHMEG6LP9ATu39YXvLRLyf995OkoQ,5315
|
|
94
94
|
nedo_vision_worker/worker/VideoStreamWorker.py,sha256=5n6v1PNO7IB-jj_McALLkUP-cBjJoIEw4UiSAs3vTb0,7606
|
|
95
95
|
nedo_vision_worker/worker/WorkerManager.py,sha256=2bxXi19fp3p1qjYBStYRdVVgko8dnevXx1_M_sqH5og,5521
|
|
96
96
|
nedo_vision_worker/worker/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
|
97
|
-
nedo_vision_worker-1.
|
|
98
|
-
nedo_vision_worker-1.
|
|
99
|
-
nedo_vision_worker-1.
|
|
100
|
-
nedo_vision_worker-1.
|
|
101
|
-
nedo_vision_worker-1.
|
|
97
|
+
nedo_vision_worker-1.3.0.dist-info/METADATA,sha256=MiQg-EA4V0jEqMkrupbyhwLvIDD1UfTpQ_cub90gh8E,14728
|
|
98
|
+
nedo_vision_worker-1.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
99
|
+
nedo_vision_worker-1.3.0.dist-info/entry_points.txt,sha256=LrglS-8nCi8C_PL_pa6uxdgCe879hBETHDVXAckvs-8,60
|
|
100
|
+
nedo_vision_worker-1.3.0.dist-info/top_level.txt,sha256=vgilhlkyD34YsEKkaBabmhIpcKSvF3XpzD2By68L-XI,19
|
|
101
|
+
nedo_vision_worker-1.3.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|