sima-cli 0.0.35__py3-none-any.whl → 0.0.36__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 +0 -1
- sima_cli/cli.py +5 -3
- sima_cli/download/downloader.py +32 -0
- sima_cli/install/metadata_installer.py +241 -7
- {sima_cli-0.0.35.dist-info → sima_cli-0.0.36.dist-info}/METADATA +1 -1
- {sima_cli-0.0.35.dist-info → sima_cli-0.0.36.dist-info}/RECORD +11 -11
- {sima_cli-0.0.35.dist-info → sima_cli-0.0.36.dist-info}/WHEEL +0 -0
- {sima_cli-0.0.35.dist-info → sima_cli-0.0.36.dist-info}/entry_points.txt +0 -0
- {sima_cli-0.0.35.dist-info → sima_cli-0.0.36.dist-info}/licenses/LICENSE +0 -0
- {sima_cli-0.0.35.dist-info → sima_cli-0.0.36.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.36"
|
sima_cli/auth/basic_auth.py
CHANGED
sima_cli/cli.py
CHANGED
@@ -313,9 +313,7 @@ def install_cmd(ctx, component, version, mirror, tag):
|
|
313
313
|
if component:
|
314
314
|
click.echo(f"⚠️ Component '{component}' is ignored when using --metadata. Proceeding with metadata-based installation.")
|
315
315
|
click.echo(f"🔧 Installing generic component from metadata URL: {mirror}")
|
316
|
-
|
317
|
-
click.echo("✅ Installation complete.")
|
318
|
-
return
|
316
|
+
return install_from_metadata(metadata_url=mirror, internal=internal)
|
319
317
|
|
320
318
|
# No component and no metadata: error
|
321
319
|
if not component:
|
@@ -324,6 +322,10 @@ def install_cmd(ctx, component, version, mirror, tag):
|
|
324
322
|
|
325
323
|
component = component.lower()
|
326
324
|
|
325
|
+
# if user specified gh: as component, treat it the same as -m
|
326
|
+
if component.startswith("gh:"):
|
327
|
+
return install_from_metadata(metadata_url=component, internal=False)
|
328
|
+
|
327
329
|
# Validate version requirement
|
328
330
|
if component in SDK_DEPENDENT_COMPONENTS and not version:
|
329
331
|
click.echo(f"❌ The component '{component}' requires a specific SDK version. Please provide one using -v.")
|
sima_cli/download/downloader.py
CHANGED
@@ -135,6 +135,38 @@ def download_file_from_url(url: str, dest_folder: str = ".", internal: bool = Fa
|
|
135
135
|
|
136
136
|
return dest_path
|
137
137
|
|
138
|
+
def check_url_available(url: str, internal: bool = False) -> bool:
|
139
|
+
"""
|
140
|
+
Perform a HEAD request to check if a resource is available.
|
141
|
+
|
142
|
+
Args:
|
143
|
+
url (str): The full URL to check.
|
144
|
+
internal (bool): Whether this is an internal resource on Artifactory.
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
bool: True if the resource is available (status 200–399), False otherwise.
|
148
|
+
"""
|
149
|
+
headers = {}
|
150
|
+
try:
|
151
|
+
if internal:
|
152
|
+
auth_token = get_auth_token(internal=True)
|
153
|
+
if auth_token:
|
154
|
+
headers["Authorization"] = f"Bearer {auth_token}"
|
155
|
+
head_fn = requests.head
|
156
|
+
elif 'https://docs.sima.ai' in url:
|
157
|
+
session = login_external()
|
158
|
+
head_fn = session.head
|
159
|
+
else:
|
160
|
+
session = requests.Session()
|
161
|
+
head_fn = session.head
|
162
|
+
|
163
|
+
resp = head_fn(url, headers=headers, timeout=10, allow_redirects=True)
|
164
|
+
# Consider any 2xx or 3xx as "available"
|
165
|
+
return 200 <= resp.status_code < 400
|
166
|
+
|
167
|
+
except Exception as e:
|
168
|
+
print(f"⚠️ HEAD check failed for {url}: {e}")
|
169
|
+
return False
|
138
170
|
|
139
171
|
def download_folder_from_url(url: str, dest_folder: str = ".", internal: bool = False) -> List[str]:
|
140
172
|
"""
|
@@ -15,6 +15,7 @@ from tqdm import tqdm
|
|
15
15
|
from urllib.parse import urljoin
|
16
16
|
from pathlib import Path
|
17
17
|
import subprocess
|
18
|
+
import requests
|
18
19
|
|
19
20
|
from rich.console import Console
|
20
21
|
from rich.panel import Panel
|
@@ -29,6 +30,153 @@ from sima_cli.install.metadata_info import print_metadata_summary, parse_size_st
|
|
29
30
|
|
30
31
|
console = Console()
|
31
32
|
|
33
|
+
def _copy_dir(src: Path, dest: Path, label: str):
|
34
|
+
"""
|
35
|
+
Copy files from src → dest, merging with existing files (no deletion).
|
36
|
+
Ensures that all parent directories for dest are created.
|
37
|
+
"""
|
38
|
+
if not src.exists():
|
39
|
+
raise FileNotFoundError(f"SDK {label} not found: {src}")
|
40
|
+
|
41
|
+
# Ensure full path exists
|
42
|
+
dest.mkdir(parents=True, exist_ok=True)
|
43
|
+
|
44
|
+
# Copy tree correctly
|
45
|
+
for item in src.iterdir():
|
46
|
+
target = dest / item.name
|
47
|
+
if item.is_dir():
|
48
|
+
shutil.copytree(item, target, dirs_exist_ok=True)
|
49
|
+
else:
|
50
|
+
shutil.copy2(item, target)
|
51
|
+
|
52
|
+
click.echo(f"✅ Copied {label} into {dest}")
|
53
|
+
|
54
|
+
def _prepare_pipeline_project(repo_dir: Path):
|
55
|
+
"""
|
56
|
+
Prepare a pipeline project by copying required SDK sources into the repo.
|
57
|
+
|
58
|
+
Steps:
|
59
|
+
1. Copy core sources into the project folder
|
60
|
+
2. Parse .project/pluginsInfo
|
61
|
+
3. Copy required plugin sources from the SDK plugin zoo
|
62
|
+
"""
|
63
|
+
plugins_info_file = repo_dir / ".project" / "pluginsInfo.json"
|
64
|
+
if not plugins_info_file.exists():
|
65
|
+
return
|
66
|
+
|
67
|
+
click.echo("📦 Preparing pipeline project...")
|
68
|
+
|
69
|
+
try:
|
70
|
+
data = json.loads(plugins_info_file.read_text())
|
71
|
+
plugins = data.get("pluginsInfo", [])
|
72
|
+
except Exception as e:
|
73
|
+
raise RuntimeError(f"Failed to read {plugins_info_file}: {e}")
|
74
|
+
|
75
|
+
# Step a: copy core
|
76
|
+
# Define what to copy
|
77
|
+
copy_map = [
|
78
|
+
(
|
79
|
+
Path("/usr/local/simaai/plugin_zoo/gst-simaai-plugins-base/core"),
|
80
|
+
repo_dir / "core",
|
81
|
+
"core"
|
82
|
+
),
|
83
|
+
(
|
84
|
+
Path("/usr/local/simaai/utils/gst_app"),
|
85
|
+
repo_dir / "dependencies" / "gst_app",
|
86
|
+
"dependencies/gst_app"
|
87
|
+
),
|
88
|
+
(
|
89
|
+
Path("/usr/local/simaai/plugin_zoo/gst-simaai-plugins-base/gst/templates"),
|
90
|
+
repo_dir / "plugins" / "templates",
|
91
|
+
"plugins/templates"
|
92
|
+
),
|
93
|
+
]
|
94
|
+
|
95
|
+
# Execute
|
96
|
+
for src, dest, label in copy_map:
|
97
|
+
_copy_dir(src, dest, label)
|
98
|
+
|
99
|
+
# Step b/c: scan plugin paths and copy SDK plugins
|
100
|
+
sdk_plugins_base = Path("/usr/local/simaai/plugin_zoo/gst-simaai-plugins-base/gst")
|
101
|
+
dest_plugins_dir = repo_dir / "plugins"
|
102
|
+
dest_plugins_dir.mkdir(exist_ok=True)
|
103
|
+
|
104
|
+
for plugin in plugins:
|
105
|
+
try:
|
106
|
+
path = plugin.get("path", "")
|
107
|
+
if not path:
|
108
|
+
continue
|
109
|
+
parts = path.split("/")
|
110
|
+
if len(parts) < 2:
|
111
|
+
continue
|
112
|
+
|
113
|
+
plugin_name = parts[1]
|
114
|
+
sdk_plugin_path = sdk_plugins_base / plugin_name
|
115
|
+
if not sdk_plugin_path.exists():
|
116
|
+
click.echo(
|
117
|
+
f"⚠️ Missing plugin source: {plugin_name} in the SDK, skipping. "
|
118
|
+
"It's possible that this is a custom plugin already exists in the repo"
|
119
|
+
)
|
120
|
+
continue
|
121
|
+
|
122
|
+
dest_plugin_path = dest_plugins_dir / plugin_name
|
123
|
+
dest_plugin_path.mkdir(parents=True, exist_ok=True)
|
124
|
+
|
125
|
+
# Merge instead of deleting
|
126
|
+
shutil.copytree(sdk_plugin_path, dest_plugin_path, dirs_exist_ok=True)
|
127
|
+
|
128
|
+
click.echo(f"✅ Copied plugin {plugin_name} into {dest_plugin_path}")
|
129
|
+
|
130
|
+
except Exception as e:
|
131
|
+
click.echo(f"❌ Error copying plugin {plugin}: {e}")
|
132
|
+
|
133
|
+
click.echo("🎉 Pipeline project prepared.")
|
134
|
+
|
135
|
+
def _download_github_repo(owner: str, repo: str, ref: str, dest_folder: str, token: str = None) -> str:
|
136
|
+
"""
|
137
|
+
Download and extract a GitHub repo tarball via the REST API (no git required).
|
138
|
+
|
139
|
+
Args:
|
140
|
+
owner (str): GitHub org/user
|
141
|
+
repo (str): Repo name
|
142
|
+
ref (str): Branch, tag, or commit (default = default branch)
|
143
|
+
dest_folder (str): Where to extract
|
144
|
+
token (str): Optional GitHub token for private repos
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
str: Path to the extracted repo
|
148
|
+
"""
|
149
|
+
url = f"https://api.github.com/repos/{owner}/{repo}/tarball/{ref}" if ref else f"https://api.github.com/repos/{owner}/{repo}/tarball"
|
150
|
+
headers = {}
|
151
|
+
if token:
|
152
|
+
headers["Authorization"] = f"Bearer {token}"
|
153
|
+
|
154
|
+
click.echo(f"🐙 Downloading GitHub repo: {owner}/{repo}" + (f"@{ref}" if ref else ""))
|
155
|
+
|
156
|
+
with requests.get(url, headers=headers, stream=True) as r:
|
157
|
+
if r.status_code in (401, 403):
|
158
|
+
raise PermissionError("Authentication required for GitHub repo")
|
159
|
+
r.raise_for_status()
|
160
|
+
|
161
|
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".tar.gz") as tmp_file:
|
162
|
+
for chunk in r.iter_content(chunk_size=8192):
|
163
|
+
tmp_file.write(chunk)
|
164
|
+
tmp_path = Path(tmp_file.name)
|
165
|
+
|
166
|
+
repo_dir = Path(dest_folder) / repo
|
167
|
+
repo_dir.mkdir(parents=True, exist_ok=True)
|
168
|
+
|
169
|
+
_extract_tar_strip_top_level(tmp_path, repo_dir)
|
170
|
+
tmp_path.unlink(missing_ok=True)
|
171
|
+
click.echo(f"✅ Downloaded GitHub repo to folder: {repo_dir}")
|
172
|
+
|
173
|
+
try:
|
174
|
+
_prepare_pipeline_project(repo_dir)
|
175
|
+
except Exception as e:
|
176
|
+
click.echo(f"⚠️ Pipeline preparation skipped: {e}")
|
177
|
+
|
178
|
+
return str(repo_dir)
|
179
|
+
|
32
180
|
def _download_assets(metadata: dict, base_url: str, dest_folder: str, internal: bool = False, skip_models: bool = False) -> list:
|
33
181
|
"""
|
34
182
|
Downloads resources defined in metadata to a local destination folder.
|
@@ -84,11 +232,34 @@ def _download_assets(metadata: dict, base_url: str, dest_folder: str, internal:
|
|
84
232
|
model_path = snapshot_download(
|
85
233
|
repo_id=repo_id,
|
86
234
|
local_dir=target_dir,
|
87
|
-
|
235
|
+
local_dir_use_symlinks=False
|
88
236
|
)
|
89
237
|
local_paths.append(model_path)
|
90
238
|
continue
|
91
239
|
|
240
|
+
if resource.startswith("gh:"):
|
241
|
+
resource_spec = resource[3:]
|
242
|
+
if "@" in resource_spec:
|
243
|
+
repo_id, ref = resource_spec.split("@", 1)
|
244
|
+
else:
|
245
|
+
repo_id, ref = resource_spec, None
|
246
|
+
|
247
|
+
if "/" not in repo_id:
|
248
|
+
raise click.ClickException(f"❌ Invalid GitHub repo spec: {resource}")
|
249
|
+
|
250
|
+
owner, name = repo_id.split("/", 1)
|
251
|
+
|
252
|
+
try:
|
253
|
+
token = os.getenv("GITHUB_TOKEN", None)
|
254
|
+
repo_path = _download_github_repo(owner, name, ref, dest_folder, token)
|
255
|
+
except Exception as e:
|
256
|
+
raise click.ClickException(
|
257
|
+
f"❌ Failed to download GitHub repo {owner}/{name}@{ref or 'default'}: {e}"
|
258
|
+
)
|
259
|
+
|
260
|
+
local_paths.append(repo_path)
|
261
|
+
continue
|
262
|
+
|
92
263
|
# Handle normal relative or absolute URLs
|
93
264
|
resource_url = urljoin(base_url, resource)
|
94
265
|
local_path = download_file_from_url(
|
@@ -296,6 +467,25 @@ def _extract_zip_streaming(zip_path: Path, extract_dir: Path, overwrite: bool =
|
|
296
467
|
|
297
468
|
print(f"✅ Extracted {len(members)} entries to {extract_dir}/")
|
298
469
|
|
470
|
+
def _extract_tar_strip_top_level(tar_path: Path, extract_dir: Path):
|
471
|
+
"""Extract a GitHub tarball, stripping the top-level folder."""
|
472
|
+
with tarfile.open(tar_path, "r:*") as tar:
|
473
|
+
members = tar.getmembers()
|
474
|
+
|
475
|
+
# Detect top-level prefix (first part before '/')
|
476
|
+
top_level = None
|
477
|
+
if members:
|
478
|
+
first_name = members[0].name
|
479
|
+
top_level = first_name.split("/", 1)[0]
|
480
|
+
|
481
|
+
for member in members:
|
482
|
+
# Strip top-level folder
|
483
|
+
if top_level and member.name.startswith(top_level + "/"):
|
484
|
+
member.name = member.name[len(top_level) + 1 :]
|
485
|
+
if not member.name:
|
486
|
+
continue
|
487
|
+
tar.extract(member, path=extract_dir)
|
488
|
+
|
299
489
|
def _combine_multipart_files(folder: str):
|
300
490
|
"""
|
301
491
|
Scan a folder for multipart files like name-split-aa, -ab, etc.,
|
@@ -353,20 +543,27 @@ def _combine_multipart_files(folder: str):
|
|
353
543
|
|
354
544
|
print(f"✅ Extracted to: {extract_dir}/")
|
355
545
|
|
356
|
-
def _extract_archives_in_folder(folder: str):
|
546
|
+
def _extract_archives_in_folder(folder: str, local_paths):
|
357
547
|
"""
|
358
|
-
Extract
|
548
|
+
Extract .tar, .gz, .tar.gz, and .zip files in the given folder,
|
549
|
+
but only if they are listed in local_paths.
|
359
550
|
Uses streaming to avoid NFS performance issues.
|
360
551
|
"""
|
361
552
|
folder = Path(folder)
|
553
|
+
local_paths = {str(Path(p).resolve()) for p in local_paths}
|
554
|
+
|
362
555
|
for file in folder.iterdir():
|
363
556
|
if not file.is_file():
|
364
557
|
continue
|
365
558
|
|
366
|
-
|
367
|
-
if
|
559
|
+
file_resolved = str(file.resolve())
|
560
|
+
if file_resolved not in local_paths:
|
561
|
+
continue
|
562
|
+
|
563
|
+
# TAR, GZ, TAR.GZ → all handled by _extract_tar_streaming
|
564
|
+
if file.suffix in [".tar", ".gz"] or file.name.endswith(".tar.gz"):
|
368
565
|
extract_dir = folder / file.stem.replace(".tar", "")
|
369
|
-
print(f"📦 Extracting TAR
|
566
|
+
print(f"📦 Extracting TAR/GZ: {file.name} to {extract_dir}/")
|
370
567
|
_extract_tar_streaming(file, extract_dir)
|
371
568
|
|
372
569
|
# ZIP
|
@@ -471,8 +668,45 @@ def _run_installation_script(metadata: Dict, extract_path: str = "."):
|
|
471
668
|
|
472
669
|
print("✅ Installation completed successfully.")
|
473
670
|
|
671
|
+
def _resolve_github_metadata_url(gh_ref: str) -> str:
|
672
|
+
"""
|
673
|
+
Resolve a GitHub shorthand like gh:org/repo@tag into a raw URL for metadata.json.
|
674
|
+
If tag is omitted, defaults to 'main'.
|
675
|
+
"""
|
676
|
+
try:
|
677
|
+
_, repo_ref = gh_ref.split(":", 1) # remove 'gh:'
|
678
|
+
if "@" in repo_ref:
|
679
|
+
org_repo, tag = repo_ref.split("@", 1)
|
680
|
+
else:
|
681
|
+
org_repo, tag = repo_ref, "main"
|
682
|
+
|
683
|
+
owner, repo = org_repo.split("/", 1)
|
684
|
+
token = os.getenv("GITHUB_TOKEN")
|
685
|
+
|
686
|
+
# Use GitHub API to fetch the metadata.json file
|
687
|
+
api_url = f"https://api.github.com/repos/{owner}/{repo}/contents/metadata.json?ref={tag}"
|
688
|
+
headers = {"Accept": "application/vnd.github.v3.raw"}
|
689
|
+
if token:
|
690
|
+
headers["Authorization"] = f"token {token}"
|
691
|
+
|
692
|
+
r = requests.get(api_url, headers=headers)
|
693
|
+
r.raise_for_status()
|
694
|
+
|
695
|
+
# Write metadata.json locally so downstream logic can use a file/URL
|
696
|
+
local_path = os.path.join("/tmp", f"{repo}-{tag}-metadata.json")
|
697
|
+
with open(local_path, "wb") as f:
|
698
|
+
f.write(r.content)
|
699
|
+
|
700
|
+
return local_path
|
701
|
+
except Exception as e:
|
702
|
+
raise RuntimeError(f"Failed to resolve GitHub metadata URL {gh_ref}: {e}")
|
703
|
+
|
474
704
|
def install_from_metadata(metadata_url: str, internal: bool, install_dir: str = '.'):
|
475
705
|
try:
|
706
|
+
if metadata_url.startswith("gh:"):
|
707
|
+
metadata_url = _resolve_github_metadata_url(metadata_url)
|
708
|
+
internal = False
|
709
|
+
|
476
710
|
metadata, _ = _download_and_validate_metadata(metadata_url, internal)
|
477
711
|
print_metadata_summary(metadata=metadata)
|
478
712
|
|
@@ -481,7 +715,7 @@ def install_from_metadata(metadata_url: str, internal: bool, install_dir: str =
|
|
481
715
|
local_paths = _download_assets(metadata, metadata_url, install_dir, internal)
|
482
716
|
if len(local_paths) > 0:
|
483
717
|
_combine_multipart_files(install_dir)
|
484
|
-
_extract_archives_in_folder(install_dir)
|
718
|
+
_extract_archives_in_folder(install_dir, local_paths)
|
485
719
|
_run_installation_script(metadata=metadata, extract_path=install_dir)
|
486
720
|
|
487
721
|
except Exception as e:
|
@@ -1,20 +1,20 @@
|
|
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=
|
4
|
-
sima_cli/cli.py,sha256=
|
3
|
+
sima_cli/__version__.py,sha256=Bbhf5gpY7WnVH4M-cc4ByQEC0_SMh5CebOd37T5sqCA,49
|
4
|
+
sima_cli/cli.py,sha256=qm8rtydcugVdd37Rd79weMdX78Y7SKWaUe4LGfX-1XY,17339
|
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=UMEXCCnNQpjpp6RZxREs6iiKtYyaeqZBnTSR0wA8s6Q,8767
|
9
9
|
sima_cli/auth/login.py,sha256=nE-dSHK_husXw1XJaEcOe3I1_bnwHkLgO_BqKuQODDM,3781
|
10
10
|
sima_cli/data/resources_internal.yaml,sha256=zlQD4cSnZK86bLtTWuvEudZTARKiuIKmB--Jv4ajL8o,200
|
11
11
|
sima_cli/data/resources_public.yaml,sha256=U7hmUomGeQ2ULdo1BU2OQHr0PyKBamIdK9qrutDlX8o,201
|
12
12
|
sima_cli/download/__init__.py,sha256=6y4O2FOCYFR2jdnQoVi3hRtEoZ0Gw6rydlTy1SGJ5FE,218
|
13
|
-
sima_cli/download/downloader.py,sha256=
|
13
|
+
sima_cli/download/downloader.py,sha256=UQdrBWLQsPQygaoVaufOjbzWmRoNnk6pgLdnbnVi04U,6436
|
14
14
|
sima_cli/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
15
|
sima_cli/install/hostdriver.py,sha256=kAWDLebs60mbWIyTbUxmNrChcKW1uD5r7FtWNSUVUE4,5852
|
16
16
|
sima_cli/install/metadata_info.py,sha256=wmMqwzGfXbuilkqaxRVrFOzOtTOiONkmPCyA2oDAQpA,2168
|
17
|
-
sima_cli/install/metadata_installer.py,sha256=
|
17
|
+
sima_cli/install/metadata_installer.py,sha256=zIxs9nSX7EC1d6qxL2woZiMSQfFfIOzB2natyTvIPDI,27428
|
18
18
|
sima_cli/install/metadata_validator.py,sha256=7954rp9vFRNnqmIMvCVTjq40kUIEbGXzfc8HmQmChe0,5221
|
19
19
|
sima_cli/install/optiview.py,sha256=r4DYdQDTUbZVCR87hl5T21gsjZrhqpU8hWnYxKmUJ_k,4790
|
20
20
|
sima_cli/install/palette.py,sha256=uRznoHa4Mv9ZXHp6AoqknfC3RxpYNKi9Ins756Cyifk,3930
|
@@ -46,7 +46,7 @@ sima_cli/utils/env.py,sha256=LtV8S1kCkOpi-7Gj4rhidQRN13x_NDKy4W_LxujheeI,8400
|
|
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.36.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.36.dist-info/METADATA,sha256=nRB0ysTR2pmyDNlBC6Tx7gk1VPJ6o83ZulKr99RLJTo,3705
|
59
|
+
sima_cli-0.0.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
60
|
+
sima_cli-0.0.36.dist-info/entry_points.txt,sha256=xRYrDq1nCs6R8wEdB3c1kKuimxEjWJkHuCzArQPT0Xk,47
|
61
|
+
sima_cli-0.0.36.dist-info/top_level.txt,sha256=FtrbAUdHNohtEPteOblArxQNwoX9_t8qJQd59fagDlc,15
|
62
|
+
sima_cli-0.0.36.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|