sima-cli 0.0.31__py3-none-any.whl → 0.0.33__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.
- sima_cli/__version__.py +1 -1
- sima_cli/auth/basic_auth.py +36 -5
- sima_cli/storage/sdcard.py +34 -5
- sima_cli/update/bootimg.py +1 -1
- sima_cli/update/updater.py +1 -1
- {sima_cli-0.0.31.dist-info → sima_cli-0.0.33.dist-info}/METADATA +1 -1
- {sima_cli-0.0.31.dist-info → sima_cli-0.0.33.dist-info}/RECORD +11 -11
- {sima_cli-0.0.31.dist-info → sima_cli-0.0.33.dist-info}/WHEEL +0 -0
- {sima_cli-0.0.31.dist-info → sima_cli-0.0.33.dist-info}/entry_points.txt +0 -0
- {sima_cli-0.0.31.dist-info → sima_cli-0.0.33.dist-info}/licenses/LICENSE +0 -0
- {sima_cli-0.0.31.dist-info → sima_cli-0.0.33.dist-info}/top_level.txt +0 -0
sima_cli/__version__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# sima_cli/__version__.py
|
2
|
-
__version__ = "0.0.
|
2
|
+
__version__ = "0.0.33"
|
sima_cli/auth/basic_auth.py
CHANGED
@@ -3,7 +3,10 @@ import click
|
|
3
3
|
import getpass
|
4
4
|
import requests
|
5
5
|
import json
|
6
|
+
import tempfile
|
7
|
+
|
6
8
|
from http.cookiejar import MozillaCookieJar
|
9
|
+
from sima_cli.__version__ import __version__
|
7
10
|
|
8
11
|
HOME_DIR = os.path.expanduser("~/.sima-cli")
|
9
12
|
COOKIE_JAR_PATH = os.path.join(HOME_DIR, ".sima-cli-cookies.txt")
|
@@ -11,10 +14,10 @@ CSRF_PATH = os.path.join(HOME_DIR, ".sima-cli-csrf.json")
|
|
11
14
|
|
12
15
|
CSRF_URL = "https://developer.sima.ai/session/csrf"
|
13
16
|
LOGIN_URL = "https://developer.sima.ai/session"
|
14
|
-
DUMMY_CHECK_URL = "https://docs.sima.ai/pkg_downloads/
|
17
|
+
DUMMY_CHECK_URL = "https://docs.sima.ai/pkg_downloads/validation"
|
15
18
|
|
16
19
|
HEADERS = {
|
17
|
-
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
|
20
|
+
"User-Agent": f"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) sima-cli/{__version__} Chrome/137.0.0.0 Safari/537.36",
|
18
21
|
"X-Requested-With": "XMLHttpRequest",
|
19
22
|
"Referer": "https://developer.sima.ai/login",
|
20
23
|
"Origin": "https://developer.sima.ai",
|
@@ -24,12 +27,39 @@ HEADERS = {
|
|
24
27
|
"sec-ch-ua-platform": '"macOS"',
|
25
28
|
}
|
26
29
|
|
30
|
+
def _handle_eula_flow(session: requests.Session, username: str, domain: str) -> bool:
|
31
|
+
try:
|
32
|
+
click.echo("\n📄 To continue, you must accept the End-User License Agreement (EULA).")
|
33
|
+
click.echo("👉 Please sign in to Developer Portal on your browser, then open the following URL to accept the EULA:")
|
34
|
+
click.echo(f"\n {DUMMY_CHECK_URL}\n")
|
35
|
+
|
36
|
+
if not click.confirm("✅ Have you completed the EULA form in your browser?", default=True):
|
37
|
+
click.echo("❌ EULA acceptance is required to continue.")
|
38
|
+
return False
|
39
|
+
|
40
|
+
return True
|
41
|
+
|
42
|
+
except Exception as e:
|
43
|
+
click.echo(f"❌ Error during EULA flow: {e}")
|
44
|
+
return False
|
27
45
|
|
28
46
|
def _is_session_valid(session: requests.Session) -> bool:
|
29
47
|
try:
|
30
48
|
response = session.get(DUMMY_CHECK_URL, allow_redirects=False)
|
31
|
-
|
32
|
-
|
49
|
+
|
50
|
+
if response.status_code == 200:
|
51
|
+
return True
|
52
|
+
elif response.status_code == 302:
|
53
|
+
location = response.headers.get("Location", "")
|
54
|
+
if "show-eula-form=1" in location:
|
55
|
+
return _handle_eula_flow(session, username="", domain="")
|
56
|
+
elif 'show-request-form=1' in location:
|
57
|
+
click.echo("❌ Your account is valid, but you do not have permission to download assets. Please contact your sales representative or email support@sima.ai for assistance.")
|
58
|
+
exit(0)
|
59
|
+
|
60
|
+
return False
|
61
|
+
except Exception as e:
|
62
|
+
click.echo(f"❌ Error validating session: {e}")
|
33
63
|
return False
|
34
64
|
|
35
65
|
def _delete_auth_files():
|
@@ -149,7 +179,7 @@ def login_external():
|
|
149
179
|
if _needs_totp(j):
|
150
180
|
# Try up to 3 TOTP attempts within this login attempt
|
151
181
|
for totp_try in range(1, 4):
|
152
|
-
totp = click.prompt(f"🔢 Enter TOTP code (attempt {totp_try}/3)", hide_input=True)
|
182
|
+
totp = click.prompt(f"🔢 Enter Time-based One Time Password (TOTP code) (attempt {totp_try}/3)", hide_input=True)
|
153
183
|
data = dict(base_data)
|
154
184
|
data["second_factor_token"] = totp
|
155
185
|
|
@@ -186,6 +216,7 @@ def login_external():
|
|
186
216
|
else:
|
187
217
|
err_detail = str(raw)[:200]
|
188
218
|
|
219
|
+
click.echo(f"❌ Server response code: {raw}")
|
189
220
|
click.echo(f"❌ Login failed. {err_detail or 'Please check your credentials and try again.'}")
|
190
221
|
|
191
222
|
click.echo("❌ Login failed after 3 attempts.")
|
sima_cli/storage/sdcard.py
CHANGED
@@ -10,8 +10,16 @@ from sima_cli.update.bootimg import list_removable_devices, unmount_device, _req
|
|
10
10
|
from sima_cli.utils.env import is_sima_board
|
11
11
|
|
12
12
|
def get_partition_path(device: str) -> str:
|
13
|
-
"""
|
14
|
-
|
13
|
+
"""
|
14
|
+
Return the first partition path for a raw block device.
|
15
|
+
/dev/sdX -> /dev/sdX1
|
16
|
+
/dev/mmcblk0 -> /dev/mmcblk0p1
|
17
|
+
/dev/nvme0n1 -> /dev/nvme0n1p1
|
18
|
+
"""
|
19
|
+
base = os.path.basename(device)
|
20
|
+
if base.startswith(("mmcblk", "nvme", "loop")):
|
21
|
+
return f"{device}p1"
|
22
|
+
return f"{device}1"
|
15
23
|
|
16
24
|
|
17
25
|
def find_mkfs_ext4() -> str:
|
@@ -68,11 +76,16 @@ def kill_partition_users(device_path: str):
|
|
68
76
|
click.echo(f"⚠️ Could not resolve partition users: {e}")
|
69
77
|
|
70
78
|
def create_partition_table(device_path: str):
|
71
|
-
"""
|
79
|
+
"""Create GPT with one full-disk ext4 partition and wait for it to appear."""
|
72
80
|
click.echo(f"🧹 Wiping and partitioning {device_path} using parted (Linux)")
|
81
|
+
# fresh label
|
73
82
|
subprocess.run(["sudo", "parted", "-s", device_path, "mklabel", "gpt"], check=True)
|
74
|
-
|
75
|
-
subprocess.run(["sudo", "
|
83
|
+
# aligned first partition (start at 1MiB, avoid metadata area)
|
84
|
+
subprocess.run(["sudo", "parted", "-s", device_path, "mkpart", "primary", "ext4", "1MiB", "100%"], check=True)
|
85
|
+
|
86
|
+
# Tell kernel and udev, then wait for the node
|
87
|
+
subprocess.run(["sudo", "partprobe", device_path], check=False)
|
88
|
+
subprocess.run(["sudo", "udevadm", "settle"], check=False)
|
76
89
|
|
77
90
|
|
78
91
|
def force_release_device(device_path: str):
|
@@ -97,6 +110,18 @@ def force_release_device(device_path: str):
|
|
97
110
|
subprocess.run(["sudo", "partprobe"], stderr=subprocess.DEVNULL)
|
98
111
|
subprocess.run(["sudo", "udevadm", "settle"], stderr=subprocess.DEVNULL)
|
99
112
|
|
113
|
+
def wait_for_partition(partition_path: str, timeout_s: float = 10.0):
|
114
|
+
"""Poll until /dev/… partition node exists or timeout."""
|
115
|
+
t0 = time.time()
|
116
|
+
while time.time() - t0 < timeout_s:
|
117
|
+
if os.path.exists(partition_path):
|
118
|
+
return True
|
119
|
+
# help the kernel notice changes, harmless if not needed
|
120
|
+
subprocess.run(["sudo", "partprobe"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
121
|
+
subprocess.run(["sudo", "udevadm", "settle"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
122
|
+
time.sleep(0.25)
|
123
|
+
return False
|
124
|
+
|
100
125
|
|
101
126
|
def sdcard_format():
|
102
127
|
"""Linux-only SD card formatter for ext4."""
|
@@ -150,6 +175,10 @@ def sdcard_format():
|
|
150
175
|
create_partition_table(selected_path)
|
151
176
|
partition_path = get_partition_path(selected_path)
|
152
177
|
|
178
|
+
if not wait_for_partition(partition_path, timeout_s=15):
|
179
|
+
click.echo(f"❌ Partition node did not appear: {partition_path}")
|
180
|
+
sys.exit(1)
|
181
|
+
|
153
182
|
click.echo(f"🧱 Formatting partition {partition_path} as ext4 using {mkfs_path}")
|
154
183
|
subprocess.run(["sudo", mkfs_path, "-F", partition_path], check=True)
|
155
184
|
|
sima_cli/update/bootimg.py
CHANGED
@@ -132,7 +132,7 @@ def unmount_device(device_path):
|
|
132
132
|
if result.returncode == 0:
|
133
133
|
click.echo(f"✅ Unmounted {device_path} on Linux")
|
134
134
|
elif "not mounted" in result.stderr.lower():
|
135
|
-
click.echo(f"ℹ️
|
135
|
+
click.echo(f"ℹ️ {device_path} was not mounted. Continuing.")
|
136
136
|
else:
|
137
137
|
click.echo(f"❌ Failed to unmount {device_path}: {result.stderr.strip()}")
|
138
138
|
sys.exit(1)
|
sima_cli/update/updater.py
CHANGED
@@ -513,7 +513,7 @@ def perform_update(version_or_url: str, ip: str = None, internal: bool = False,
|
|
513
513
|
if board in ['davinci', 'modalix']:
|
514
514
|
click.echo(f"🔧 Target board: {board} : {fdt_name}, board currently running: {version}, full_image: {full_image}")
|
515
515
|
|
516
|
-
if flavor == 'full' and
|
516
|
+
if flavor == 'full' and 'modalix' not in fdt_name:
|
517
517
|
click.echo(f"❌ You've requested updating {fdt_name} to full image, this is only supported for the Modalix DevKit")
|
518
518
|
return
|
519
519
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
sima_cli/__init__.py,sha256=Nb2jSg9-CX1XvSc1c21U9qQ3atINxphuNkNfmR-9P3o,332
|
2
2
|
sima_cli/__main__.py,sha256=ehzD6AZ7zGytC2gLSvaJatxeD0jJdaEvNJvwYeGsWOg,69
|
3
|
-
sima_cli/__version__.py,sha256=
|
3
|
+
sima_cli/__version__.py,sha256=3ahnchILqB7qDs5_EQeH5x6nIg_PgKEwGZZ5MOomFCg,49
|
4
4
|
sima_cli/cli.py,sha256=uCZ-9mKBGyGtfx3p97WZkdMjXL2KJlqihfZm8VsWiqw,17220
|
5
5
|
sima_cli/app_zoo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
sima_cli/app_zoo/app.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
7
|
sima_cli/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
-
sima_cli/auth/basic_auth.py,sha256=
|
8
|
+
sima_cli/auth/basic_auth.py,sha256=ht_mVXBtxV2UGvUYwvhkPHs4cMWL5Hw2B_OFxWdKw6c,8825
|
9
9
|
sima_cli/auth/login.py,sha256=yCYXWgrfbP4jSTZ3hITfxlgHkdVQVzsd8hQKpqaqCKs,3780
|
10
10
|
sima_cli/data/resources_internal.yaml,sha256=zlQD4cSnZK86bLtTWuvEudZTARKiuIKmB--Jv4ajL8o,200
|
11
11
|
sima_cli/data/resources_public.yaml,sha256=U7hmUomGeQ2ULdo1BU2OQHr0PyKBamIdK9qrutDlX8o,201
|
@@ -27,16 +27,16 @@ sima_cli/sdk/syscheck.py,sha256=h9zCULW67y4i2hqiGc-hc1ucBDShA5FAe9NxwBGq-fM,4575
|
|
27
27
|
sima_cli/serial/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
28
|
sima_cli/serial/serial.py,sha256=c5k0H2BTJGGCfysmBX1Ijp2pUT9serwdmE6_WyLUiQs,8664
|
29
29
|
sima_cli/storage/nvme.py,sha256=cCzYWcyPwcFu5pSMBkovsS4EwovaIMGolhEFStogXMA,4739
|
30
|
-
sima_cli/storage/sdcard.py,sha256
|
30
|
+
sima_cli/storage/sdcard.py,sha256=50JPL75-ivWe0Kn34bvCXujj111p7Ih0c_OwZCkQznA,7530
|
31
31
|
sima_cli/update/__init__.py,sha256=0P-z-rSaev40IhfJXytK3AFWv2_sdQU4Ry6ei2sEus0,66
|
32
32
|
sima_cli/update/bmaptool.py,sha256=KrhUGShBwY4Wzz50QiuMYAxxPgEy1nz5C68G-0a4qF4,4988
|
33
|
-
sima_cli/update/bootimg.py,sha256=
|
33
|
+
sima_cli/update/bootimg.py,sha256=OA_GyZwI8dbU3kaucKmoxAZbnnSnjXeOkU6yuDPji1k,13632
|
34
34
|
sima_cli/update/cleanlog.py,sha256=-V6eDl3MdsvDmCfkKUJTqkXJ_WnLJE01uxS7z96b15g,909
|
35
35
|
sima_cli/update/local.py,sha256=yOMvOu9nrODEzYZBrxUpdmlfqmkahkDk9nAEuG4RyAg,5588
|
36
36
|
sima_cli/update/netboot.py,sha256=hsJQLq4HVwFFkaWjA54VZdkMGDhO0RmylciS78qAfrM,19663
|
37
37
|
sima_cli/update/query.py,sha256=6RgvQfQT1_EtBGcibvVcz003dRKOq17NaGgL2mhaBbY,4891
|
38
38
|
sima_cli/update/remote.py,sha256=dAMIGpHqpf7VBps9JPe4hfHD_qyi1tG6ZW8E_qXQQiQ,14446
|
39
|
-
sima_cli/update/updater.py,sha256=
|
39
|
+
sima_cli/update/updater.py,sha256=UEWcV3wZbikNaTMk1nWFGiciBwUZtdX94reZWn22plk,24213
|
40
40
|
sima_cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
41
|
sima_cli/utils/artifactory.py,sha256=6YyVpzVm8ATy7NEwT9nkWx-wptkXrvG7Wl_zDT6jmLs,2390
|
42
42
|
sima_cli/utils/config.py,sha256=wE-cPQqY_gOqaP8t01xsRHD9tBUGk9MgBUm2GYYxI3E,1616
|
@@ -46,7 +46,7 @@ sima_cli/utils/env.py,sha256=IP5HrH0lE7RMSiBeXcEt5GCLMT5p-QQroG-uGzl5XFU,8181
|
|
46
46
|
sima_cli/utils/net.py,sha256=WVntA4CqipkNrrkA4tBVRadJft_pMcGYh4Re5xk3rqo,971
|
47
47
|
sima_cli/utils/network.py,sha256=UvqxbqbWUczGFyO-t1SybG7Q-x9kjUVRNIn_D6APzy8,1252
|
48
48
|
sima_cli/utils/pkg_update_check.py,sha256=IAV_NAOsBDL_lYNYMRYfdZWuVq-rJ_zzHjJJZ7UQaoc,3274
|
49
|
-
sima_cli-0.0.
|
49
|
+
sima_cli-0.0.33.dist-info/licenses/LICENSE,sha256=a260OFuV4SsMZ6sQCkoYbtws_4o2deFtbnT9kg7Rfd4,1082
|
50
50
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
51
|
tests/test_app_zoo.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
52
52
|
tests/test_auth.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -55,8 +55,8 @@ tests/test_download.py,sha256=t87DwxlHs26_ws9rpcHGwr_OrcRPd3hz6Zmm0vRee2U,4465
|
|
55
55
|
tests/test_firmware.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
56
56
|
tests/test_model_zoo.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
57
|
tests/test_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
58
|
-
sima_cli-0.0.
|
59
|
-
sima_cli-0.0.
|
60
|
-
sima_cli-0.0.
|
61
|
-
sima_cli-0.0.
|
62
|
-
sima_cli-0.0.
|
58
|
+
sima_cli-0.0.33.dist-info/METADATA,sha256=sB-Dp9MaVUhAwlWCum4LvSNdyFdUZJmoqgCa88qH8Ug,3705
|
59
|
+
sima_cli-0.0.33.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
60
|
+
sima_cli-0.0.33.dist-info/entry_points.txt,sha256=xRYrDq1nCs6R8wEdB3c1kKuimxEjWJkHuCzArQPT0Xk,47
|
61
|
+
sima_cli-0.0.33.dist-info/top_level.txt,sha256=FtrbAUdHNohtEPteOblArxQNwoX9_t8qJQd59fagDlc,15
|
62
|
+
sima_cli-0.0.33.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|