autoverse-cli 0.28.3__py3-none-any.whl → 0.29.1.dev408__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.
- {autoverse_cli-0.28.3.dist-info → autoverse_cli-0.29.1.dev408.dist-info}/METADATA +22 -1
- {autoverse_cli-0.28.3.dist-info → autoverse_cli-0.29.1.dev408.dist-info}/RECORD +10 -10
- avrs/app_version.py +1 -1
- avrs/race_cloud.py +86 -16
- avrs/race_cloud_cfg_util.py +4 -30
- avrs/race_cloud_util.py +50 -37
- {autoverse_cli-0.28.3.dist-info → autoverse_cli-0.29.1.dev408.dist-info}/WHEEL +0 -0
- {autoverse_cli-0.28.3.dist-info → autoverse_cli-0.29.1.dev408.dist-info}/entry_points.txt +0 -0
- {autoverse_cli-0.28.3.dist-info → autoverse_cli-0.29.1.dev408.dist-info}/licenses/LICENSE +0 -0
- {autoverse_cli-0.28.3.dist-info → autoverse_cli-0.29.1.dev408.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: autoverse-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.29.1.dev408
|
|
4
4
|
Summary: The Autoverse CLI
|
|
5
5
|
Author-email: Dan Kamrath <dan.kamrath@autonomalabs.com>
|
|
6
6
|
License: # End-User License Agreement (EULA) of the Autonoma AutoVerse CLI
|
|
@@ -52,10 +52,31 @@ The new implementation of the Autoverse CLI
|
|
|
52
52
|
|
|
53
53
|
## Installation
|
|
54
54
|
|
|
55
|
+
### Stable Release (Recommended)
|
|
55
56
|
```bash
|
|
56
57
|
pip install autoverse-cli
|
|
57
58
|
```
|
|
58
59
|
|
|
60
|
+
### Development Versions
|
|
61
|
+
|
|
62
|
+
Development versions are published from feature branches and follow the format `X.Y.Z.devN`.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Install the latest development version
|
|
66
|
+
pip install autoverse-cli --pre
|
|
67
|
+
|
|
68
|
+
# Install a specific development version
|
|
69
|
+
pip install autoverse-cli==0.29.1.dev123
|
|
70
|
+
|
|
71
|
+
# Check available versions (including dev)
|
|
72
|
+
pip index versions autoverse-cli
|
|
73
|
+
|
|
74
|
+
# Upgrade to latest dev version
|
|
75
|
+
pip install --upgrade --pre autoverse-cli
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> **Note:** `pip install autoverse-cli` (without `--pre`) always installs the latest stable release from `main`. Development versions require the `--pre` flag explicitly.
|
|
79
|
+
|
|
59
80
|
## Shell Completion
|
|
60
81
|
|
|
61
82
|
To enable tab completion for the `avrs` command, run:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
autoverse_cli-0.
|
|
1
|
+
autoverse_cli-0.29.1.dev408.dist-info/licenses/LICENSE,sha256=d4eWXho-u18HkBsX4K21uHX_bBb2UXZSrJdsb7Z_JlM,2647
|
|
2
2
|
avrs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
avrs/app_version.py,sha256=
|
|
3
|
+
avrs/app_version.py,sha256=ZdXZlJob3TXGBHkwL5DrTMvjg6wtqb58C5-Olo1sI98,864
|
|
4
4
|
avrs/argparse_help.py,sha256=EoEaohGXZXqJvs1dFEzbo9vh47CYdHdSY2Im2Ps2iFo,945
|
|
5
5
|
avrs/avrs.py,sha256=pQHc8KLAD0hCxpBoNbXOgj2Et3qiqxSMKyAXFLwWFjE,5787
|
|
6
6
|
avrs/can_tool.py,sha256=IBoctKobBJ3wCq4ZdtuXuXH4AMEUxazCfYT6YP0Luw8,7161
|
|
@@ -8,11 +8,11 @@ avrs/can_tool_util.py,sha256=G3q21dTGMLc09SDq_RieoW7kSn-kXPkXxPDjavPh4hQ,7710
|
|
|
8
8
|
avrs/cfg.py,sha256=kMn08Z4Ms1PAu2-U1QI8weEJeIVEppP4A4_tFfwnjtg,2924
|
|
9
9
|
avrs/launcher.py,sha256=uk7xG2JTLJv7FJMDo1diwc-zmTvUxXJME9-0ctrZRuk,11352
|
|
10
10
|
avrs/launcher_util.py,sha256=zXUbJByn9M-ErkNM6DvLCFtUkueYH-R0dehjQj0aYEs,6879
|
|
11
|
-
avrs/race_cloud.py,sha256=
|
|
11
|
+
avrs/race_cloud.py,sha256=Ff7Qee_B9V3M_L_uW8BP7A2F1kTiSs7Ne1TAsAC8mzE,22991
|
|
12
12
|
avrs/race_cloud_bridge_can.py,sha256=K3is7GFzWo2KBojr6V65kz138UfkVFXXofVxSAziArY,2888
|
|
13
|
-
avrs/race_cloud_cfg_util.py,sha256=
|
|
13
|
+
avrs/race_cloud_cfg_util.py,sha256=TF_gsP7c_39MKs1CyzeXkTH-Fwyd8wLkFkMbqQVmdeo,12066
|
|
14
14
|
avrs/race_cloud_fwd_api.py,sha256=jB4kt6Shu9Pj96WPVjK790PZjucYxmuHjjVKczQfyZI,1620
|
|
15
|
-
avrs/race_cloud_util.py,sha256=
|
|
15
|
+
avrs/race_cloud_util.py,sha256=A8IiVnHmqGTA0qMtOBtGqYXfjeIQNzaPdtnrtvzpq1Y,15484
|
|
16
16
|
avrs/shell_completion.py,sha256=_IM85ADKQHYNMlTa1_nhnYWsgdOzRQ7tIFHxAT6EWWA,4298
|
|
17
17
|
avrs/simconfig.py,sha256=UZc4FrxVHUkk2e9IglSpuojXkaL_nPrJW7trbEGgOOo,2907
|
|
18
18
|
avrs/simconfig_util.py,sha256=ronvXg9Mraz60K99ABBvo_YDI1_rWphUWUn_s_voTKw,6044
|
|
@@ -44,8 +44,8 @@ avrs/requests/toggle_hud.py,sha256=sV5t5QZc4uvRihPVk8jEKZiQNsyF9tsUwq5b4jjZplc,3
|
|
|
44
44
|
avrs/requests/vd.py,sha256=Rd0mCc89m2yKjftVf0cMHMFbJG4iFd09KzrI-DsCLgI,2606
|
|
45
45
|
avrs/requests/vehicle_input.py,sha256=R1b1xkRtOBkwyU6OSN4bWVlYsIUroZG0WKbYbc4pEH8,729
|
|
46
46
|
avrs/requests/vehicle_replay.py,sha256=7HPfVLjSLNbOyzU77Bz29qpHqRsMUAIWvnwvnNiw2nk,15026
|
|
47
|
-
autoverse_cli-0.
|
|
48
|
-
autoverse_cli-0.
|
|
49
|
-
autoverse_cli-0.
|
|
50
|
-
autoverse_cli-0.
|
|
51
|
-
autoverse_cli-0.
|
|
47
|
+
autoverse_cli-0.29.1.dev408.dist-info/METADATA,sha256=dkMoJjdB0_j5UoA1WigTUgCpd1mHMZuBJjQo7gABjaU,4588
|
|
48
|
+
autoverse_cli-0.29.1.dev408.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
49
|
+
autoverse_cli-0.29.1.dev408.dist-info/entry_points.txt,sha256=Cb9qsUyU5AKkklehCcvtfT0-N3SXbUEqvjze4iEU5kE,40
|
|
50
|
+
autoverse_cli-0.29.1.dev408.dist-info/top_level.txt,sha256=-AJO2e4MCVej6hY0U84pu5NfMeMW5qaAPSMisDT5rmA,5
|
|
51
|
+
autoverse_cli-0.29.1.dev408.dist-info/RECORD,,
|
avrs/app_version.py
CHANGED
avrs/race_cloud.py
CHANGED
|
@@ -2,6 +2,7 @@ import subprocess
|
|
|
2
2
|
import base64
|
|
3
3
|
import logging
|
|
4
4
|
import time
|
|
5
|
+
import ipaddress
|
|
5
6
|
from avrs.cfg import *
|
|
6
7
|
from avrs.race_cloud_util import *
|
|
7
8
|
from avrs.race_cloud_cfg_util import *
|
|
@@ -11,6 +12,47 @@ from avrs.util import *
|
|
|
11
12
|
from avrs.requests.request import AvrsApiRequest
|
|
12
13
|
from argparse import RawTextHelpFormatter
|
|
13
14
|
|
|
15
|
+
|
|
16
|
+
def is_valid_public_ip(value):
|
|
17
|
+
"""Check if a string is a valid public IP address (not private, not loopback, not reserved)."""
|
|
18
|
+
try:
|
|
19
|
+
ip = ipaddress.ip_address(value)
|
|
20
|
+
# Reject private, loopback, reserved, multicast, and link-local addresses
|
|
21
|
+
return not (ip.is_private or ip.is_loopback or ip.is_reserved or
|
|
22
|
+
ip.is_multicast or ip.is_link_local)
|
|
23
|
+
except ValueError:
|
|
24
|
+
return False
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def parse_sim_target(value):
|
|
28
|
+
"""
|
|
29
|
+
Parse sim_target argument: can be a legacy index (0-5) or a public IP address.
|
|
30
|
+
Returns (is_valid, parsed_value, is_ip).
|
|
31
|
+
"""
|
|
32
|
+
# First, check if it's a legacy integer index (0-5)
|
|
33
|
+
try:
|
|
34
|
+
index = int(value)
|
|
35
|
+
if 0 <= index <= 5:
|
|
36
|
+
return (True, index, False)
|
|
37
|
+
else:
|
|
38
|
+
return (False, "Legacy index must be between 0 and 5", False)
|
|
39
|
+
except ValueError:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
# Check if it's a valid public IP address
|
|
43
|
+
try:
|
|
44
|
+
ip = ipaddress.ip_address(value)
|
|
45
|
+
if is_valid_public_ip(value):
|
|
46
|
+
# Valid public IP address
|
|
47
|
+
return (True, value, True)
|
|
48
|
+
else:
|
|
49
|
+
# IP is private, loopback, or otherwise not public
|
|
50
|
+
return (False, "IP address must be public (not private, loopback, or reserved)", False)
|
|
51
|
+
except ValueError:
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
return (False, "Must be a legacy index (0-5) or a valid public IP address", False)
|
|
55
|
+
|
|
14
56
|
class AvrsRaceCloud(AvrsApiRequest):
|
|
15
57
|
def __init__(self, parser, cfg):
|
|
16
58
|
self.cfg = cfg
|
|
@@ -24,10 +66,9 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
24
66
|
'connect',
|
|
25
67
|
help='connect to an instance for cloud racing')
|
|
26
68
|
connect_parser.add_argument(
|
|
27
|
-
'
|
|
28
|
-
type
|
|
29
|
-
|
|
30
|
-
help='the index of the simulator instance to connect to')
|
|
69
|
+
'sim_target',
|
|
70
|
+
type=str,
|
|
71
|
+
help='simulator target: legacy index (0-5) or PUBLIC IP address of the server instance (private IPs not allowed)')
|
|
31
72
|
connect_parser.add_argument(
|
|
32
73
|
'team_name',
|
|
33
74
|
help='the name of the team to race under')
|
|
@@ -74,10 +115,9 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
74
115
|
'sim-ctrl',
|
|
75
116
|
help='control the sim program (start, stop, restart, reset)')
|
|
76
117
|
sim_ctrl_parser.add_argument(
|
|
77
|
-
'
|
|
78
|
-
type=
|
|
79
|
-
|
|
80
|
-
help='the index of the simulator instance to apply the action')
|
|
118
|
+
'sim_target',
|
|
119
|
+
type=str,
|
|
120
|
+
help='simulator target: legacy index (0-5) or PUBLIC IP address of the server instance (private IPs not allowed)')
|
|
81
121
|
sim_ctrl_parser.add_argument(
|
|
82
122
|
'action',
|
|
83
123
|
choices=['start', 'stop', 'restart', 'reset-connection', 'get-log'],
|
|
@@ -169,6 +209,12 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
169
209
|
def race_connect(self, args):
|
|
170
210
|
logger = logging.getLogger('avrs')
|
|
171
211
|
|
|
212
|
+
# Validate sim_target (can be legacy index 0-5 or public IP only)
|
|
213
|
+
is_valid, parsed_value, is_ip = parse_sim_target(args.sim_target)
|
|
214
|
+
if not is_valid:
|
|
215
|
+
print('invalid sim_target: {}'.format(parsed_value))
|
|
216
|
+
return
|
|
217
|
+
|
|
172
218
|
# make api call to begin connection
|
|
173
219
|
our_ip = get_local_instance_ip()
|
|
174
220
|
|
|
@@ -176,8 +222,9 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
176
222
|
print('this machines IP was returned as localhost. was this run on the cloud instance?')
|
|
177
223
|
return
|
|
178
224
|
|
|
179
|
-
|
|
180
|
-
|
|
225
|
+
target_display = args.sim_target if is_ip else 'index {}'.format(parsed_value)
|
|
226
|
+
logger.info('starting race-cloud connect for team {} to {}'.format(
|
|
227
|
+
args.team_name, target_display))
|
|
181
228
|
print('connecting to race with team name: {}'.format(args.team_name))
|
|
182
229
|
|
|
183
230
|
if args.no_restart_sim:
|
|
@@ -217,7 +264,7 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
217
264
|
|
|
218
265
|
connection_request = {
|
|
219
266
|
'action': 'connect',
|
|
220
|
-
'
|
|
267
|
+
'sim_id': str(parsed_value), # Can be index (0-5) or public IP address only
|
|
221
268
|
'ip_to_reserve': our_ip,
|
|
222
269
|
'team_name': args.team_name,
|
|
223
270
|
'sim_id_override': args.instance_id,
|
|
@@ -229,7 +276,6 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
229
276
|
ok, response = call_race_cloud_api(connection_request)
|
|
230
277
|
if not ok:
|
|
231
278
|
print('connect api error: {}'.format(response))
|
|
232
|
-
return
|
|
233
279
|
|
|
234
280
|
ok, rbody, sim_ip = get_api_script_response(response)
|
|
235
281
|
if not ok:
|
|
@@ -242,9 +288,27 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
242
288
|
|
|
243
289
|
slot_info = {}
|
|
244
290
|
for k, v in rbody.items():
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
291
|
+
logger.info('Processing response for key: {}'.format(k))
|
|
292
|
+
logger.info('stdout: {}'.format(v.get('stdout', '')))
|
|
293
|
+
logger.info('stderr: {}'.format(v.get('stderr', '')))
|
|
294
|
+
|
|
295
|
+
stdout = v.get('stdout', '').strip()
|
|
296
|
+
stderr = v.get('stderr', '').strip()
|
|
297
|
+
|
|
298
|
+
if not stdout:
|
|
299
|
+
print('Error: No stdout from remote command')
|
|
300
|
+
if stderr:
|
|
301
|
+
print('stderr: {}'.format(stderr))
|
|
302
|
+
return
|
|
303
|
+
|
|
304
|
+
try:
|
|
305
|
+
slot_info = json.loads(stdout)
|
|
306
|
+
except json.JSONDecodeError as e:
|
|
307
|
+
print('Error parsing JSON from stdout: {}'.format(e))
|
|
308
|
+
print('stdout content: {}'.format(stdout[:500])) # Print first 500 chars
|
|
309
|
+
if stderr:
|
|
310
|
+
print('stderr: {}'.format(stderr))
|
|
311
|
+
return
|
|
248
312
|
|
|
249
313
|
if not slot_info['ok']:
|
|
250
314
|
print('issue reserving slot: {}'.format(slot_info['msg']))
|
|
@@ -406,6 +470,12 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
406
470
|
def remote_sim_ctrl(self, args):
|
|
407
471
|
logger = logging.getLogger('avrs')
|
|
408
472
|
|
|
473
|
+
# Validate sim_target (can be legacy index 0-5 or public IP only)
|
|
474
|
+
is_valid, parsed_value, is_ip = parse_sim_target(args.sim_target)
|
|
475
|
+
if not is_valid:
|
|
476
|
+
print('invalid sim_target: {}'.format(parsed_value))
|
|
477
|
+
return
|
|
478
|
+
|
|
409
479
|
# go ahead and reset local connection as well
|
|
410
480
|
if args.action == 'reset-connection':
|
|
411
481
|
reset_race_cloud_connection()
|
|
@@ -414,7 +484,7 @@ class AvrsRaceCloud(AvrsApiRequest):
|
|
|
414
484
|
|
|
415
485
|
reset_request = {
|
|
416
486
|
'action': args.action,
|
|
417
|
-
'
|
|
487
|
+
'sim_id': str(parsed_value), # Can be index (0-5) or public IP address only
|
|
418
488
|
'ip_to_reserve': our_ip,
|
|
419
489
|
'sim_id_override': args.instance_id,
|
|
420
490
|
'ensure_instance_is_running': False
|
avrs/race_cloud_cfg_util.py
CHANGED
|
@@ -78,13 +78,13 @@ def register_received_vehicle(team_name, slot, cfg_data, bsu_vcan, kistler_vcan,
|
|
|
78
78
|
if eav24 is None:
|
|
79
79
|
return (False, 'no eav24 payload found')
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
logger.info('disabling perception for received vehicle config')
|
|
82
|
+
eav24['body']['bLidarEnabled'] = False
|
|
83
83
|
eav24['body']['bCameraEnabled'] = False
|
|
84
84
|
eav24['body']['bRadarEnabled'] = False
|
|
85
|
-
|
|
85
|
+
eav24['body']['bPublishGroundTruth'] = False
|
|
86
86
|
eav24['body']['bPublishInputs'] = False
|
|
87
|
-
eav24['body']['bRenderHudInWorld'] =
|
|
87
|
+
eav24['body']['bRenderHudInWorld'] = True
|
|
88
88
|
|
|
89
89
|
# do not disable HUD
|
|
90
90
|
#logger.info('disabling hud for received vehicle config')
|
|
@@ -208,32 +208,6 @@ def register_received_vehicle(team_name, slot, cfg_data, bsu_vcan, kistler_vcan,
|
|
|
208
208
|
logger.info("opponentGroundTruthDsd rate was > 100. clamping")
|
|
209
209
|
gtc["body"]["opponentGroundTruthDsd"]["rateHz"] = 100
|
|
210
210
|
|
|
211
|
-
# clamp lidar rates
|
|
212
|
-
for payload in cfg_object['payloads']:
|
|
213
|
-
if payload['typeName'].lower() == 'genericlidaripd':
|
|
214
|
-
lidar_rate = payload.get("body", {}).get("sensorDesc", {}).get("dataStream", {}).get("rateHz", 0)
|
|
215
|
-
if lidar_rate > 20:
|
|
216
|
-
instance_name = payload.get("body", {}).get("componentConfig", {}).get("instanceName", "unknown")
|
|
217
|
-
logger.info("lidar {} rate was > 20. clamping".format(instance_name))
|
|
218
|
-
payload["body"]["sensorDesc"]["dataStream"]["rateHz"] = 20
|
|
219
|
-
|
|
220
|
-
# clamp camera rates
|
|
221
|
-
for payload in cfg_object['payloads']:
|
|
222
|
-
if payload['typeName'].lower() == 'camerasensor':
|
|
223
|
-
camera_rate = payload.get("body", {}).get("sensorDesc", {}).get("dataStream", {}).get("rateHz", 0)
|
|
224
|
-
if camera_rate > 20:
|
|
225
|
-
instance_name = payload.get("body", {}).get("componentConfig", {}).get("instanceName", "unknown")
|
|
226
|
-
logger.info("camera {} rate was > 20. clamping".format(instance_name))
|
|
227
|
-
payload["body"]["sensorDesc"]["dataStream"]["rateHz"] = 20
|
|
228
|
-
|
|
229
|
-
# clamp radar rates
|
|
230
|
-
for payload in cfg_object['payloads']:
|
|
231
|
-
if payload['typeName'].lower() == 'radarsensor':
|
|
232
|
-
radar_rate = payload.get("body", {}).get("sensorDesc", {}).get("dataStream", {}).get("rateHz", 0)
|
|
233
|
-
if radar_rate > 20:
|
|
234
|
-
instance_name = payload.get("body", {}).get("componentConfig", {}).get("instanceName", "unknown")
|
|
235
|
-
logger.info("radar {} rate was > 20. clamping".format(instance_name))
|
|
236
|
-
payload["body"]["sensorDesc"]["dataStream"]["rateHz"] = 20
|
|
237
211
|
|
|
238
212
|
# do not allow default object name (collision)
|
|
239
213
|
if cfg_object['name'] == 'eav24':
|
avrs/race_cloud_util.py
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import json
|
|
3
|
-
import http.client
|
|
4
3
|
import logging
|
|
4
|
+
import boto3
|
|
5
|
+
from botocore.auth import SigV4Auth
|
|
6
|
+
from botocore.awsrequest import AWSRequest
|
|
7
|
+
import urllib.request
|
|
5
8
|
from avrs.util import *
|
|
6
9
|
|
|
7
10
|
BASH_KILL_PROCESS_SCRIPT = '''
|
|
@@ -360,45 +363,55 @@ def call_race_cloud_api(body):
|
|
|
360
363
|
logger = logging.getLogger('avrs')
|
|
361
364
|
logger.info('calling race-cloud api with body: {}'.format(body))
|
|
362
365
|
|
|
363
|
-
|
|
366
|
+
url = 'https://9gca6018p0.execute-api.us-east-1.amazonaws.com/backend/race-connect'
|
|
367
|
+
region = 'us-east-1'
|
|
364
368
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
'x-api-key': '7aQ83sJ89Q2DZ8NdIi9aUTBuUS2uyix5QoDwrl1j'
|
|
369
|
-
}
|
|
370
|
-
body = json.dumps(body).encode('utf-8')
|
|
371
|
-
connection.request('POST', '/beta/connect', body, headers)
|
|
372
|
-
response = connection.getresponse()
|
|
373
|
-
if response.status != 200:
|
|
374
|
-
return (False, 'response had status code {}'.format(response))
|
|
375
|
-
return (True, response.read().decode('utf-8'))
|
|
376
|
-
|
|
377
|
-
def get_api_script_response(raw):
|
|
378
|
-
logger = logging.getLogger('avrs')
|
|
379
|
-
try:
|
|
380
|
-
parsed = json.loads(raw)
|
|
381
|
-
decoded = parsed['body']
|
|
369
|
+
# Get credentials from boto3 session (uses IAM role on EC2)
|
|
370
|
+
session = boto3.Session()
|
|
371
|
+
credentials = session.get_credentials()
|
|
382
372
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
decoded = json.loads(decoded)
|
|
373
|
+
# Prepare the request body
|
|
374
|
+
body_json = json.dumps(body)
|
|
386
375
|
|
|
387
|
-
|
|
376
|
+
# Create AWS request for signing
|
|
377
|
+
request = AWSRequest(
|
|
378
|
+
method='POST',
|
|
379
|
+
url=url,
|
|
380
|
+
data=body_json,
|
|
381
|
+
headers={'Content-Type': 'application/json'}
|
|
382
|
+
)
|
|
388
383
|
|
|
389
|
-
|
|
390
|
-
|
|
384
|
+
# Sign the request with SigV4
|
|
385
|
+
SigV4Auth(credentials, 'execute-api', region).add_auth(request)
|
|
391
386
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
387
|
+
# Make the request using urllib
|
|
388
|
+
try:
|
|
389
|
+
req = urllib.request.Request(
|
|
390
|
+
url,
|
|
391
|
+
data=body_json.encode('utf-8'),
|
|
392
|
+
headers=dict(request.headers),
|
|
393
|
+
method='POST'
|
|
394
|
+
)
|
|
395
|
+
with urllib.request.urlopen(req) as response:
|
|
396
|
+
response_body = response.read().decode('utf-8')
|
|
397
|
+
return (True, response_body)
|
|
398
|
+
except urllib.error.HTTPError as e:
|
|
399
|
+
error_body = e.read().decode('utf-8')
|
|
400
|
+
logger.error('API error - status: {}, body: {}'.format(e.code, error_body))
|
|
401
|
+
return (False, 'response had status code {} - {}'.format(e.code, error_body))
|
|
402
402
|
except Exception as e:
|
|
403
|
-
logger.error('
|
|
404
|
-
return (False, '
|
|
403
|
+
logger.error('API request failed: {}'.format(str(e)))
|
|
404
|
+
return (False, 'request failed: {}'.format(str(e)))
|
|
405
|
+
|
|
406
|
+
def get_api_script_response(raw):
|
|
407
|
+
logger = logging.getLogger('avrs')
|
|
408
|
+
# Parse API Gateway response, then parse the body which is also JSON string
|
|
409
|
+
api_response = json.loads(raw)
|
|
410
|
+
body_str = api_response['body']
|
|
411
|
+
# Body is a JSON string from Lambda Proxy integration
|
|
412
|
+
decoded = json.loads(body_str) if isinstance(body_str, str) else body_str
|
|
413
|
+
logger.info('race cloud api response: {}'.format(decoded))
|
|
414
|
+
if decoded['script_response']['statusCode'] != 200:
|
|
415
|
+
return (False, 'inner response had bad status code {}'.format(decoded))
|
|
416
|
+
#print(decoded)
|
|
417
|
+
return (True, json.loads(decoded['script_response']['body']), decoded['sim_private_ip'])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|