isar 1.30.3__py3-none-any.whl → 1.30.4__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/apis/api.py CHANGED
@@ -1,4 +1,7 @@
1
+ import json
1
2
  import logging
3
+ import time
4
+ from datetime import datetime, timezone
2
5
  from http import HTTPStatus
3
6
  from logging import Logger
4
7
  from typing import List, Union
@@ -24,6 +27,9 @@ from isar.config.configuration_error import ConfigurationError
24
27
  from isar.config.keyvault.keyvault_error import KeyvaultError
25
28
  from isar.config.keyvault.keyvault_service import Keyvault
26
29
  from isar.config.settings import settings
30
+ from robot_interface.telemetry.mqtt_client import MqttClientInterface
31
+ from robot_interface.telemetry.payloads import StartUpMessagePayload
32
+ from robot_interface.utilities.json_service import EnhancedJSONEncoder
27
33
 
28
34
  HTTP_URL = COMMON_ATTRIBUTES["HTTP_URL"]
29
35
  HTTP_STATUS_CODE = COMMON_ATTRIBUTES["HTTP_STATUS_CODE"]
@@ -37,6 +43,7 @@ class API:
37
43
  scheduling_controller: SchedulingController,
38
44
  robot_controller: RobotController,
39
45
  keyvault: Keyvault,
46
+ mqtt_publisher: MqttClientInterface,
40
47
  port: int = settings.API_PORT,
41
48
  azure_ai_logging_enabled: bool = settings.LOG_HANDLER_APPLICATION_INSIGHTS_ENABLED,
42
49
  ) -> None:
@@ -47,22 +54,31 @@ class API:
47
54
  self.host: str = "0.0.0.0" # Locking uvicorn to use 0.0.0.0
48
55
  self.port: int = port
49
56
  self.azure_ai_logging_enabled: bool = azure_ai_logging_enabled
57
+ self.mqtt_publisher: MqttClientInterface = mqtt_publisher
50
58
 
51
59
  self.logger: Logger = logging.getLogger("api")
52
60
 
53
61
  self.app: FastAPI = self._create_app()
62
+ self.server = self._setup_server()
54
63
 
55
64
  def get_app(self) -> FastAPI:
56
65
  return self.app
57
66
 
58
- def run_app(self) -> None:
59
- uvicorn.run(
67
+ def _setup_server(self) -> uvicorn.Server:
68
+ config = uvicorn.Config(
60
69
  self.app,
61
70
  port=self.port,
62
71
  host=self.host,
63
72
  reload=False,
64
73
  log_config=None,
65
74
  )
75
+ return uvicorn.Server(config)
76
+
77
+ def wait_for_api_server_ready(self) -> None:
78
+ while not self.server.started:
79
+ time.sleep(0.01)
80
+ self.logger.info("Uvicorn server has been started")
81
+ self._publish_startup_message()
66
82
 
67
83
  def _create_app(self) -> FastAPI:
68
84
  tags_metadata = [
@@ -73,7 +89,10 @@ class API:
73
89
  ]
74
90
  app = FastAPI(
75
91
  openapi_tags=tags_metadata,
76
- on_startup=[self.authenticator.load_config, self._log_startup_message],
92
+ on_startup=[
93
+ self.authenticator.load_config,
94
+ self._log_startup_message,
95
+ ],
77
96
  swagger_ui_oauth2_redirect_url="/oauth2-redirect",
78
97
  swagger_ui_init_oauth={
79
98
  "usePkceWithAuthorizationCodeGrant": True,
@@ -349,3 +368,21 @@ class API:
349
368
  )
350
369
 
351
370
  return response
371
+
372
+ def _publish_startup_message(self) -> None:
373
+ if not self.mqtt_publisher:
374
+ return
375
+
376
+ payload: StartUpMessagePayload = StartUpMessagePayload(
377
+ isar_id=settings.ISAR_ID,
378
+ timestamp=datetime.now(timezone.utc),
379
+ )
380
+
381
+ self.logger.info("Publishing startup message to MQTT broker")
382
+
383
+ self.mqtt_publisher.publish(
384
+ topic=settings.TOPIC_ISAR_STARTUP,
385
+ payload=json.dumps(payload, cls=EnhancedJSONEncoder),
386
+ qos=1,
387
+ retain=True,
388
+ )
isar/config/settings.py CHANGED
@@ -211,6 +211,7 @@ class Settings(BaseSettings):
211
211
  TOPIC_ISAR_ROBOT_HEARTBEAT: str = Field(
212
212
  default="robot_heartbeat", validate_default=True
213
213
  )
214
+ TOPIC_ISAR_STARTUP: str = Field(default="startup", validate_default=True)
214
215
 
215
216
  # Logging
216
217
 
@@ -261,6 +262,7 @@ class Settings(BaseSettings):
261
262
  "TOPIC_ISAR_ROBOT_HEARTBEAT",
262
263
  "TOPIC_ISAR_INSPECTION_RESULT",
263
264
  "TOPIC_ISAR_INSPECTION_VALUE",
265
+ "TOPIC_ISAR_STARTUP",
264
266
  )
265
267
  @classmethod
266
268
  def prefix_isar_topics(cls, v: Any, info: ValidationInfo):
isar/modules.py CHANGED
@@ -45,6 +45,16 @@ class ApplicationContainer(containers.DeclarativeContainer):
45
45
  )
46
46
  robot_utilities = providers.Singleton(RobotUtilities, robot=robot_interface)
47
47
 
48
+ # Mqtt client
49
+ mqtt_client = (
50
+ providers.Singleton(
51
+ MqttPublisher,
52
+ mqtt_queue=providers.Callable(events.provided.mqtt_queue),
53
+ )
54
+ if settings.MQTT_ENABLED
55
+ else None
56
+ )
57
+
48
58
  # API and controllers
49
59
  authenticator = providers.Singleton(Authenticator)
50
60
  scheduling_utilities = providers.Singleton(
@@ -65,6 +75,7 @@ class ApplicationContainer(containers.DeclarativeContainer):
65
75
  scheduling_controller=scheduling_controller,
66
76
  robot_controller=robot_controller,
67
77
  keyvault=keyvault,
78
+ mqtt_publisher=mqtt_client,
68
79
  )
69
80
 
70
81
  # Storage
@@ -77,16 +88,6 @@ class ApplicationContainer(containers.DeclarativeContainer):
77
88
  storage_handlers_temp.append(blob_storage)
78
89
  storage_handlers = providers.List(*storage_handlers_temp)
79
90
 
80
- # Mqtt client
81
- mqtt_client = (
82
- providers.Singleton(
83
- MqttPublisher,
84
- mqtt_queue=providers.Callable(events.provided.mqtt_queue),
85
- )
86
- if settings.MQTT_ENABLED
87
- else None
88
- )
89
-
90
91
  # State machine
91
92
  task_selector = providers.Singleton(
92
93
  SequentialTaskSelector
isar/script.py CHANGED
@@ -160,13 +160,15 @@ def start() -> None:
160
160
  threads.extend(publishers)
161
161
 
162
162
  api: API = injector.api()
163
- api_thread: Thread = Thread(target=api.run_app, name="ISAR API", daemon=True)
163
+ api_thread: Thread = Thread(target=api.server.run, name="ISAR API", daemon=True)
164
164
  threads.append(api_thread)
165
165
 
166
166
  for thread in threads:
167
167
  thread.start()
168
168
  logger.info("Started thread: %s", thread.name)
169
169
 
170
+ api.wait_for_api_server_ready()
171
+
170
172
  while True:
171
173
  for thread in threads:
172
174
  if not thread.is_alive():
@@ -18,7 +18,7 @@ def put_start_mission_on_queue(state_machine: "StateMachine") -> bool:
18
18
 
19
19
  def initiate_mission(state_machine: "StateMachine") -> bool:
20
20
  state_machine.logger.info(
21
- "Initialization successful. Starting new mission:\n"
21
+ "Initiating mission:\n"
22
22
  f" Mission ID: {state_machine.current_mission.id}\n"
23
23
  f" Mission Name: {state_machine.current_mission.name}\n"
24
24
  f" Number of Tasks: {len(state_machine.current_mission.tasks)}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isar
3
- Version: 1.30.3
3
+ Version: 1.30.4
4
4
  Summary: Integration and Supervisory control of Autonomous Robots
5
5
  Author-email: Equinor ASA <fg_robots_dev@equinor.com>
6
6
  License: Eclipse Public License version 2.0
@@ -1,8 +1,8 @@
1
1
  isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
2
- isar/modules.py,sha256=73cB5KgYUURsNR2bps1aVUXNY7gv6HHQyZ3qwnFpbJA,4742
3
- isar/script.py,sha256=mcZGMkIbUKkdLY5CwQOO16HSLlNJZRFaozAppmTMfTQ,6010
2
+ isar/modules.py,sha256=QBB1pge1i17HVMLA5n-qd9K3APCrX9bFF2vlfjheOhU,4778
3
+ isar/script.py,sha256=0oUUfytKDOsWrPv4iWemTWl5L3Ug66mQsbvqGqQrVWk,6050
4
4
  isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- isar/apis/api.py,sha256=1-RmRH7NReCpOo_NSwP5hS2lDQm6_Dx2ZWe2460GhJY,13770
5
+ isar/apis/api.py,sha256=2hggLxcdsHqTYDAfVUMwMIBgpuB-0ba2HWMscHkRGzA,15072
6
6
  isar/apis/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  isar/apis/models/models.py,sha256=HzLaWhjAv0uJRBWipIgYg_F75eaQ5jl9Pi4UnYbDJ-M,1749
8
8
  isar/apis/models/start_mission_definition.py,sha256=S87i_vrgXTY1nTMTiXMJAnx_q5uVxuiRNcrQrAYWKeo,6152
@@ -15,7 +15,7 @@ isar/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5ATfKc,46
16
16
  isar/config/log.py,sha256=SzEWbzXU1DpN7YONIRT8k0zBOGm_qVkXlJuuZtb8STc,2300
17
17
  isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
18
- isar/config/settings.py,sha256=M8Licz8HfVH46nh8dmUwVyi-4MqWD-1sYBOYNoorae0,12379
18
+ isar/config/settings.py,sha256=dn9fEKX7GpzD9Y7q0TjQxW9Xf0iY-pCl3NV7bkxH1E8,12487
19
19
  isar/config/certs/ca-cert.pem,sha256=qoNljfad_qcMxhXJIUMLd7nT-Qwf_d4dYSdoOFEOE8I,2179
20
20
  isar/config/keyvault/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  isar/config/keyvault/keyvault_error.py,sha256=zvPCsZLjboxsxthYkxpRERCTFxYV8R5WmACewAUQLwk,41
@@ -95,7 +95,7 @@ isar/state_machine/transitions/functions/pause.py,sha256=aoDkq2nV6wBY0YQX3KbjvBR
95
95
  isar/state_machine/transitions/functions/resume.py,sha256=9KQjH_6YBGyxFhb7G5dgDe3WH0xHawhEIw6yTVEm9os,998
96
96
  isar/state_machine/transitions/functions/return_home.py,sha256=UlniwYvpz74hxqgN0TyVv3LCmiMsqsosKEtEGLqkNj0,1139
97
97
  isar/state_machine/transitions/functions/robot_status.py,sha256=xhKZ5u_X8uDvnhvGnAIABuKaPXeVqFjkgj4H2Om-j_A,1013
98
- isar/state_machine/transitions/functions/start_mission.py,sha256=NXFLEWZ5ZbsulbIQVgDz2mRUOULP3mfpgSheiw4LSYw,2593
98
+ isar/state_machine/transitions/functions/start_mission.py,sha256=ricRfhLH1_lNpqWxneMZcm7ps2YfY6sQGHkiT0Glf6M,2564
99
99
  isar/state_machine/transitions/functions/stop.py,sha256=aIj3EPnpgNLdsJwOK1ehhI1TpenQa9JjBxZH0Nm6dLg,1649
100
100
  isar/state_machine/transitions/functions/utils.py,sha256=Wa72Ocq4QT1E6qkpEJZQ3h5o33pGvx7Tlkt2JZ2Grbk,314
101
101
  isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -104,7 +104,7 @@ isar/storage/local_storage.py,sha256=Bnmoi5gyN8r-oRh0aHrOdGqaH3JqRScFKMRXYojW5kY
104
104
  isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8AvL7o,828
105
105
  isar/storage/uploader.py,sha256=HAC3ssuPQCQ1xH4aTQfHIaq-ZoEzKwONWmsAOpNXOzw,9523
106
106
  isar/storage/utilities.py,sha256=oLH0Rp7UtrQQdilfITnmXO1Z0ExdeDhBImYHid55vBA,3449
107
- isar-1.30.3.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
107
+ isar-1.30.4.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
108
108
  robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
109
  robot_interface/robot_interface.py,sha256=Miout0IRX7QniUNu_upyNzkB8KDUWin7GGCqIeMh83E,8195
110
110
  robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
@@ -124,12 +124,12 @@ robot_interface/models/robots/media.py,sha256=8A-CuuubfngzPprs6zWB9hSaqe3jzgsE8r
124
124
  robot_interface/models/robots/robot_model.py,sha256=-0jNKWPcEgtF_2klb1It3u0SCoAR0hSW9nce58Zq0Co,417
125
125
  robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
126
126
  robot_interface/telemetry/mqtt_client.py,sha256=ueXdtIFNCwciTj4spvdJj9emd-IOmUuJjpsXQSSWZPY,2987
127
- robot_interface/telemetry/payloads.py,sha256=78EVedDyRhYIquwXWdwjhA3RntMboCcuPWE7TI_gDf0,2721
127
+ robot_interface/telemetry/payloads.py,sha256=PpvmV7XeGgfhc_aRUYFOdwBTwV2x8TwTBINJ-rKchVw,2804
128
128
  robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
129
  robot_interface/utilities/json_service.py,sha256=qkzVkb60Gi_pto-b5n1vNzCrQze2yqgIJqSLNLYj1Fg,1034
130
130
  robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
131
- isar-1.30.3.dist-info/METADATA,sha256=wJcwLK3BoorZOiqr_4dYD_sdppvRkl8qIHazybd1Ml0,31063
132
- isar-1.30.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
133
- isar-1.30.3.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
134
- isar-1.30.3.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
135
- isar-1.30.3.dist-info/RECORD,,
131
+ isar-1.30.4.dist-info/METADATA,sha256=SaISJES198lknEfIqlqwrZ1CZe4A0vzi_mKYuu1fZrU,31063
132
+ isar-1.30.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
133
+ isar-1.30.4.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
134
+ isar-1.30.4.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
135
+ isar-1.30.4.dist-info/RECORD,,
@@ -132,3 +132,9 @@ class InspectionValuePayload:
132
132
  y: float
133
133
  z: float
134
134
  timestamp: datetime
135
+
136
+
137
+ @dataclass
138
+ class StartUpMessagePayload:
139
+ isar_id: str
140
+ timestamp: datetime
File without changes