isar 1.34.9__py3-none-any.whl → 1.34.13__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.
- isar/apis/api.py +0 -23
- isar/apis/models/start_mission_definition.py +6 -3
- isar/apis/schedule/scheduling_controller.py +3 -29
- isar/config/keyvault/keyvault_service.py +3 -1
- isar/config/settings.py +0 -8
- isar/models/status.py +4 -0
- isar/modules.py +0 -2
- isar/robot/robot.py +8 -2
- isar/script.py +1 -1
- isar/services/utilities/scheduling_utilities.py +0 -42
- isar/state_machine/state_machine.py +24 -2
- isar/state_machine/states/maintenance.py +8 -1
- isar/state_machine/states/stopping.py +8 -0
- isar/state_machine/states/stopping_paused_mission.py +36 -0
- isar/state_machine/states/stopping_paused_return_home.py +59 -0
- isar/state_machine/states/stopping_return_home.py +24 -42
- isar/state_machine/states/unknown_status.py +2 -0
- isar/state_machine/states_enum.py +2 -0
- isar/state_machine/transitions/mission.py +37 -4
- isar/state_machine/transitions/return_home.py +2 -0
- isar/state_machine/transitions/robot_status.py +7 -0
- isar/state_machine/utils/common_event_handlers.py +65 -0
- {isar-1.34.9.dist-info → isar-1.34.13.dist-info}/METADATA +49 -16
- {isar-1.34.9.dist-info → isar-1.34.13.dist-info}/RECORD +29 -44
- robot_interface/telemetry/payloads.py +1 -1
- isar/config/configuration_error.py +0 -2
- isar/config/keyvault/keyvault_error.py +0 -2
- isar/config/predefined_mission_definition/__init__.py +0 -0
- isar/config/predefined_mission_definition/default_exr.json +0 -49
- isar/config/predefined_mission_definition/default_mission.json +0 -87
- isar/config/predefined_mission_definition/default_turtlebot.json +0 -117
- isar/config/predefined_missions/__init__.py +0 -0
- isar/config/predefined_missions/default.json +0 -72
- isar/config/predefined_missions/default_extra_capabilities.json +0 -107
- isar/mission_planner/__init__.py +0 -0
- isar/mission_planner/local_planner.py +0 -68
- isar/mission_planner/mission_planner_interface.py +0 -26
- isar/services/auth/__init__.py +0 -0
- isar/services/auth/azure_credentials.py +0 -14
- isar/services/service_connections/request_handler.py +0 -153
- isar/services/utilities/threaded_request.py +0 -68
- robot_interface/models/initialize/__init__.py +0 -0
- {isar-1.34.9.dist-info → isar-1.34.13.dist-info}/WHEEL +0 -0
- {isar-1.34.9.dist-info → isar-1.34.13.dist-info}/entry_points.txt +0 -0
- {isar-1.34.9.dist-info → isar-1.34.13.dist-info}/licenses/LICENSE +0 -0
- {isar-1.34.9.dist-info → isar-1.34.13.dist-info}/top_level.txt +0 -0
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mission_definition": {
|
|
3
|
-
"tasks": [
|
|
4
|
-
{
|
|
5
|
-
"pose": {
|
|
6
|
-
"position": {
|
|
7
|
-
"x": -3.6,
|
|
8
|
-
"y": 4,
|
|
9
|
-
"z": 0,
|
|
10
|
-
"frame": "asset"
|
|
11
|
-
},
|
|
12
|
-
"orientation": {
|
|
13
|
-
"x": 0,
|
|
14
|
-
"y": 0,
|
|
15
|
-
"z": -0.7286672256879113,
|
|
16
|
-
"w": -0.6848660759820616,
|
|
17
|
-
"frame": "asset"
|
|
18
|
-
},
|
|
19
|
-
"frame_name": "asset"
|
|
20
|
-
},
|
|
21
|
-
"tag": "1-A",
|
|
22
|
-
"inspections": [
|
|
23
|
-
{
|
|
24
|
-
"type": "Image",
|
|
25
|
-
"inspection_target": {
|
|
26
|
-
"x": -4.7,
|
|
27
|
-
"y": 4.9,
|
|
28
|
-
"z": 0,
|
|
29
|
-
"frame": "robot"
|
|
30
|
-
},
|
|
31
|
-
"metadata": {
|
|
32
|
-
"zoom": "2x"
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"type": "ThermalImage",
|
|
37
|
-
"inspection_target": {
|
|
38
|
-
"x": -4.7,
|
|
39
|
-
"y": 4.9,
|
|
40
|
-
"z": 0,
|
|
41
|
-
"frame": "robot"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
]
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"pose": {
|
|
48
|
-
"position": {
|
|
49
|
-
"x": 4.7,
|
|
50
|
-
"y": 3,
|
|
51
|
-
"z": 0,
|
|
52
|
-
"frame": "asset"
|
|
53
|
-
},
|
|
54
|
-
"orientation": {
|
|
55
|
-
"x": 0,
|
|
56
|
-
"y": 0,
|
|
57
|
-
"z": 0.5769585,
|
|
58
|
-
"w": 0.8167734,
|
|
59
|
-
"frame": "asset"
|
|
60
|
-
},
|
|
61
|
-
"frame_name": "asset"
|
|
62
|
-
},
|
|
63
|
-
"tag": "2-B",
|
|
64
|
-
"inspections": [
|
|
65
|
-
{
|
|
66
|
-
"type": "Image",
|
|
67
|
-
"inspection_target": {
|
|
68
|
-
"x": 5.6,
|
|
69
|
-
"y": 5.2,
|
|
70
|
-
"z": 0,
|
|
71
|
-
"frame": "robot"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
]
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
"pose": {
|
|
78
|
-
"position": {
|
|
79
|
-
"x": 0.95,
|
|
80
|
-
"y": 2.6,
|
|
81
|
-
"z": 0,
|
|
82
|
-
"frame": "asset"
|
|
83
|
-
},
|
|
84
|
-
"orientation": {
|
|
85
|
-
"x": 0,
|
|
86
|
-
"y": 0,
|
|
87
|
-
"z": -0.6992469,
|
|
88
|
-
"w": 0.7148802,
|
|
89
|
-
"frame": "asset"
|
|
90
|
-
},
|
|
91
|
-
"frame_name": "asset"
|
|
92
|
-
},
|
|
93
|
-
"tag": "3-C",
|
|
94
|
-
"inspections": [
|
|
95
|
-
{
|
|
96
|
-
"type": "Image",
|
|
97
|
-
"inspection_target": {
|
|
98
|
-
"x": 5.6,
|
|
99
|
-
"y": 5.2,
|
|
100
|
-
"z": 0,
|
|
101
|
-
"frame": "robot"
|
|
102
|
-
}
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
"type": "ThermalImage",
|
|
106
|
-
"inspection_target": {
|
|
107
|
-
"x": 1.9,
|
|
108
|
-
"y": 1.9,
|
|
109
|
-
"z": 0,
|
|
110
|
-
"frame": "robot"
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
]
|
|
114
|
-
}
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
}
|
|
File without changes
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "1",
|
|
3
|
-
"name": "Default mission",
|
|
4
|
-
"tasks": [
|
|
5
|
-
{
|
|
6
|
-
"type": "take_image",
|
|
7
|
-
"robot_pose": {
|
|
8
|
-
"position": {
|
|
9
|
-
"x": -2,
|
|
10
|
-
"y": -2,
|
|
11
|
-
"z": 0,
|
|
12
|
-
"frame": {
|
|
13
|
-
"name": "asset"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"orientation": {
|
|
17
|
-
"x": 0,
|
|
18
|
-
"y": 0,
|
|
19
|
-
"z": 0.4794255,
|
|
20
|
-
"w": 0.8775826,
|
|
21
|
-
"frame": {
|
|
22
|
-
"name": "asset"
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
"frame": {
|
|
26
|
-
"name": "asset"
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
"target": {
|
|
30
|
-
"x": 2,
|
|
31
|
-
"y": 2,
|
|
32
|
-
"z": 0,
|
|
33
|
-
"frame": {
|
|
34
|
-
"name": "asset"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"type": "take_image",
|
|
40
|
-
"robot_pose": {
|
|
41
|
-
"position": {
|
|
42
|
-
"x": -2,
|
|
43
|
-
"y": 2,
|
|
44
|
-
"z": 0,
|
|
45
|
-
"frame": {
|
|
46
|
-
"name": "asset"
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
"orientation": {
|
|
50
|
-
"x": 0,
|
|
51
|
-
"y": 0,
|
|
52
|
-
"z": 0.4794255,
|
|
53
|
-
"w": 0.8775826,
|
|
54
|
-
"frame": {
|
|
55
|
-
"name": "asset"
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
"frame": {
|
|
59
|
-
"name": "asset"
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
"target": {
|
|
63
|
-
"x": 2,
|
|
64
|
-
"y": 2,
|
|
65
|
-
"z": 0,
|
|
66
|
-
"frame": {
|
|
67
|
-
"name": "asset"
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
]
|
|
72
|
-
}
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "2",
|
|
3
|
-
"name": "Default mission with extra capabilities",
|
|
4
|
-
"tasks": [
|
|
5
|
-
{
|
|
6
|
-
"type": "take_image",
|
|
7
|
-
"robot_pose": {
|
|
8
|
-
"position": {
|
|
9
|
-
"x": -3.6,
|
|
10
|
-
"y": 4,
|
|
11
|
-
"z": 0,
|
|
12
|
-
"frame": {"name": "asset"}
|
|
13
|
-
},
|
|
14
|
-
"orientation": {
|
|
15
|
-
"x": 0,
|
|
16
|
-
"y": 0,
|
|
17
|
-
"z": -0.7286672256879113,
|
|
18
|
-
"w": -0.6848660759820616,
|
|
19
|
-
"frame": {"name": "asset"}
|
|
20
|
-
},
|
|
21
|
-
"frame": {"name": "asset"}
|
|
22
|
-
},
|
|
23
|
-
"target": {
|
|
24
|
-
"x": -4.7,
|
|
25
|
-
"y": 4.9,
|
|
26
|
-
"z": 0,
|
|
27
|
-
"frame": {"name": "asset"}
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
{
|
|
32
|
-
"type": "take_image",
|
|
33
|
-
"robot_pose": {
|
|
34
|
-
"position": {
|
|
35
|
-
"x": 4.7,
|
|
36
|
-
"y": 3,
|
|
37
|
-
"z": 0,
|
|
38
|
-
"frame": {"name": "asset"}
|
|
39
|
-
},
|
|
40
|
-
"orientation": {
|
|
41
|
-
"x": 0,
|
|
42
|
-
"y": 0,
|
|
43
|
-
"z": 0.5769585,
|
|
44
|
-
"w": 0.8167734,
|
|
45
|
-
"frame": {"name": "asset"}
|
|
46
|
-
},
|
|
47
|
-
"frame": {"name": "asset"}
|
|
48
|
-
},
|
|
49
|
-
"target": {
|
|
50
|
-
"x": 5.6,
|
|
51
|
-
"y": 5.2,
|
|
52
|
-
"z": 0,
|
|
53
|
-
"frame": {"name": "asset"}
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"type": "take_thermal_image",
|
|
58
|
-
"robot_pose": {
|
|
59
|
-
"position": {
|
|
60
|
-
"x": 4.7,
|
|
61
|
-
"y": 3,
|
|
62
|
-
"z": 0,
|
|
63
|
-
"frame": {"name": "asset"}
|
|
64
|
-
},
|
|
65
|
-
"orientation": {
|
|
66
|
-
"x": 0,
|
|
67
|
-
"y": 0,
|
|
68
|
-
"z": 0.5769585,
|
|
69
|
-
"w": 0.8167734,
|
|
70
|
-
"frame": {"name": "asset"}
|
|
71
|
-
},
|
|
72
|
-
"frame": {"name": "asset"}
|
|
73
|
-
},
|
|
74
|
-
"target": {
|
|
75
|
-
"x": 3.1,
|
|
76
|
-
"y": 5.2,
|
|
77
|
-
"z": 0,
|
|
78
|
-
"frame": {"name": "asset"}
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"type": "take_thermal_image",
|
|
83
|
-
"robot_pose": {
|
|
84
|
-
"position": {
|
|
85
|
-
"x": 0.95,
|
|
86
|
-
"y": 2.6,
|
|
87
|
-
"z": 0,
|
|
88
|
-
"frame": {"name": "asset"}
|
|
89
|
-
},
|
|
90
|
-
"orientation": {
|
|
91
|
-
"x": 0,
|
|
92
|
-
"y": 0,
|
|
93
|
-
"z": -0.6992469,
|
|
94
|
-
"w": 0.7148802,
|
|
95
|
-
"frame": {"name": "asset"}
|
|
96
|
-
},
|
|
97
|
-
"frame": {"name": "asset"}
|
|
98
|
-
},
|
|
99
|
-
"target": {
|
|
100
|
-
"x": 1.9,
|
|
101
|
-
"y": 1.9,
|
|
102
|
-
"z": 0,
|
|
103
|
-
"frame": {"name": "asset"}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
]
|
|
107
|
-
}
|
isar/mission_planner/__init__.py
DELETED
|
File without changes
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import logging
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
from isar.config.settings import settings
|
|
6
|
-
from isar.mission_planner.mission_planner_interface import (
|
|
7
|
-
MissionNotFoundError,
|
|
8
|
-
MissionPlannerError,
|
|
9
|
-
MissionPlannerInterface,
|
|
10
|
-
)
|
|
11
|
-
from robot_interface.models.mission.mission import Mission
|
|
12
|
-
|
|
13
|
-
logger = logging.getLogger("api")
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class LocalPlanner(MissionPlannerInterface):
|
|
17
|
-
def __init__(self):
|
|
18
|
-
self.predefined_mission_folder = Path(settings.PREDEFINED_MISSIONS_FOLDER)
|
|
19
|
-
|
|
20
|
-
def get_mission(self, mission_id) -> Mission:
|
|
21
|
-
missions: dict = self.get_predefined_missions()
|
|
22
|
-
if missions is None:
|
|
23
|
-
raise MissionPlannerError("There were no predefined missions")
|
|
24
|
-
try:
|
|
25
|
-
mission: Mission = missions[mission_id]["mission"]
|
|
26
|
-
return mission
|
|
27
|
-
except KeyError as e:
|
|
28
|
-
raise MissionNotFoundError(
|
|
29
|
-
f"Could not get mission : {mission_id} - does not exist {e}"
|
|
30
|
-
) from e
|
|
31
|
-
except Exception as e:
|
|
32
|
-
raise MissionPlannerError(f"Could not get mission : {mission_id}") from e
|
|
33
|
-
|
|
34
|
-
@staticmethod
|
|
35
|
-
def read_mission_from_file(mission_path: Path) -> Mission:
|
|
36
|
-
with open(mission_path) as json_file:
|
|
37
|
-
mission_dict = json.load(json_file)
|
|
38
|
-
|
|
39
|
-
return Mission(**mission_dict)
|
|
40
|
-
|
|
41
|
-
def get_predefined_missions(self) -> dict:
|
|
42
|
-
missions: dict = {}
|
|
43
|
-
invalid_mission_ids: list = []
|
|
44
|
-
json_files = self.predefined_mission_folder.glob("*.json")
|
|
45
|
-
for file in json_files:
|
|
46
|
-
mission_name = file.stem
|
|
47
|
-
path_to_file = self.predefined_mission_folder.joinpath(file.name)
|
|
48
|
-
|
|
49
|
-
mission: Mission = self.read_mission_from_file(path_to_file)
|
|
50
|
-
if mission.id in invalid_mission_ids:
|
|
51
|
-
logger.warning(
|
|
52
|
-
f"Duplicate mission id {mission.id} : {path_to_file.as_posix()}"
|
|
53
|
-
)
|
|
54
|
-
elif mission.id in missions:
|
|
55
|
-
conflicting_file_path = missions[mission.id]["file"]
|
|
56
|
-
logger.warning(
|
|
57
|
-
f"Duplicate mission id {mission.id} : {path_to_file.as_posix()}"
|
|
58
|
-
+ f" and {conflicting_file_path}"
|
|
59
|
-
)
|
|
60
|
-
invalid_mission_ids.append(mission.id)
|
|
61
|
-
missions.pop(mission.id)
|
|
62
|
-
else:
|
|
63
|
-
missions[mission.id] = {
|
|
64
|
-
"name": mission_name,
|
|
65
|
-
"file": path_to_file.as_posix(),
|
|
66
|
-
"mission": mission,
|
|
67
|
-
}
|
|
68
|
-
return missions
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from abc import ABCMeta, abstractmethod
|
|
2
|
-
|
|
3
|
-
from robot_interface.models.mission.mission import Mission
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class MissionPlannerInterface(metaclass=ABCMeta):
|
|
7
|
-
@abstractmethod
|
|
8
|
-
def get_mission(self, mission_id: str) -> Mission:
|
|
9
|
-
"""
|
|
10
|
-
Parameters
|
|
11
|
-
----------
|
|
12
|
-
mission_id : str
|
|
13
|
-
|
|
14
|
-
Returns
|
|
15
|
-
-------
|
|
16
|
-
mission : Mission
|
|
17
|
-
"""
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class MissionPlannerError(Exception):
|
|
22
|
-
pass
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class MissionNotFoundError(Exception):
|
|
26
|
-
pass
|
isar/services/auth/__init__.py
DELETED
|
File without changes
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
from azure.core.exceptions import ClientAuthenticationError
|
|
4
|
-
from azure.identity import DefaultAzureCredential
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class AzureCredentials:
|
|
8
|
-
@staticmethod
|
|
9
|
-
def get_azure_credentials():
|
|
10
|
-
try:
|
|
11
|
-
return DefaultAzureCredential()
|
|
12
|
-
except ClientAuthenticationError as e:
|
|
13
|
-
logging.error(e.message)
|
|
14
|
-
raise e
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from typing import Any, Optional
|
|
3
|
-
|
|
4
|
-
import requests
|
|
5
|
-
from requests.exceptions import ConnectionError, HTTPError, RequestException, Timeout
|
|
6
|
-
from requests.models import Response
|
|
7
|
-
|
|
8
|
-
from isar.config.settings import settings
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class RequestHandler:
|
|
12
|
-
def __init__(self):
|
|
13
|
-
self.logger = logging.getLogger("request_handler")
|
|
14
|
-
|
|
15
|
-
def base_request(
|
|
16
|
-
self,
|
|
17
|
-
url: str,
|
|
18
|
-
method: str,
|
|
19
|
-
json_body: Any,
|
|
20
|
-
timeout: float,
|
|
21
|
-
auth: tuple,
|
|
22
|
-
headers: Optional[dict] = None,
|
|
23
|
-
data: Optional[dict] = None,
|
|
24
|
-
params: Optional[dict] = None,
|
|
25
|
-
**kwargs,
|
|
26
|
-
) -> Response:
|
|
27
|
-
try:
|
|
28
|
-
response = requests.request(
|
|
29
|
-
url=url,
|
|
30
|
-
method=method,
|
|
31
|
-
auth=auth,
|
|
32
|
-
headers=headers,
|
|
33
|
-
timeout=timeout,
|
|
34
|
-
json=json_body,
|
|
35
|
-
data=data,
|
|
36
|
-
params=params,
|
|
37
|
-
**kwargs,
|
|
38
|
-
)
|
|
39
|
-
except Timeout as e:
|
|
40
|
-
self.logger.exception("Timeout exception")
|
|
41
|
-
raise RequestException from e
|
|
42
|
-
except ConnectionError as e:
|
|
43
|
-
self.logger.exception("Connection error")
|
|
44
|
-
raise RequestException from e
|
|
45
|
-
except RequestException as e:
|
|
46
|
-
raise RequestException from e
|
|
47
|
-
except Exception as e:
|
|
48
|
-
self.logger.exception("An unhandled exception occurred during a request")
|
|
49
|
-
raise RequestException from e
|
|
50
|
-
try:
|
|
51
|
-
response.raise_for_status()
|
|
52
|
-
except HTTPError:
|
|
53
|
-
self.logger.exception(
|
|
54
|
-
f"Http error. Http status code= {response.status_code}, Content: {response.content}"
|
|
55
|
-
)
|
|
56
|
-
raise
|
|
57
|
-
return response
|
|
58
|
-
|
|
59
|
-
def get(
|
|
60
|
-
self,
|
|
61
|
-
url: str,
|
|
62
|
-
json_body=None,
|
|
63
|
-
request_timeout: float = settings.REQUEST_TIMEOUT,
|
|
64
|
-
auth: Optional[tuple] = None,
|
|
65
|
-
headers: Optional[dict] = None,
|
|
66
|
-
data: Optional[dict] = None,
|
|
67
|
-
params: Optional[dict] = None,
|
|
68
|
-
**kwargs,
|
|
69
|
-
) -> Response:
|
|
70
|
-
response = self.base_request(
|
|
71
|
-
url=url,
|
|
72
|
-
method="GET",
|
|
73
|
-
auth=auth,
|
|
74
|
-
headers=headers,
|
|
75
|
-
timeout=request_timeout,
|
|
76
|
-
json_body=json_body,
|
|
77
|
-
data=data,
|
|
78
|
-
params=params,
|
|
79
|
-
**kwargs,
|
|
80
|
-
)
|
|
81
|
-
return response
|
|
82
|
-
|
|
83
|
-
def post(
|
|
84
|
-
self,
|
|
85
|
-
url: str,
|
|
86
|
-
json_body=None,
|
|
87
|
-
request_timeout: float = settings.REQUEST_TIMEOUT,
|
|
88
|
-
auth: Optional[tuple] = None,
|
|
89
|
-
headers: Optional[dict] = None,
|
|
90
|
-
data: Optional[dict] = None,
|
|
91
|
-
params: Optional[dict] = None,
|
|
92
|
-
**kwargs,
|
|
93
|
-
) -> Response:
|
|
94
|
-
response = self.base_request(
|
|
95
|
-
url=url,
|
|
96
|
-
method="POST",
|
|
97
|
-
auth=auth,
|
|
98
|
-
headers=headers,
|
|
99
|
-
timeout=request_timeout,
|
|
100
|
-
json_body=json_body,
|
|
101
|
-
data=data,
|
|
102
|
-
params=params,
|
|
103
|
-
**kwargs,
|
|
104
|
-
)
|
|
105
|
-
return response
|
|
106
|
-
|
|
107
|
-
def delete(
|
|
108
|
-
self,
|
|
109
|
-
url: str,
|
|
110
|
-
json_body=None,
|
|
111
|
-
request_timeout: float = settings.REQUEST_TIMEOUT,
|
|
112
|
-
auth: Optional[tuple] = None,
|
|
113
|
-
headers: Optional[dict] = None,
|
|
114
|
-
data: Optional[dict] = None,
|
|
115
|
-
params: Optional[dict] = None,
|
|
116
|
-
**kwargs,
|
|
117
|
-
) -> Response:
|
|
118
|
-
response = self.base_request(
|
|
119
|
-
url=url,
|
|
120
|
-
method="DELETE",
|
|
121
|
-
auth=auth,
|
|
122
|
-
headers=headers,
|
|
123
|
-
timeout=request_timeout,
|
|
124
|
-
json_body=json_body,
|
|
125
|
-
data=data,
|
|
126
|
-
params=params,
|
|
127
|
-
**kwargs,
|
|
128
|
-
)
|
|
129
|
-
return response
|
|
130
|
-
|
|
131
|
-
def put(
|
|
132
|
-
self,
|
|
133
|
-
url: str,
|
|
134
|
-
json_body=None,
|
|
135
|
-
request_timeout: float = settings.REQUEST_TIMEOUT,
|
|
136
|
-
auth: Optional[tuple] = None,
|
|
137
|
-
headers: Optional[dict] = None,
|
|
138
|
-
data: Optional[dict] = None,
|
|
139
|
-
params: Optional[dict] = None,
|
|
140
|
-
**kwargs,
|
|
141
|
-
) -> Response:
|
|
142
|
-
response = self.base_request(
|
|
143
|
-
url=url,
|
|
144
|
-
method="PUT",
|
|
145
|
-
auth=auth,
|
|
146
|
-
headers=headers,
|
|
147
|
-
timeout=request_timeout,
|
|
148
|
-
json_body=json_body,
|
|
149
|
-
data=data,
|
|
150
|
-
params=params,
|
|
151
|
-
**kwargs,
|
|
152
|
-
)
|
|
153
|
-
return response
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
from threading import Lock, Thread
|
|
2
|
-
from typing import Any, Optional
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class ThreadedRequest:
|
|
6
|
-
def __init__(self, request_func: Any):
|
|
7
|
-
self._thread: Optional[Thread] = None
|
|
8
|
-
self._request_func: Any = request_func
|
|
9
|
-
self._output: Optional[Any] = None
|
|
10
|
-
self._output_lock: Lock = Lock()
|
|
11
|
-
self._exception: Optional[Exception] = None
|
|
12
|
-
self._exception_lock: Lock = Lock()
|
|
13
|
-
|
|
14
|
-
def start_thread(self, *request_args, **kwargs) -> bool:
|
|
15
|
-
if self._is_thread_alive():
|
|
16
|
-
return False
|
|
17
|
-
self._output = None
|
|
18
|
-
self._thread = Thread(target=self._thread_func, args=request_args, **kwargs)
|
|
19
|
-
self._thread.start()
|
|
20
|
-
return True
|
|
21
|
-
|
|
22
|
-
def get_output(self) -> Any:
|
|
23
|
-
if self._is_thread_alive():
|
|
24
|
-
raise ThreadedRequestNotFinishedError
|
|
25
|
-
|
|
26
|
-
self._exception_lock.acquire()
|
|
27
|
-
exception = self._exception
|
|
28
|
-
self._exception_lock.release()
|
|
29
|
-
|
|
30
|
-
if exception:
|
|
31
|
-
raise exception
|
|
32
|
-
|
|
33
|
-
self._output_lock.acquire()
|
|
34
|
-
output = self._output
|
|
35
|
-
self._output_lock.release()
|
|
36
|
-
|
|
37
|
-
return output
|
|
38
|
-
|
|
39
|
-
def wait_for_thread(self) -> None:
|
|
40
|
-
if not self._thread:
|
|
41
|
-
return
|
|
42
|
-
self._thread.join()
|
|
43
|
-
|
|
44
|
-
def _is_thread_alive(self) -> bool:
|
|
45
|
-
if not self._thread:
|
|
46
|
-
return False
|
|
47
|
-
return self._thread.is_alive()
|
|
48
|
-
|
|
49
|
-
def _thread_func(self, *args) -> None:
|
|
50
|
-
try:
|
|
51
|
-
request_output: Any = self._request_func(*args)
|
|
52
|
-
except Exception as e:
|
|
53
|
-
self._exception_lock.acquire()
|
|
54
|
-
self._exception = e
|
|
55
|
-
self._exception_lock.release()
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
self._output_lock.acquire()
|
|
59
|
-
self._output = request_output
|
|
60
|
-
self._output_lock.release()
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class ThreadedRequestError(Exception):
|
|
64
|
-
pass
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class ThreadedRequestNotFinishedError(ThreadedRequestError):
|
|
68
|
-
pass
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|