ap-client 0.5.3.dev2__tar.gz → 0.5.3.dev3__tar.gz
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.
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/PKG-INFO +1 -1
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/ossutil_commands.py +61 -8
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/ossutil_io.py +1 -1
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/pyproject.toml +1 -1
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/__init__.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/akpool_commands.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/api.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/cli.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/config.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/dataset_commands.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/dataset_register.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/exporter.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/fs_commands.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/instance_commands.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/irepo_sdk.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/managed_ak.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/manifest_view.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/profile_commands.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/repo_read_guard.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/share_api.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/split_publish.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/tbb.py +0 -0
- {ap_client-0.5.3.dev2 → ap_client-0.5.3.dev3}/ap_client/waiter.py +0 -0
|
@@ -42,16 +42,62 @@ def _format(value: Optional[str]) -> str:
|
|
|
42
42
|
return _normalize_output_format(value, keep_table=True)
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
def
|
|
45
|
+
def _tree(entries: list[dict], root: str) -> None:
|
|
46
|
+
from rich.console import Console
|
|
47
|
+
from rich.text import Text
|
|
48
|
+
from rich.tree import Tree
|
|
49
|
+
|
|
50
|
+
base = root.rstrip("/") + "/" if root else ""
|
|
51
|
+
if entries and not all(row["path"].startswith(base) for row in entries):
|
|
52
|
+
base = root.rsplit("/", 1)[0] + "/" if "/" in root else ""
|
|
53
|
+
tree = Tree(Text(base or "./", style="bold cyan"), guide_style="dim")
|
|
54
|
+
nodes: dict = {}
|
|
55
|
+
for row in entries:
|
|
56
|
+
relative = row["path"][len(base) :] if row["path"].startswith(base) else row["path"]
|
|
57
|
+
if not relative.rstrip("/"):
|
|
58
|
+
continue
|
|
59
|
+
parts = relative.rstrip("/").split("/")
|
|
60
|
+
children = nodes
|
|
61
|
+
for index, part in enumerate(parts):
|
|
62
|
+
directory = (
|
|
63
|
+
index < len(parts) - 1 or row["type"] == "directory" or row["path"].endswith("/")
|
|
64
|
+
)
|
|
65
|
+
key = (part, directory)
|
|
66
|
+
node = children.setdefault(key, {"children": {}})
|
|
67
|
+
if index == len(parts) - 1:
|
|
68
|
+
node["size"] = row.get("size")
|
|
69
|
+
children = node["children"]
|
|
70
|
+
|
|
71
|
+
def add(parent, children):
|
|
72
|
+
for (name, directory), node in sorted(
|
|
73
|
+
children.items(), key=lambda item: (not item[0][1], item[0][0].casefold(), item[0][0])
|
|
74
|
+
):
|
|
75
|
+
label = Text(name + ("/" if directory else ""), style="bold blue" if directory else "")
|
|
76
|
+
if not directory and node.get("size") is not None:
|
|
77
|
+
size = float(node["size"])
|
|
78
|
+
unit = "B"
|
|
79
|
+
for unit in ("B", "KiB", "MiB", "GiB", "TiB"):
|
|
80
|
+
if size < 1024 or unit == "TiB":
|
|
81
|
+
break
|
|
82
|
+
size /= 1024
|
|
83
|
+
label.append(f" {int(size) if unit == 'B' else f'{size:.1f}'} {unit}", style="dim")
|
|
84
|
+
add(parent.add(label), node["children"])
|
|
85
|
+
|
|
86
|
+
add(tree, nodes)
|
|
87
|
+
Console().print(tree)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _emit(value: dict, output_format: str, *, short: bool = False, root: str = "") -> None:
|
|
46
91
|
if output_format in ("json", "yaml"):
|
|
47
92
|
from .cli import _print_formatted
|
|
48
93
|
|
|
49
94
|
_print_formatted(value, output_format)
|
|
50
95
|
elif "entries" in value:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
row["path"]
|
|
54
|
-
|
|
96
|
+
if short:
|
|
97
|
+
for row in value["entries"]:
|
|
98
|
+
typer.echo(row["path"])
|
|
99
|
+
else:
|
|
100
|
+
_tree(value["entries"], root)
|
|
55
101
|
if value["is_truncated"]:
|
|
56
102
|
typer.echo(
|
|
57
103
|
"Listing truncated; continue with --marker " + value["next_marker"], err=True
|
|
@@ -88,6 +134,7 @@ def _fail(exc: Exception) -> None:
|
|
|
88
134
|
def oss_ls(
|
|
89
135
|
path: str = typer.Argument(..., help="Full oss:// URI or prefix relative to repo-config"),
|
|
90
136
|
directory: bool = typer.Option(False, "--directory", "-d", help="List only the current level"),
|
|
137
|
+
recursive: bool = typer.Option(False, "--recursive", "-r", help="Expand all directory levels"),
|
|
91
138
|
short: bool = typer.Option(False, "--short-format", "-s", help="Print only paths"),
|
|
92
139
|
limited_num: Optional[int] = typer.Option(None, "--limited-num", min=1),
|
|
93
140
|
marker: str = typer.Option("", "--marker", help="Resume after this OSS URI or relative path"),
|
|
@@ -97,15 +144,20 @@ def oss_ls(
|
|
|
97
144
|
payer: Optional[str] = typer.Option(None, "--payer"),
|
|
98
145
|
output_format: Optional[str] = typer.Option(None, "--output-format", "--format"),
|
|
99
146
|
):
|
|
100
|
-
"""
|
|
147
|
+
"""Show one directory level as a tree; use -r to expand all levels."""
|
|
101
148
|
try:
|
|
102
149
|
fmt = _format(output_format)
|
|
150
|
+
if recursive and directory:
|
|
151
|
+
raise OssUsageError("Use either --recursive or --directory")
|
|
103
152
|
files = _files()
|
|
104
153
|
_configure(files, encoding_type, payer)
|
|
154
|
+
remote = (
|
|
155
|
+
files.resolve(path, prefix=True) if recursive else files.resolve(path, directory=True)
|
|
156
|
+
)
|
|
105
157
|
_emit(
|
|
106
158
|
files.list(
|
|
107
|
-
|
|
108
|
-
recursive=
|
|
159
|
+
remote,
|
|
160
|
+
recursive=recursive,
|
|
109
161
|
limit=limited_num,
|
|
110
162
|
marker=marker,
|
|
111
163
|
include=tuple(include or ()),
|
|
@@ -113,6 +165,7 @@ def oss_ls(
|
|
|
113
165
|
),
|
|
114
166
|
fmt,
|
|
115
167
|
short=short,
|
|
168
|
+
root=remote.path,
|
|
116
169
|
)
|
|
117
170
|
except Exception as exc:
|
|
118
171
|
_fail(exc)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ap-client"
|
|
7
|
-
version = "0.5.3.
|
|
7
|
+
version = "0.5.3.dev3"
|
|
8
8
|
description = "Agent Platform API Client & CLI"
|
|
9
9
|
readme = { text = "A lightweight Python SDK and command line interface for Agent Platform. It provides helpers for configuring API access and managing templates, datasets, jobs, and groups.", content-type = "text/markdown" }
|
|
10
10
|
requires-python = ">=3.10"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|