nedo-vision-worker 1.2.8__py3-none-any.whl → 1.2.9__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.
@@ -6,5 +6,5 @@ A library for running worker agents in the Nedo Vision platform.
6
6
 
7
7
  from .worker_service import WorkerService
8
8
 
9
- __version__ = "1.2.8"
9
+ __version__ = "1.2.9"
10
10
  __all__ = ["WorkerService"]
@@ -77,6 +77,10 @@ class PPEDetectionRepository:
77
77
  Args:
78
78
  detection_data (list): List of dictionaries containing the detection data.
79
79
  """
80
+ if not detection_data:
81
+ logging.info("No detection data provided for deletion.")
82
+ return
83
+
80
84
  try:
81
85
  # Extract person_id from detection data to delete the corresponding records
82
86
  person_ids_to_delete = [data['person_id'] for data in detection_data]
@@ -97,10 +101,25 @@ class PPEDetectionRepository:
97
101
  if not os.path.isabs(image_path):
98
102
  image_path = str(get_storage_path("files") / Path(image_path).relative_to("data/files"))
99
103
  if os.path.exists(image_path):
100
- os.remove(image_path)
101
- logging.info(f"Deleted image file: {image_path}")
104
+ try:
105
+ os.remove(image_path)
106
+ logging.info(f"Deleted image file: {image_path}")
107
+ except OSError as e:
108
+ logging.warning(f"Failed to delete image file {image_path}: {e}")
102
109
  else:
103
110
  logging.warning(f"Image file not found for detection {detection.id}: {image_path}")
111
+
112
+ # Delete the image tile file if it exists
113
+ image_tile_path = detection.image_tile_path
114
+ if image_tile_path:
115
+ if not os.path.isabs(image_tile_path):
116
+ image_tile_path = str(get_storage_path("files") / Path(image_tile_path).relative_to("data/files"))
117
+ if os.path.exists(image_tile_path):
118
+ try:
119
+ os.remove(image_tile_path)
120
+ logging.info(f"Deleted image tile file: {image_tile_path}")
121
+ except OSError as e:
122
+ logging.warning(f"Failed to delete image tile file {image_tile_path}: {e}")
104
123
 
105
124
  # Delete the detection record
106
125
  self.session.delete(detection)
@@ -61,6 +61,10 @@ class RestrictedAreaRepository:
61
61
  Args:
62
62
  violation_data (list): List of dictionaries containing the violation data.
63
63
  """
64
+ if not violation_data:
65
+ logging.info("No violation data provided for deletion.")
66
+ return
67
+
64
68
  try:
65
69
  person_ids_to_delete = [data['person_id'] for data in violation_data]
66
70
 
@@ -75,11 +79,26 @@ class RestrictedAreaRepository:
75
79
  if not os.path.isabs(image_path):
76
80
  image_path = str(get_storage_path("restricted_violations") / Path(image_path).relative_to("data/restricted_violations"))
77
81
  if os.path.exists(image_path):
78
- os.remove(image_path)
79
- logging.info(f"Deleted image file: {image_path}")
82
+ try:
83
+ os.remove(image_path)
84
+ logging.info(f"Deleted image file: {image_path}")
85
+ except OSError as e:
86
+ logging.warning(f"Failed to delete image file {image_path}: {e}")
80
87
  else:
81
88
  logging.warning(f"Image file not found for violation {violation.id}: {image_path}")
82
89
 
90
+ # Delete the image tile file if it exists
91
+ image_tile_path = violation.image_tile_path
92
+ if image_tile_path:
93
+ if not os.path.isabs(image_tile_path):
94
+ image_tile_path = str(get_storage_path("restricted_violations") / Path(image_tile_path).relative_to("data/restricted_violations"))
95
+ if os.path.exists(image_tile_path):
96
+ try:
97
+ os.remove(image_tile_path)
98
+ logging.info(f"Deleted image tile file: {image_tile_path}")
99
+ except OSError as e:
100
+ logging.warning(f"Failed to delete image tile file {image_tile_path}: {e}")
101
+
83
102
  self.session.delete(violation)
84
103
 
85
104
  self.session.commit()
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import os
2
3
  from .GrpcClientBase import GrpcClientBase
3
4
  from ..protos.PPEDetectionService_pb2_grpc import PPEDetectionGRPCServiceStub
4
5
  from ..protos.PPEDetectionService_pb2 import UpsertPPEDetectionBatchRequest, UpsertPPEDetectionRequest, PPEDetectionLabelRequest
@@ -56,11 +57,23 @@ class PPEDetectionClient(GrpcClientBase):
56
57
  return {"success": False, "message": "gRPC connection is not established."}
57
58
 
58
59
  try:
59
- # Prepare the list of UpsertPPEDetectionRequest messages
60
60
  ppe_detection_requests = []
61
+ valid_records = []
62
+ invalid_records = []
63
+
61
64
  for data in detection_data:
62
- image_binary = self.read_image_as_binary(data['image'])
63
- image_tile_binary = self.read_image_as_binary(data['image_tile'])
65
+ if not os.path.exists(data['image']) or not os.path.exists(data['image_tile']):
66
+ logger.warning(f"⚠️ Missing image files for person_id {data.get('person_id')}")
67
+ invalid_records.append(data)
68
+ continue
69
+
70
+ try:
71
+ image_binary = self.read_image_as_binary(data['image'])
72
+ image_tile_binary = self.read_image_as_binary(data['image_tile'])
73
+ except Exception as e:
74
+ logger.error(f"❌ Error reading images for person_id {data.get('person_id')}: {e}")
75
+ invalid_records.append(data)
76
+ continue
64
77
 
65
78
  ppe_detection_labels = [
66
79
  PPEDetectionLabelRequest(
@@ -73,11 +86,11 @@ class PPEDetectionClient(GrpcClientBase):
73
86
  )
74
87
  for label in data['ppe_detection_labels']
75
88
  ]
76
- source = data['worker_source_id']
89
+
77
90
  request = UpsertPPEDetectionRequest(
78
91
  person_id=data['person_id'],
79
92
  worker_id=worker_id,
80
- worker_source_id=source,
93
+ worker_source_id=data['worker_source_id'],
81
94
  image=image_binary,
82
95
  image_tile=image_tile_binary,
83
96
  worker_timestamp=data['worker_timestamp'],
@@ -85,18 +98,24 @@ class PPEDetectionClient(GrpcClientBase):
85
98
  token=token
86
99
  )
87
100
  ppe_detection_requests.append(request)
101
+ valid_records.append(data)
102
+
103
+ if invalid_records:
104
+ logger.info(f"🧹 Deleting {len(invalid_records)} invalid PPE detection records")
105
+ self.repository.delete_records_from_db(invalid_records)
106
+
107
+ if not ppe_detection_requests:
108
+ return {"success": True, "message": "No valid detections to send"}
88
109
 
89
- # Create the UpsertPPEDetectionBatchRequest
90
110
  batch_request = UpsertPPEDetectionBatchRequest(
91
111
  ppe_detection_requests=ppe_detection_requests,
92
112
  token=token
93
113
  )
94
114
 
95
- # Call the UpsertBatch RPC
96
115
  response = self.handle_rpc(self.stub.UpsertBatch, batch_request)
97
116
 
98
117
  if response and response.success:
99
- self.repository.delete_records_from_db(detection_data)
118
+ self.repository.delete_records_from_db(valid_records)
100
119
  return {"success": True, "message": response.message}
101
120
 
102
121
  return {"success": False, "message": response.message if response else "Unknown error"}
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import os
2
3
  from ..repositories.RestrictedAreaRepository import RestrictedAreaRepository
3
4
  from .GrpcClientBase import GrpcClientBase
4
5
  from ..protos.HumanDetectionService_pb2_grpc import HumanDetectionGRPCServiceStub
@@ -60,10 +61,22 @@ class RestrictedAreaClient(GrpcClientBase):
60
61
 
61
62
  try:
62
63
  human_detection_requests = []
64
+ valid_records = []
65
+ invalid_records = []
63
66
 
64
67
  for data in violation_data:
65
- image_binary = self.read_image_as_binary(data['image'])
66
- image_tile_binary = self.read_image_as_binary(data['image_tile'])
68
+ if not os.path.exists(data['image']) or not os.path.exists(data['image_tile']):
69
+ logger.warning(f"⚠️ Missing image files for person_id {data.get('person_id')}")
70
+ invalid_records.append(data)
71
+ continue
72
+
73
+ try:
74
+ image_binary = self.read_image_as_binary(data['image'])
75
+ image_tile_binary = self.read_image_as_binary(data['image_tile'])
76
+ except Exception as e:
77
+ logger.error(f"❌ Error reading images for person_id {data.get('person_id')}: {e}")
78
+ invalid_records.append(data)
79
+ continue
67
80
 
68
81
  request = UpsertHumanDetectionRequest(
69
82
  person_id=data['person_id'],
@@ -81,6 +94,14 @@ class RestrictedAreaClient(GrpcClientBase):
81
94
  )
82
95
 
83
96
  human_detection_requests.append(request)
97
+ valid_records.append(data)
98
+
99
+ if invalid_records:
100
+ logger.info(f"🧹 Deleting {len(invalid_records)} invalid violation records")
101
+ self.repository.delete_records_from_db(invalid_records)
102
+
103
+ if not human_detection_requests:
104
+ return {"success": True, "message": "No valid violations to send"}
84
105
 
85
106
  batch_request = UpsertHumanDetectionBatchRequest(
86
107
  human_detection_requests=human_detection_requests,
@@ -90,7 +111,7 @@ class RestrictedAreaClient(GrpcClientBase):
90
111
  response = self.handle_rpc(self.stub.UpsertBatch, batch_request)
91
112
 
92
113
  if response and response.success:
93
- self.repository.delete_records_from_db(violation_data)
114
+ self.repository.delete_records_from_db(valid_records)
94
115
  return {"success": True, "message": response.message}
95
116
 
96
117
  return {"success": False, "message": response.message if response else "Unknown error"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nedo-vision-worker
3
- Version: 1.2.8
3
+ Version: 1.2.9
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=RU8uEjcEodK2R_F4Fg2qBYmhhJpvf-vQBA-Cjo9Dvf8,203
1
+ nedo_vision_worker/__init__.py,sha256=oLzUhGDH-bezYa_Smc3pWfjWYzwQGUZ0LiTwVuu5AYA,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=oyQjIRyfa0pA-ErVtrKkCLMY521QIbz9ZqSXotC8nqY,4766
44
- nedo_vision_worker/repositories/RestrictedAreaRepository.py,sha256=y3n2ZfQbth1I_IjVYaT38qpRINQQC_dKeTf0yHPFNjw,3724
43
+ nedo_vision_worker/repositories/PPEDetectionRepository.py,sha256=s4iCaTNYoJJgGr9ojWgoj6wtUQYFbloxSpnuntX26yw,5792
44
+ nedo_vision_worker/repositories/RestrictedAreaRepository.py,sha256=XudFBscLCXCheUTAPC_CbwBkJMn2uIx2HCnU0NH4riE,4766
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
@@ -56,9 +56,9 @@ nedo_vision_worker/services/GrpcClientBase.py,sha256=hPyxOGw3aGSW1FhmY3wp3Iq8U1M
56
56
  nedo_vision_worker/services/GrpcClientManager.py,sha256=DLXekmxlQogLo8V9-TNDXtyHT_UG-BaggqwsIups55k,5568
57
57
  nedo_vision_worker/services/GrpcConnection.py,sha256=UNjaUC4ZcXuteHQx8AAAL5ymYkT1OpoIvyCYPUc3tCI,4915
58
58
  nedo_vision_worker/services/ImageUploadClient.py,sha256=T353YsRfm74G7Mh-eWr5nvdQHXTfpKwHJFmNW8HyjT8,3019
59
- nedo_vision_worker/services/PPEDetectionClient.py,sha256=CC-b0LRAgrftfIKp6TFKpeBkTYefe-C6Z1oz_X3HArQ,4345
59
+ nedo_vision_worker/services/PPEDetectionClient.py,sha256=3oE_Y0Avw_kcWKgTA7qmChq32woW7JerWefrCxllUYU,5172
60
60
  nedo_vision_worker/services/RTSPtoRTMPStreamer.py,sha256=LtfrWDHNcm-Ky6nZLnFCF8xgqIm7VQmsWIenK2yKNfo,3804
61
- nedo_vision_worker/services/RestrictedAreaClient.py,sha256=AE9SOcVQca4zn5V96boho56EgN5BCIpV-8grvFBBnGo,3853
61
+ nedo_vision_worker/services/RestrictedAreaClient.py,sha256=TD2Y5UJ0NjXgNFNgwS5ze4P-5jWwgrP0j0Nlyyd7-6Q,4844
62
62
  nedo_vision_worker/services/SharedDirectDeviceClient.py,sha256=dylMhqpMsfK_UKLWIVL-ApJRP4g-NCP_55xvlGYBiwo,10760
63
63
  nedo_vision_worker/services/SharedVideoStreamServer.py,sha256=WMKVxkzMoyfbgYiJ0fQOT-Ujz9btz6FLlaDP738yfoY,11601
64
64
  nedo_vision_worker/services/SystemUsageClient.py,sha256=Yf77dooQeNh6CDL5FkWVrX9543OVz1wc3exCAg6GlWw,3273
@@ -94,8 +94,8 @@ nedo_vision_worker/worker/SystemUsageManager.py,sha256=mkh4sT-HkIEY1CJHMEG6LP9AT
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.2.8.dist-info/METADATA,sha256=7MmzgVArAQxzCvxpcCr-LzPrFa0prCfOkaYCPLkmH_0,14728
98
- nedo_vision_worker-1.2.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
99
- nedo_vision_worker-1.2.8.dist-info/entry_points.txt,sha256=LrglS-8nCi8C_PL_pa6uxdgCe879hBETHDVXAckvs-8,60
100
- nedo_vision_worker-1.2.8.dist-info/top_level.txt,sha256=vgilhlkyD34YsEKkaBabmhIpcKSvF3XpzD2By68L-XI,19
101
- nedo_vision_worker-1.2.8.dist-info/RECORD,,
97
+ nedo_vision_worker-1.2.9.dist-info/METADATA,sha256=ySyI3I8lzUmhonotTgOrhH2Tt-AxL_l9oYifd_qaHcU,14728
98
+ nedo_vision_worker-1.2.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
99
+ nedo_vision_worker-1.2.9.dist-info/entry_points.txt,sha256=LrglS-8nCi8C_PL_pa6uxdgCe879hBETHDVXAckvs-8,60
100
+ nedo_vision_worker-1.2.9.dist-info/top_level.txt,sha256=vgilhlkyD34YsEKkaBabmhIpcKSvF3XpzD2By68L-XI,19
101
+ nedo_vision_worker-1.2.9.dist-info/RECORD,,