ap-client 0.6.0.dev2__tar.gz → 0.6.1.dev0__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.6.0.dev2 → ap_client-0.6.1.dev0}/PKG-INFO +5 -3
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/api.py +1 -33
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/cli.py +6 -72
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/dataset_commands.py +46 -12
- ap_client-0.6.1.dev0/ap_client/dataset_name.py +53 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/dataset_register.py +20 -6
- ap_client-0.6.1.dev0/ap_client/dfs_commands.py +680 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/instance_commands.py +519 -52
- ap_client-0.6.1.dev0/ap_client/instance_options.py +94 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/irepo_sdk.py +69 -1
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/managed_ak.py +5 -16
- ap_client-0.6.1.dev0/ap_client/ossutil_hash.py +329 -0
- ap_client-0.6.1.dev0/ap_client/ossutil_io.py +1168 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/repo_read_guard.py +6 -2
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/split_publish.py +1 -1
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/pyproject.toml +6 -3
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/__init__.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/akpool_commands.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/config.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/exporter.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/fs_commands.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/manifest_view.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/profile_commands.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/share_api.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/tbb.py +0 -0
- {ap_client-0.6.0.dev2 → ap_client-0.6.1.dev0}/ap_client/waiter.py +0 -0
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: ap-client
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.1.dev0
|
|
4
4
|
Summary: Agent Platform API Client & CLI
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: click>=8.0.0
|
|
6
7
|
Requires-Dist: irepo-artifact==0.2.1
|
|
7
8
|
Requires-Dist: pyyaml>=6.0
|
|
8
9
|
Requires-Dist: requests>=2.28.0
|
|
9
10
|
Requires-Dist: rich>=13.0.0
|
|
10
11
|
Requires-Dist: typer>=0.9.0
|
|
12
|
+
Requires-Dist: urllib3>=1.26
|
|
11
13
|
Requires-Dist: websockets>=13.0
|
|
12
14
|
Provides-Extra: all
|
|
13
|
-
Requires-Dist: instance-repo[oss]<2.0.0,>=1.
|
|
15
|
+
Requires-Dist: instance-repo[oss]<2.0.0,>=1.4.0.dev3; extra == 'all'
|
|
14
16
|
Provides-Extra: dataset
|
|
15
|
-
Requires-Dist: instance-repo[oss]<2.0.0,>=1.
|
|
17
|
+
Requires-Dist: instance-repo[oss]<2.0.0,>=1.4.0.dev3; extra == 'dataset'
|
|
16
18
|
Description-Content-Type: text/markdown
|
|
17
19
|
|
|
18
20
|
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.
|
|
@@ -1125,15 +1125,8 @@ class APIClient:
|
|
|
1125
1125
|
benchmark: Optional[str] = None,
|
|
1126
1126
|
experiment: Optional[str] = None,
|
|
1127
1127
|
ak_ids: Optional[list[str]] = None,
|
|
1128
|
-
priority: Optional[str] = None,
|
|
1129
|
-
priority_weight: Optional[int] = None,
|
|
1130
1128
|
) -> dict:
|
|
1131
|
-
"""Create a group
|
|
1132
|
-
|
|
1133
|
-
Omitted priority fields use the server defaults: medium and weight 0.
|
|
1134
|
-
"""
|
|
1135
|
-
if priority is not None and priority not in {"high", "medium"}:
|
|
1136
|
-
raise ValueError("priority must be one of high/medium")
|
|
1129
|
+
"""Create a group."""
|
|
1137
1130
|
if ak_ids is not None and not isinstance(ak_ids, list):
|
|
1138
1131
|
raise ValueError("ak_ids must be a list")
|
|
1139
1132
|
references = list(ak_ids or [])
|
|
@@ -1171,10 +1164,6 @@ class APIClient:
|
|
|
1171
1164
|
body["queue_id"] = effective_queue_id
|
|
1172
1165
|
if max_concurrency is not None:
|
|
1173
1166
|
body["max_concurrency"] = max_concurrency
|
|
1174
|
-
if priority is not None:
|
|
1175
|
-
body["priority"] = priority
|
|
1176
|
-
if priority_weight is not None:
|
|
1177
|
-
body["priority_weight"] = priority_weight
|
|
1178
1167
|
if eval_config is not None:
|
|
1179
1168
|
body["eval_config"] = eval_config
|
|
1180
1169
|
if model_base_url_collection is not None:
|
|
@@ -1893,9 +1882,6 @@ class APIClient:
|
|
|
1893
1882
|
meta_teacher_direction: Optional[str] = None,
|
|
1894
1883
|
meta_train_stage: Optional[str] = None,
|
|
1895
1884
|
benchmark: Optional[str] = None,
|
|
1896
|
-
priority: Optional[str] = None,
|
|
1897
|
-
priority_weight: Optional[int] = None,
|
|
1898
|
-
priority_update_mode: Optional[str] = None,
|
|
1899
1885
|
) -> dict:
|
|
1900
1886
|
"""Update group properties.
|
|
1901
1887
|
|
|
@@ -1908,19 +1894,7 @@ class APIClient:
|
|
|
1908
1894
|
``meta_*`` 独立属性为部分更新(传了才改,不支持清除);新服务端
|
|
1909
1895
|
优先读属性,老服务端忽略属性——因此过渡期内同时也会将属性合并进
|
|
1910
1896
|
tags 轨(双写)。
|
|
1911
|
-
|
|
1912
|
-
Priority changes update the Group defaults. The default existing mode
|
|
1913
|
-
also updates all current Jobs, including PostProcess; incremental mode
|
|
1914
|
-
changes only the defaults for future Jobs. Updating priority alone uses
|
|
1915
|
-
weight 0; updating only weight preserves the current priority tier.
|
|
1916
1897
|
"""
|
|
1917
|
-
if priority is not None and priority not in {"high", "medium"}:
|
|
1918
|
-
raise ValueError("priority must be one of high/medium")
|
|
1919
|
-
if priority_update_mode is not None:
|
|
1920
|
-
if priority_update_mode not in {"existing", "incremental"}:
|
|
1921
|
-
raise ValueError("priority_update_mode must be one of existing/incremental")
|
|
1922
|
-
if priority is None and priority_weight is None:
|
|
1923
|
-
raise ValueError("priority_update_mode requires priority or priority_weight")
|
|
1924
1898
|
body: dict = {}
|
|
1925
1899
|
|
|
1926
1900
|
if max_concurrency is not None:
|
|
@@ -1937,12 +1911,6 @@ class APIClient:
|
|
|
1937
1911
|
body["scaffold"] = scaffold
|
|
1938
1912
|
if benchmark is not None:
|
|
1939
1913
|
body["benchmark"] = benchmark
|
|
1940
|
-
if priority is not None:
|
|
1941
|
-
body["priority"] = priority
|
|
1942
|
-
if priority_weight is not None:
|
|
1943
|
-
body["priority_weight"] = priority_weight
|
|
1944
|
-
if priority_update_mode is not None:
|
|
1945
|
-
body["priority_update_mode"] = priority_update_mode
|
|
1946
1914
|
meta_attr_tags = _merge_meta_tags(
|
|
1947
1915
|
None,
|
|
1948
1916
|
meta_model=meta_model,
|
|
@@ -25,6 +25,7 @@ from ap_client.api import (
|
|
|
25
25
|
)
|
|
26
26
|
from ap_client.config import ENV_VAR_SPECS, ConfigurationError, _parse_bool, normalize_output_format
|
|
27
27
|
from ap_client.dataset_commands import register as _register_dataset_commands
|
|
28
|
+
from ap_client.dfs_commands import register as _register_dfs_commands
|
|
28
29
|
from ap_client.exporter import export_group, export_job, export_jobs
|
|
29
30
|
from ap_client.fs_commands import register as _register_fs_commands
|
|
30
31
|
from ap_client.instance_commands import register as _register_instance_commands
|
|
@@ -167,6 +168,7 @@ app.add_typer(checkpoint_app, name="checkpoint")
|
|
|
167
168
|
# ap dataset version/split/access 嵌套在 dataset 下;instance/fs 是一等资源。
|
|
168
169
|
_register_dataset_commands(dataset_app)
|
|
169
170
|
_register_instance_commands(app)
|
|
171
|
+
_register_dfs_commands(app)
|
|
170
172
|
_register_fs_commands(app)
|
|
171
173
|
_register_akpool_commands(app)
|
|
172
174
|
|
|
@@ -642,18 +644,7 @@ def _print_formatted(data: dict, output_format: str) -> None:
|
|
|
642
644
|
import yaml
|
|
643
645
|
except ImportError as exc:
|
|
644
646
|
raise typer.BadParameter("--format yaml requires PyYAML to be installed") from exc
|
|
645
|
-
|
|
646
|
-
class LosslessDumper(yaml.SafeDumper):
|
|
647
|
-
pass
|
|
648
|
-
|
|
649
|
-
def represent_string(dumper, value):
|
|
650
|
-
# YAML normalizes literal NEL/line separators in unquoted scalars.
|
|
651
|
-
# Double quotes make the emitter escape them while keeping Chinese readable.
|
|
652
|
-
style = '"' if any(character in value for character in "\x85\u2028\u2029") else None
|
|
653
|
-
return dumper.represent_scalar("tag:yaml.org,2002:str", value, style=style)
|
|
654
|
-
|
|
655
|
-
LosslessDumper.add_representer(str, represent_string)
|
|
656
|
-
typer.echo(yaml.dump(data, Dumper=LosslessDumper, allow_unicode=True, sort_keys=False))
|
|
647
|
+
typer.echo(yaml.safe_dump(data, allow_unicode=True, sort_keys=False))
|
|
657
648
|
return
|
|
658
649
|
_print_json(data)
|
|
659
650
|
|
|
@@ -3230,12 +3221,12 @@ def job_create(
|
|
|
3230
3221
|
priority: Optional[str] = typer.Option(
|
|
3231
3222
|
None,
|
|
3232
3223
|
"--priority",
|
|
3233
|
-
help="Scheduling tier: high or medium
|
|
3224
|
+
help="Scheduling priority tier: high or medium (default: medium)",
|
|
3234
3225
|
),
|
|
3235
3226
|
priority_weight: Optional[int] = typer.Option(
|
|
3236
3227
|
None,
|
|
3237
3228
|
"--priority-weight",
|
|
3238
|
-
help="
|
|
3229
|
+
help="Fine-grained priority weight within tier, 0-10 (default: 0)",
|
|
3239
3230
|
),
|
|
3240
3231
|
resource_mode: Optional[str] = typer.Option(
|
|
3241
3232
|
None,
|
|
@@ -5468,18 +5459,6 @@ def group_create(
|
|
|
5468
5459
|
min=1,
|
|
5469
5460
|
help="Maximum concurrent jobs. Server default: 50.",
|
|
5470
5461
|
),
|
|
5471
|
-
priority: Optional[str] = typer.Option(
|
|
5472
|
-
None,
|
|
5473
|
-
"--priority",
|
|
5474
|
-
help="Default priority inherited by Jobs: high or medium (server default: medium)",
|
|
5475
|
-
),
|
|
5476
|
-
priority_weight: Optional[int] = typer.Option(
|
|
5477
|
-
None,
|
|
5478
|
-
"--priority-weight",
|
|
5479
|
-
min=0,
|
|
5480
|
-
max=10,
|
|
5481
|
-
help="Default priority weight inherited by Jobs, 0-10 (server default: 0)",
|
|
5482
|
-
),
|
|
5483
5462
|
eval_config: Optional[str] = typer.Option(
|
|
5484
5463
|
None, "--eval-config", help="Evaluation config (JSON)"
|
|
5485
5464
|
),
|
|
@@ -5592,8 +5571,6 @@ def group_create(
|
|
|
5592
5571
|
):
|
|
5593
5572
|
"""Create a Group."""
|
|
5594
5573
|
output_format = _normalize_output_format(output_format)
|
|
5595
|
-
if priority is not None and priority not in {"high", "medium"}:
|
|
5596
|
-
raise typer.BadParameter("--priority must be one of high/medium")
|
|
5597
5574
|
try:
|
|
5598
5575
|
for reference in ak_id or []:
|
|
5599
5576
|
validate_ak_id(reference)
|
|
@@ -5675,8 +5652,6 @@ def group_create(
|
|
|
5675
5652
|
checkpoint=checkpoint_dict,
|
|
5676
5653
|
benchmark=benchmark,
|
|
5677
5654
|
experiment=experiment,
|
|
5678
|
-
**({"priority": priority} if priority is not None else {}),
|
|
5679
|
-
**({"priority_weight": priority_weight} if priority_weight is not None else {}),
|
|
5680
5655
|
)
|
|
5681
5656
|
except ManagedAKProtocolError as exc:
|
|
5682
5657
|
_emit_error(str(exc))
|
|
@@ -5689,10 +5664,6 @@ def group_create(
|
|
|
5689
5664
|
print(f" ak_ids: {response_ak_ids(result)}")
|
|
5690
5665
|
if result.get("queue_id") is not None:
|
|
5691
5666
|
print(f" queue_id: {result.get('queue_id')}")
|
|
5692
|
-
if result.get("priority") is not None:
|
|
5693
|
-
print(f" priority: {result.get('priority')}")
|
|
5694
|
-
if result.get("priority_weight") is not None:
|
|
5695
|
-
print(f" priority_weight: {result.get('priority_weight')}")
|
|
5696
5667
|
if result.get("template") is not None:
|
|
5697
5668
|
print(f" template: {result.get('template')}")
|
|
5698
5669
|
if result.get("agenthub_revision") is not None:
|
|
@@ -6119,40 +6090,14 @@ def group_update(
|
|
|
6119
6090
|
"--meta-train-stage",
|
|
6120
6091
|
help="Set meta_train_stage tag (options: ap meta-train-stage list)",
|
|
6121
6092
|
),
|
|
6122
|
-
priority: Optional[str] = typer.Option(
|
|
6123
|
-
None,
|
|
6124
|
-
"--priority",
|
|
6125
|
-
help="Group priority default: high or medium; --priority alone sets weight to 0",
|
|
6126
|
-
),
|
|
6127
|
-
priority_weight: Optional[int] = typer.Option(
|
|
6128
|
-
None,
|
|
6129
|
-
"--priority-weight",
|
|
6130
|
-
min=0,
|
|
6131
|
-
max=10,
|
|
6132
|
-
help="Group priority weight default, 0-10; weight alone preserves the current tier",
|
|
6133
|
-
),
|
|
6134
|
-
priority_update_mode: Optional[str] = typer.Option(
|
|
6135
|
-
None,
|
|
6136
|
-
"--priority-update-mode",
|
|
6137
|
-
help="existing updates defaults and all current Jobs (including PostProcess); incremental updates only defaults (server default: existing)",
|
|
6138
|
-
),
|
|
6139
6093
|
output_format: str = typer.Option(
|
|
6140
6094
|
None,
|
|
6141
6095
|
"--format",
|
|
6142
6096
|
help="Output format: plain/table/json/yaml (default: AP_FORMAT or command default)",
|
|
6143
6097
|
),
|
|
6144
6098
|
):
|
|
6145
|
-
"""Update Group properties
|
|
6099
|
+
"""Update Group properties."""
|
|
6146
6100
|
output_format = _normalize_output_format(output_format)
|
|
6147
|
-
if priority is not None and priority not in {"high", "medium"}:
|
|
6148
|
-
raise typer.BadParameter("--priority must be one of high/medium")
|
|
6149
|
-
if priority_update_mode is not None:
|
|
6150
|
-
if priority_update_mode not in {"existing", "incremental"}:
|
|
6151
|
-
raise typer.BadParameter("--priority-update-mode must be one of existing/incremental")
|
|
6152
|
-
if priority is None and priority_weight is None:
|
|
6153
|
-
raise typer.BadParameter(
|
|
6154
|
-
"--priority-update-mode requires --priority or --priority-weight"
|
|
6155
|
-
)
|
|
6156
6101
|
eval_config_dict = _parse_json_object(eval_config, "--eval-config")
|
|
6157
6102
|
model_base_url_collection_list = _parse_model_base_url_collection_option(
|
|
6158
6103
|
model_base_url_collection, model_base_url_file
|
|
@@ -6189,8 +6134,6 @@ def group_update(
|
|
|
6189
6134
|
scaffold,
|
|
6190
6135
|
benchmark,
|
|
6191
6136
|
tags_list,
|
|
6192
|
-
priority,
|
|
6193
|
-
priority_weight,
|
|
6194
6137
|
)
|
|
6195
6138
|
):
|
|
6196
6139
|
raise typer.BadParameter("At least one field must be provided to update")
|
|
@@ -6206,13 +6149,6 @@ def group_update(
|
|
|
6206
6149
|
scaffold=scaffold,
|
|
6207
6150
|
**({"benchmark": benchmark} if benchmark is not None else {}),
|
|
6208
6151
|
**({"tags": tags_list} if tags_list is not None else {}),
|
|
6209
|
-
**({"priority": priority} if priority is not None else {}),
|
|
6210
|
-
**({"priority_weight": priority_weight} if priority_weight is not None else {}),
|
|
6211
|
-
**(
|
|
6212
|
-
{"priority_update_mode": priority_update_mode}
|
|
6213
|
-
if priority_update_mode is not None
|
|
6214
|
-
else {}
|
|
6215
|
-
),
|
|
6216
6152
|
)
|
|
6217
6153
|
if output_format == "plain":
|
|
6218
6154
|
_print_group_action_plain(
|
|
@@ -6227,8 +6163,6 @@ def group_update(
|
|
|
6227
6163
|
"model",
|
|
6228
6164
|
"scaffold",
|
|
6229
6165
|
"benchmark",
|
|
6230
|
-
"priority",
|
|
6231
|
-
"priority_weight",
|
|
6232
6166
|
"updated_at",
|
|
6233
6167
|
],
|
|
6234
6168
|
)
|
|
@@ -123,7 +123,10 @@ _NO_BENCHMARK = "none"
|
|
|
123
123
|
_FORMAT_HELP = "Output format: plain/table/json/yaml (default: AP_FORMAT or command default)"
|
|
124
124
|
|
|
125
125
|
_METADATA_MODELS = ("version_first", "split_first")
|
|
126
|
-
|
|
126
|
+
# IR SDK >= 1.4.0.dev3 的业务入口固定 split_first:business_metadata_model 拒绝
|
|
127
|
+
# version_first(仅保留给低层 legacy 读)。带 version 的 split 查询在两种模型下
|
|
128
|
+
# 结果一致(实测),显式 split_first 与 SDK 归一值一致且新旧 SDK 均接受。
|
|
129
|
+
_VERSION_SPLIT_METADATA_MODEL = "split_first"
|
|
127
130
|
|
|
128
131
|
#: CLI **不替 SDK 决定元数据模型**:不下发 ``metadata_model``,由 SDK 按 profile 归一
|
|
129
132
|
#: (当前为 ``split_first``)。
|
|
@@ -1186,9 +1189,26 @@ def dataset_get(
|
|
|
1186
1189
|
"dataset_name": dataset,
|
|
1187
1190
|
"registered": False,
|
|
1188
1191
|
}
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
+
from .dataset_name import (
|
|
1193
|
+
DatasetNameError,
|
|
1194
|
+
DatasetNameUpgradeRequired,
|
|
1195
|
+
parse_dataset_name,
|
|
1196
|
+
)
|
|
1197
|
+
|
|
1198
|
+
try:
|
|
1199
|
+
name = parse_dataset_name(dataset)
|
|
1200
|
+
except DatasetNameUpgradeRequired as exc:
|
|
1201
|
+
raise _fail(
|
|
1202
|
+
f"Failed to query dataset {dataset}: {exc}",
|
|
1203
|
+
"pip install 'ap-client[dataset]' --upgrade",
|
|
1204
|
+
exit_code=2,
|
|
1205
|
+
) from exc
|
|
1206
|
+
except DatasetNameError:
|
|
1207
|
+
# 非规范名:不凭空发明 level 字段(与历史行为一致)。
|
|
1208
|
+
pass
|
|
1209
|
+
else:
|
|
1210
|
+
rendered["dataset_l1"] = name.l1
|
|
1211
|
+
rendered["dataset_l2"] = name.l2
|
|
1192
1212
|
else:
|
|
1193
1213
|
rendered = _registered_dict(detail)
|
|
1194
1214
|
_emit_detail(rendered, output_format, order=_DATASET_DETAIL_ORDER, always=("status",))
|
|
@@ -1197,7 +1217,9 @@ def dataset_get(
|
|
|
1197
1217
|
|
|
1198
1218
|
|
|
1199
1219
|
def dataset_create(
|
|
1200
|
-
dataset: str = typer.Argument(
|
|
1220
|
+
dataset: str = typer.Argument(
|
|
1221
|
+
..., help="Dataset name: L1 or L1/L2 (e.g. my-bench or alibaba/my-bench)"
|
|
1222
|
+
),
|
|
1201
1223
|
benchmark: str = typer.Option(..., "--benchmark", help="Benchmark name or source_id"),
|
|
1202
1224
|
description: Optional[str] = typer.Option(None, "--description", help="Dataset description"),
|
|
1203
1225
|
visibility: str = typer.Option(
|
|
@@ -1216,20 +1238,32 @@ def dataset_create(
|
|
|
1216
1238
|
|
|
1217
1239
|
from instance_repo.models import DatasetSeries
|
|
1218
1240
|
|
|
1241
|
+
from .dataset_name import (
|
|
1242
|
+
DatasetNameError,
|
|
1243
|
+
DatasetNameUpgradeRequired,
|
|
1244
|
+
parse_dataset_name,
|
|
1245
|
+
)
|
|
1219
1246
|
from .irepo_sdk import _reason
|
|
1220
1247
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1248
|
+
try:
|
|
1249
|
+
name = parse_dataset_name(dataset)
|
|
1250
|
+
except DatasetNameUpgradeRequired as exc:
|
|
1251
|
+
raise _fail(
|
|
1252
|
+
f"Failed to create dataset {dataset}: {exc}",
|
|
1253
|
+
"pip install 'ap-client[dataset]' --upgrade",
|
|
1254
|
+
exit_code=2,
|
|
1255
|
+
) from exc
|
|
1256
|
+
except DatasetNameError:
|
|
1223
1257
|
raise _fail(
|
|
1224
|
-
f"Failed to create dataset {dataset}: the name must be
|
|
1225
|
-
"
|
|
1258
|
+
f"Failed to create dataset {dataset}: the name must be one segment (L1) "
|
|
1259
|
+
"or two segments (L1/L2)",
|
|
1260
|
+
"e.g. my-bench or your-team/my-bench",
|
|
1226
1261
|
exit_code=2,
|
|
1227
1262
|
)
|
|
1228
|
-
l1, l2 = parts
|
|
1229
1263
|
series = DatasetSeries(
|
|
1230
1264
|
dataset_name=dataset,
|
|
1231
|
-
dataset_l1=l1,
|
|
1232
|
-
dataset_l2=l2,
|
|
1265
|
+
dataset_l1=name.l1,
|
|
1266
|
+
dataset_l2=name.l2,
|
|
1233
1267
|
benchmark_id=benchmark_id,
|
|
1234
1268
|
visibility=resolved_visibility,
|
|
1235
1269
|
description=description or None,
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""DatasetName 解析 Adapter:唯一入口委托给已安装的 InstanceRepo SDK。
|
|
2
|
+
|
|
3
|
+
AP CLI 不维护第三套 dataset 名解析:``instance_repo.paths.DatasetName`` 是客户端
|
|
4
|
+
路径契约的唯一事实源(L1 单段 ``A`` / 两段 ``A/B``,与 apiserver 的 namespace
|
|
5
|
+
guard 及 conformance 契约对齐)。SDK 缺失或过旧(没有 ``DatasetName.parse``
|
|
6
|
+
能力)时,给出明确的升级提示,不静默降级、不本地重写解析规则。
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"DatasetNameError",
|
|
15
|
+
"DatasetNameUpgradeRequired",
|
|
16
|
+
"parse_dataset_name",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
#: SDK 缺失/无 DatasetName 能力时的升级提示(与 irepo_sdk 的 SdkMissing 同范式)。
|
|
20
|
+
_UPGRADE_HINT = (
|
|
21
|
+
"The installed instance-repo SDK does not provide DatasetName parsing "
|
|
22
|
+
"(single-segment L1 dataset names need it).\n"
|
|
23
|
+
"Install it with: pip install 'ap-client[dataset]' --upgrade"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class DatasetNameUpgradeRequired(RuntimeError):
|
|
28
|
+
"""已安装的 instance-repo SDK 缺少 DatasetName 能力,必须升级。"""
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class DatasetNameError(ValueError):
|
|
32
|
+
"""Dataset 名不符合 IR DatasetName 契约(单段或两段、无非法段)。"""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def parse_dataset_name(value: str) -> Any:
|
|
36
|
+
"""Parse ``value`` through the installed IR ``DatasetName`` capability.
|
|
37
|
+
|
|
38
|
+
Returns the SDK ``DatasetName`` (``canonical`` / ``l1`` / ``l2`` /
|
|
39
|
+
``segments`` / ``leaf``)。Raises :class:`DatasetNameUpgradeRequired` when the
|
|
40
|
+
installed SDK lacks the capability; raises :class:`DatasetNameError` when
|
|
41
|
+
the value is not a valid L1 or L1/L2 name.
|
|
42
|
+
"""
|
|
43
|
+
try:
|
|
44
|
+
from instance_repo.paths import DatasetName
|
|
45
|
+
except ImportError as exc:
|
|
46
|
+
raise DatasetNameUpgradeRequired(_UPGRADE_HINT) from exc
|
|
47
|
+
parse = getattr(DatasetName, "parse", None)
|
|
48
|
+
if not callable(parse):
|
|
49
|
+
raise DatasetNameUpgradeRequired(_UPGRADE_HINT)
|
|
50
|
+
try:
|
|
51
|
+
return parse(value)
|
|
52
|
+
except Exception as exc: # noqa: BLE001 - SDK 校验失败统一转成 CLI 契约
|
|
53
|
+
raise DatasetNameError(str(exc)) from exc
|
|
@@ -66,11 +66,25 @@ def _claim_without_workspace(
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
def _create_owned_dataset(repo: Any, dataset: str, benchmark_id: str) -> dict:
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
from .dataset_name import (
|
|
70
|
+
DatasetNameError,
|
|
71
|
+
DatasetNameUpgradeRequired,
|
|
72
|
+
parse_dataset_name,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
name = parse_dataset_name(dataset)
|
|
77
|
+
except DatasetNameUpgradeRequired as exc:
|
|
78
|
+
raise datasets._fail(
|
|
79
|
+
f"Failed to create dataset {dataset}: {exc}",
|
|
80
|
+
"pip install 'ap-client[dataset]' --upgrade",
|
|
81
|
+
exit_code=2,
|
|
82
|
+
) from exc
|
|
83
|
+
except DatasetNameError:
|
|
71
84
|
raise datasets._fail(
|
|
72
|
-
f"Failed to create dataset {dataset}: the name must be
|
|
73
|
-
"
|
|
85
|
+
f"Failed to create dataset {dataset}: the name must be one segment (L1) "
|
|
86
|
+
"or two segments (L1/L2)",
|
|
87
|
+
"Use a dataset name such as my-bench or your-team/my-bench",
|
|
74
88
|
exit_code=2,
|
|
75
89
|
)
|
|
76
90
|
|
|
@@ -78,8 +92,8 @@ def _create_owned_dataset(repo: Any, dataset: str, benchmark_id: str) -> dict:
|
|
|
78
92
|
|
|
79
93
|
fields: dict[str, Any] = {
|
|
80
94
|
"dataset_name": dataset,
|
|
81
|
-
"dataset_l1":
|
|
82
|
-
"dataset_l2":
|
|
95
|
+
"dataset_l1": name.l1,
|
|
96
|
+
"dataset_l2": name.l2,
|
|
83
97
|
"visibility": "private",
|
|
84
98
|
}
|
|
85
99
|
if benchmark_id:
|