isar 1.19.0__py3-none-any.whl → 1.19.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of isar might be problematic. Click here for more details.

isar/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
- from pkg_resources import DistributionNotFound, get_distribution
1
+ from importlib.metadata import PackageNotFoundError, distribution
2
2
 
3
3
  try:
4
- __version__ = get_distribution(__name__).version
5
- except DistributionNotFound:
4
+ __version__ = distribution(__name__).version
5
+ except PackageNotFoundError:
6
6
  pass # package is not installed
isar/config/log.py CHANGED
@@ -1,6 +1,6 @@
1
- import importlib.resources as pkg_resources
2
1
  import logging
3
2
  import logging.config
3
+ from importlib.resources import as_file, files
4
4
 
5
5
  import yaml
6
6
  from opencensus.ext.azure.log_exporter import AzureLogHandler
@@ -14,8 +14,9 @@ from isar.config.settings import settings
14
14
 
15
15
  def setup_loggers(keyvault: Keyvault) -> None:
16
16
  log_levels: dict = settings.LOG_LEVELS
17
- with pkg_resources.path("isar.config", "logging.conf") as path:
18
- log_config = yaml.safe_load(open(path))
17
+ source = files("isar").joinpath("config").joinpath("logging.conf")
18
+ with as_file(source) as f:
19
+ log_config = yaml.safe_load(open(f))
19
20
 
20
21
  logging.config.dictConfig(log_config)
21
22
 
isar/config/settings.py CHANGED
@@ -1,5 +1,5 @@
1
- import importlib.resources as pkg_resources
2
1
  import os
2
+ from importlib.resources import as_file, files
3
3
  from typing import Any, List, Optional
4
4
 
5
5
  from dotenv import load_dotenv
@@ -14,11 +14,12 @@ from robot_interface.telemetry.payloads import VideoStream
14
14
  class Settings(BaseSettings):
15
15
  def __init__(self) -> None:
16
16
  try:
17
- with pkg_resources.path(f"isar.config", "settings.env") as path:
18
- env_file_path = path
17
+ source = files("isar").joinpath("config").joinpath("settings.env")
18
+ with as_file(source) as eml:
19
+ env_file = eml
19
20
  except ModuleNotFoundError:
20
- env_file_path = None
21
- super().__init__(_env_file=env_file_path)
21
+ env_file = None
22
+ super().__init__(_env_file=env_file)
22
23
 
23
24
  # Determines which robot package ISAR will attempt to import
24
25
  # Name must match with an installed python package in the local environment
@@ -310,13 +311,16 @@ settings = Settings()
310
311
  class RobotSettings(BaseSettings):
311
312
  def __init__(self) -> None:
312
313
  try:
313
- with pkg_resources.path(
314
- f"{settings.ROBOT_PACKAGE}.config", "settings.env"
315
- ) as path:
316
- env_file_path = path
314
+ source = (
315
+ files(f"{settings.ROBOT_PACKAGE}")
316
+ .joinpath("config")
317
+ .joinpath("settings.env")
318
+ )
319
+ with as_file(source) as eml:
320
+ env_file = eml
317
321
  except ModuleNotFoundError:
318
- env_file_path = None
319
- super().__init__(_env_file=env_file_path)
322
+ env_file = None
323
+ super().__init__(_env_file=env_file)
320
324
 
321
325
  # ISAR steps the robot is capable of performing
322
326
  # This should be set in the robot package settings.env file
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  import time
3
- from datetime import datetime
3
+ from datetime import UTC, datetime
4
4
  from queue import Queue
5
5
 
6
6
  from isar.config.settings import settings
@@ -18,7 +18,7 @@ class RobotHeartbeatPublisher:
18
18
  payload: RobotHeartbeatPayload = RobotHeartbeatPayload(
19
19
  isar_id=settings.ISAR_ID,
20
20
  robot_name=settings.ROBOT_NAME,
21
- timestamp=datetime.utcnow(),
21
+ timestamp=datetime.now(UTC),
22
22
  )
23
23
 
24
24
  self.mqtt_publisher.publish(
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  import time
3
- from datetime import datetime
3
+ from datetime import UTC, datetime
4
4
  from queue import Queue
5
5
 
6
6
  from isar.config.settings import robot_settings, settings
@@ -25,7 +25,7 @@ class RobotInfoPublisher:
25
25
  host=settings.API_HOST_VIEWED_EXTERNALLY,
26
26
  port=settings.API_PORT,
27
27
  capabilities=robot_settings.CAPABILITIES,
28
- timestamp=datetime.utcnow(),
28
+ timestamp=datetime.now(UTC),
29
29
  )
30
30
 
31
31
  self.mqtt_publisher.publish(
@@ -2,7 +2,7 @@ import json
2
2
  import logging
3
3
  import queue
4
4
  from collections import deque
5
- from datetime import datetime
5
+ from datetime import UTC, datetime
6
6
  from typing import Deque, List, Optional
7
7
 
8
8
  from alitra import Pose
@@ -508,7 +508,7 @@ class StateMachine(object):
508
508
  "error_description": (
509
509
  error_message.error_description if error_message else None
510
510
  ),
511
- "timestamp": datetime.utcnow(),
511
+ "timestamp": datetime.now(UTC),
512
512
  },
513
513
  cls=EnhancedJSONEncoder,
514
514
  )
@@ -516,7 +516,8 @@ class StateMachine(object):
516
516
  self.mqtt_publisher.publish(
517
517
  topic=settings.TOPIC_ISAR_MISSION,
518
518
  payload=payload,
519
- retain=False,
519
+ qos=1,
520
+ retain=True,
520
521
  )
521
522
 
522
523
  def publish_task_status(self, task: Task) -> None:
@@ -540,7 +541,7 @@ class StateMachine(object):
540
541
  "error_description": (
541
542
  error_message.error_description if error_message else None
542
543
  ),
543
- "timestamp": datetime.utcnow(),
544
+ "timestamp": datetime.now(UTC),
544
545
  },
545
546
  cls=EnhancedJSONEncoder,
546
547
  )
@@ -548,7 +549,8 @@ class StateMachine(object):
548
549
  self.mqtt_publisher.publish(
549
550
  topic=settings.TOPIC_ISAR_TASK,
550
551
  payload=payload,
551
- retain=False,
552
+ qos=1,
553
+ retain=True,
552
554
  )
553
555
 
554
556
  def publish_step_status(self, step: Step) -> None:
@@ -574,7 +576,7 @@ class StateMachine(object):
574
576
  "error_description": (
575
577
  error_message.error_description if error_message else None
576
578
  ),
577
- "timestamp": datetime.utcnow(),
579
+ "timestamp": datetime.now(UTC),
578
580
  },
579
581
  cls=EnhancedJSONEncoder,
580
582
  )
@@ -582,7 +584,8 @@ class StateMachine(object):
582
584
  self.mqtt_publisher.publish(
583
585
  topic=settings.TOPIC_ISAR_STEP,
584
586
  payload=payload,
585
- retain=False,
587
+ qos=1,
588
+ retain=True,
586
589
  )
587
590
 
588
591
  def publish_status(self) -> None:
@@ -593,7 +596,7 @@ class StateMachine(object):
593
596
  "isar_id": settings.ISAR_ID,
594
597
  "robot_name": settings.ROBOT_NAME,
595
598
  "status": self._current_status(),
596
- "timestamp": datetime.utcnow(),
599
+ "timestamp": datetime.now(UTC),
597
600
  },
598
601
  cls=EnhancedJSONEncoder,
599
602
  )
@@ -601,7 +604,8 @@ class StateMachine(object):
601
604
  self.mqtt_publisher.publish(
602
605
  topic=settings.TOPIC_ISAR_STATUS,
603
606
  payload=payload,
604
- retain=False,
607
+ qos=1,
608
+ retain=True,
605
609
  )
606
610
 
607
611
  def _current_status(self) -> RobotStatus:
isar/storage/uploader.py CHANGED
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  import logging
3
3
  from dataclasses import dataclass
4
- from datetime import datetime, timedelta
4
+ from datetime import UTC, datetime, timedelta
5
5
  from queue import Empty, Queue
6
6
  from typing import List, Union
7
7
 
@@ -22,12 +22,12 @@ class UploaderQueueItem:
22
22
  mission: Mission
23
23
  storage_handler: StorageInterface
24
24
  _retry_count: int
25
- _next_retry_time: datetime = datetime.utcnow()
25
+ _next_retry_time: datetime = datetime.now(UTC)
26
26
 
27
27
  def increment_retry(self, max_wait_time: int) -> None:
28
28
  self._retry_count += 1
29
29
  seconds_until_retry: int = min(2**self._retry_count, max_wait_time)
30
- self._next_retry_time = datetime.utcnow() + timedelta(
30
+ self._next_retry_time = datetime.now(UTC) + timedelta(
31
31
  seconds=seconds_until_retry
32
32
  )
33
33
 
@@ -35,10 +35,10 @@ class UploaderQueueItem:
35
35
  return self._retry_count
36
36
 
37
37
  def is_ready_for_upload(self) -> bool:
38
- return datetime.utcnow() >= self._next_retry_time
38
+ return datetime.now(UTC) >= self._next_retry_time
39
39
 
40
40
  def seconds_until_retry(self) -> int:
41
- return max(0, int((self._next_retry_time - datetime.utcnow()).total_seconds()))
41
+ return max(0, int((self._next_retry_time - datetime.now(UTC)).total_seconds()))
42
42
 
43
43
 
44
44
  class Uploader:
@@ -154,12 +154,13 @@ class Uploader:
154
154
  "inspection_id": inspection.id,
155
155
  "inspection_path": inspection_path,
156
156
  "analysis_type": inspection.metadata.analysis_type,
157
- "timestamp": datetime.utcnow(),
157
+ "timestamp": datetime.now(UTC),
158
158
  },
159
159
  cls=EnhancedJSONEncoder,
160
160
  )
161
161
  self.mqtt_publisher.publish(
162
162
  topic=settings.TOPIC_ISAR_INSPECTION_RESULT,
163
163
  payload=payload,
164
- retain=False,
164
+ qos=1,
165
+ retain=True,
165
166
  )
isar/storage/utilities.py CHANGED
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  import time
3
- from datetime import datetime
3
+ from datetime import UTC, datetime
4
4
  from pathlib import Path
5
5
  from typing import Tuple
6
6
 
@@ -37,7 +37,7 @@ def construct_metadata_file(
37
37
  "mission_id": mission.id,
38
38
  "mission_name": mission.name,
39
39
  "plant_name": settings.PLANT_NAME,
40
- "mission_date": datetime.utcnow().date(),
40
+ "mission_date": datetime.now(UTC).date(),
41
41
  "isar_id": settings.ISAR_ID,
42
42
  "robot_name": settings.ROBOT_NAME,
43
43
  "analysis_type": (
@@ -80,4 +80,4 @@ def get_filename(
80
80
 
81
81
  def get_foldername(mission: Mission) -> str:
82
82
  mission_name: str = mission.name.replace(" ", "-")
83
- return f"{datetime.utcnow().date()}__{settings.PLANT_SHORT_NAME}__{mission_name}__{mission.id}"
83
+ return f"{datetime.now(UTC).date()}__{settings.PLANT_SHORT_NAME}__{mission_name}__{mission.id}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: isar
3
- Version: 1.19.0
3
+ Version: 1.19.1
4
4
  Summary: Integration and Supervisory control of Autonomous Robots
5
5
  Home-page: https://github.com/equinor/isar
6
6
  Author: Equinor ASA
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python
12
12
  Classifier: Topic :: Scientific/Engineering
13
13
  Classifier: Topic :: Scientific/Engineering :: Physics
14
14
  Classifier: Topic :: Software Development :: Libraries
15
- Requires-Python: >=3.10
15
+ Requires-Python: >=3.11
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: alitra >=1.1.3
@@ -1,4 +1,4 @@
1
- isar/__init__.py,sha256=oXTcQpZYQ7jkRIem-Nq3hw9DrveoIV3-8k697XN16rA,190
1
+ isar/__init__.py,sha256=vGRSvnHq6l7PIQJcAKYS-sM_YIl1D77m4SGMFjyX8lY,187
2
2
  isar/modules.py,sha256=aO8bLSC4i_Qo4bOJ6aFfwAZRTJAw8o9SOOfkceUGCiU,6708
3
3
  isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  isar/apis/api.py,sha256=vSXfkWR7iITWbh4BsDzjEDtQrz6KS-vi2S8AeaeDc3Q,13112
@@ -11,10 +11,10 @@ isar/apis/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
11
11
  isar/apis/security/authentication.py,sha256=TI8U9Y_L6ihHLMeM50ZONd5EPfuHdw_XMU_Q987W4AY,1975
12
12
  isar/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5ATfKc,46
14
- isar/config/log.py,sha256=39G_Cue0qvw0Uv-1NYXvQ83yivPIKcAv-bGNNREFw5o,2251
14
+ isar/config/log.py,sha256=zHFLmGWQRn8TrcsxUS6KHpJt2JE86kYazU7b-bkcN9o,2285
15
15
  isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
16
16
  isar/config/settings.env,sha256=-kivj0osAAKlInnY81ugySTlcImhVABbnj9kUoBDLu8,535
17
- isar/config/settings.py,sha256=Wfau6k5ZUoC0BWgWXdzj4cSU7lny8SWrwqoy3t1U4Wg,13081
17
+ isar/config/settings.py,sha256=pZrZGe60WoMNl_SlCzJFavU3Qqil_ocCuaKcKfDn0KM,13175
18
18
  isar/config/certs/ca-cert.pem,sha256=gSBTyY0tKSFnssyvrvbFvHpQwii0kEkBryklVmevdtc,2029
19
19
  isar/config/keyvault/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  isar/config/keyvault/keyvault_error.py,sha256=zvPCsZLjboxsxthYkxpRERCTFxYV8R5WmACewAUQLwk,41
@@ -58,15 +58,15 @@ isar/services/service_connections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
58
58
  isar/services/service_connections/request_handler.py,sha256=0LxC0lu_HXeEf_xmJWjfEsh14oAUI97cpG1IWtBlcs4,4278
59
59
  isar/services/service_connections/mqtt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  isar/services/service_connections/mqtt/mqtt_client.py,sha256=Aib0lqaddxW9aVXXYD7wGL9jIpr2USCCH91SQgFdIG4,3548
61
- isar/services/service_connections/mqtt/robot_heartbeat_publisher.py,sha256=TxvpLA_qfyXwwN58h2X-eomTnhbFPhqfjamPxBz084E,1000
62
- isar/services/service_connections/mqtt/robot_info_publisher.py,sha256=d5HQ6Hfp5E21kaj1IJsFMWXecbzvH8iYByZhOucR004,1383
61
+ isar/services/service_connections/mqtt/robot_heartbeat_publisher.py,sha256=0Qjo2wRZZoooXG-UE4z8YJc9QCCz6v-9YAqHRJgx-kE,1005
62
+ isar/services/service_connections/mqtt/robot_info_publisher.py,sha256=f1vhBNPlx6p3Au8l7OsWIJXRM_xjA8qcLHvnkwCtRBM,1388
63
63
  isar/services/service_connections/stid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
64
  isar/services/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  isar/services/utilities/queue_utilities.py,sha256=Pw3hehSwkXJNeDv-bDVDfs58VOwtt3i5hpiJ2ZpphuQ,1225
66
66
  isar/services/utilities/scheduling_utilities.py,sha256=LFimEmacML3J9q-FNLfKPhcAr-R3f2rkYkbsoro0Gyo,8434
67
67
  isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
68
68
  isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
- isar/state_machine/state_machine.py,sha256=wmjPXoavlxrLvgMr41LGZekE5D_Cnsoz5IRAreag6_8,23576
69
+ isar/state_machine/state_machine.py,sha256=-i7m2xVcgL3cW6AIMGAom97wzt433MXM8EQEGUykAJA,23653
70
70
  isar/state_machine/states_enum.py,sha256=BlrUcBWkM5K6D_UZXRwTaUgGpAagWmVZH6HhDBGzVU4,278
71
71
  isar/state_machine/states/__init__.py,sha256=kErbKPDTwNfCLijvdyN6_AuOqDwR23nu9F0Qovsnir4,218
72
72
  isar/state_machine/states/idle.py,sha256=_nrM17s4artaHezanl28_WcNyJod1_hkCyzAqZlPQiE,3034
@@ -82,8 +82,8 @@ isar/storage/blob_storage.py,sha256=oKdml1VVN8iTr-d_5H4Lz5E7zrhJRknCzOxHD-tO7m8,
82
82
  isar/storage/local_storage.py,sha256=fLzVuwvdEk9l8z7od1qX2p5MeWzcsx-vN4yWvelZeFM,1836
83
83
  isar/storage/slimm_storage.py,sha256=Hp7ZIgZgIR4KAFjzxDKfgMZjPZwP2kmdc1gG8zVcsMk,8966
84
84
  isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8AvL7o,828
85
- isar/storage/uploader.py,sha256=Jpjml4fwPOeApHWfYWEO4gCfIxJKotujUTz2-5TTCt0,6345
86
- isar/storage/utilities.py,sha256=xnJHT_lu985k0Jlq7_Seu_nWVlocOCVAR8yz2zLkv5Q,3108
85
+ isar/storage/uploader.py,sha256=te3GyiSeu96MhbiqQ7ueIMUPLSKblx3UqYAshkxfVIE,6368
86
+ isar/storage/utilities.py,sha256=eTyY56WCTda5YswE9znWNeNEoTbT3jokNbwcLVmmQjA,3113
87
87
  robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
88
  robot_interface/robot_interface.py,sha256=i2qw1V9mLO-ljtS7LiRliQ7XNmmBJIwD4NG8mDfwMEI,8317
89
89
  robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
@@ -102,13 +102,13 @@ robot_interface/models/mission/task.py,sha256=bjp-m_Ak6tzgUIQvbGe90Mnwt6QhofTgFx
102
102
  robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
103
  robot_interface/models/robots/robot_model.py,sha256=pZQsqhn9hh6XE3EjMZhWMzYqg5oJ4CJ4CXeOASKvEf8,452
104
104
  robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
- robot_interface/telemetry/mqtt_client.py,sha256=p82lvfCqLyBHQ2n4jhWGRNb0RktAn4ptL8FZkASGGl4,2753
105
+ robot_interface/telemetry/mqtt_client.py,sha256=AHBmOpVvoo6pY5uXwyBY7SooN_cnpuS0DMkfLUPwpl8,2743
106
106
  robot_interface/telemetry/payloads.py,sha256=eMK7mjZPsLY6yvu7AK-OcdvkeUpChzDrySDY7IjQ9RM,1464
107
107
  robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
108
  robot_interface/utilities/json_service.py,sha256=nU2Q_3P9Fq9hs6F_wtUjWtHfl_g1Siy-yDhXXSKwHwg,1018
109
109
  robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
110
- isar-1.19.0.dist-info/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
111
- isar-1.19.0.dist-info/METADATA,sha256=E_9yJSv0SF_T3xHun3k_dPsM4DqQ9ayg_E65UpXLC68,15101
112
- isar-1.19.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
113
- isar-1.19.0.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
114
- isar-1.19.0.dist-info/RECORD,,
110
+ isar-1.19.1.dist-info/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
111
+ isar-1.19.1.dist-info/METADATA,sha256=kZ4uX6V3gxK6sUg-sNnXAzi0JYmvgOm5G38ISMy88xs,15101
112
+ isar-1.19.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
113
+ isar-1.19.1.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
114
+ isar-1.19.1.dist-info/RECORD,,
@@ -1,13 +1,11 @@
1
+ import json
1
2
  import time
2
3
  from abc import ABCMeta, abstractmethod
4
+ from datetime import UTC, datetime
3
5
  from queue import Queue
4
- from typing import Callable, Tuple, Type
5
- from datetime import datetime
6
- import json
6
+ from typing import Callable, Tuple
7
7
 
8
- from robot_interface.models.exceptions.robot_exceptions import (
9
- RobotTelemetryException,
10
- )
8
+ from robot_interface.models.exceptions.robot_exceptions import RobotTelemetryException
11
9
  from robot_interface.telemetry.payloads import CloudHealthPayload
12
10
  from robot_interface.utilities.json_service import EnhancedJSONEncoder
13
11
 
@@ -75,7 +73,7 @@ class MqttTelemetryPublisher(MqttClientInterface):
75
73
  topic = self.topic
76
74
  except RobotTelemetryException:
77
75
  payload = json.dumps(
78
- CloudHealthPayload(isar_id, robot_name, datetime.utcnow()),
76
+ CloudHealthPayload(isar_id, robot_name, datetime.now(UTC)),
79
77
  cls=EnhancedJSONEncoder,
80
78
  )
81
79
  topic = self.cloud_healt_topic
File without changes
File without changes