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 CHANGED
@@ -1,2 +1,2 @@
1
1
  # sima_cli/__version__.py
2
- __version__ = "0.0.31"
2
+ __version__ = "0.0.33"
@@ -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/dummy"
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
- return response.status_code == 200
32
- except Exception:
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.")
@@ -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
- """For Linux: partition is device + '1'"""
14
- return device + "1"
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
- """Linux: create a GPT partition table with one ext4 partition"""
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
- subprocess.run(["sudo", "parted", "-s", device_path, "mkpart", "primary", "ext4", "0%", "100%"], check=True)
75
- subprocess.run(["sudo", "partprobe", device_path], check=True)
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
 
@@ -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"ℹ️ {device_path} was not mounted. Continuing.")
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)
@@ -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 fdt_name != 'modalix-som':
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sima-cli
3
- Version: 0.0.31
3
+ Version: 0.0.33
4
4
  Summary: CLI tool for SiMa Developer Portal to download models, firmware, and apps.
5
5
  Home-page: https://developer.sima.ai/
6
6
  Author: SiMa.ai
@@ -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=5Ig2ah-U3Zaaf5Y1Kp0steH9WKPAxGvzGGgVTVSg_tY,49
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=mEmPrj32TVu1s34xR_UrJlIKHA3xBh98i_FzIZvAWag,7364
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=-WULjdV31-n8v5OOqfxR77qBbIK4hJnrD3xWxUVMoGI,6324
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=Eg8ZSp8LMZXbOMxX4ZPCjFOg3YEufmsVfojKrRc3fug,13631
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=Bi-9apDXJlnQg_sUQ46rQPXD6zbx4uE_JhXbfJIGBxE,24213
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.31.dist-info/licenses/LICENSE,sha256=a260OFuV4SsMZ6sQCkoYbtws_4o2deFtbnT9kg7Rfd4,1082
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.31.dist-info/METADATA,sha256=Q18Y7rOEEqe3ejP7IMqt5H6F3KipuWjUk15o_UwSIpg,3705
59
- sima_cli-0.0.31.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
60
- sima_cli-0.0.31.dist-info/entry_points.txt,sha256=xRYrDq1nCs6R8wEdB3c1kKuimxEjWJkHuCzArQPT0Xk,47
61
- sima_cli-0.0.31.dist-info/top_level.txt,sha256=FtrbAUdHNohtEPteOblArxQNwoX9_t8qJQd59fagDlc,15
62
- sima_cli-0.0.31.dist-info/RECORD,,
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,,