cu-cli 0.1.0b1__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.
- cu_cli/__init__.py +17 -0
- cu_cli/__main__.py +11 -0
- cu_cli/apiversion.py +124 -0
- cu_cli/cli.py +138 -0
- cu_cli/client.py +138 -0
- cu_cli/commands/__init__.py +4 -0
- cu_cli/commands/_command_spec.py +94 -0
- cu_cli/commands/_help.py +33 -0
- cu_cli/commands/_infra_models.py +184 -0
- cu_cli/commands/_infra_wizard.py +630 -0
- cu_cli/commands/_model_setup.py +46 -0
- cu_cli/commands/_options.py +112 -0
- cu_cli/commands/analyze.py +631 -0
- cu_cli/commands/analyzer.py +1462 -0
- cu_cli/commands/defaults.py +172 -0
- cu_cli/commands/doctor.py +166 -0
- cu_cli/commands/env_var.py +67 -0
- cu_cli/commands/infra.py +302 -0
- cu_cli/commands/profile_cmd.py +525 -0
- cu_cli/commands/upgrade.py +120 -0
- cu_cli/core/__init__.py +17 -0
- cu_cli/core/analyze.py +44 -0
- cu_cli/core/analyzers.py +30 -0
- cu_cli/core/azure_resources.py +486 -0
- cu_cli/core/defaults.py +18 -0
- cu_cli/core/doctor.py +42 -0
- cu_cli/core/foundry.py +68 -0
- cu_cli/core/infra_models.py +367 -0
- cu_cli/core/inputs.py +209 -0
- cu_cli/core/schema.py +24 -0
- cu_cli/errors.py +174 -0
- cu_cli/exit_codes.py +20 -0
- cu_cli/modality.py +24 -0
- cu_cli/output.py +179 -0
- cu_cli/profile.py +30 -0
- cu_cli/py.typed +0 -0
- cu_cli/resources/__init__.py +4 -0
- cu_cli/resources/azd_template/README.md +187 -0
- cu_cli/resources/azd_template/azure.yaml +27 -0
- cu_cli/resources/azd_template/hooks/postprovision.ps1 +320 -0
- cu_cli/resources/azd_template/hooks/postprovision.sh +299 -0
- cu_cli/resources/azd_template/infra/main.bicep +115 -0
- cu_cli/resources/azd_template/infra/main.parameters.json +30 -0
- cu_cli/resources/azd_template/infra/models.json +1 -0
- cu_cli/resources/azd_template/infra/modules/foundry.bicep +122 -0
- cu_cli/schema_validate.py +28 -0
- cu_cli/spec_validate.py +18 -0
- cu_cli/telemetry.py +42 -0
- cu_cli/update_check.py +154 -0
- cu_cli/update_provider.py +92 -0
- cu_cli/windows_self_upgrade.py +245 -0
- cu_cli-0.1.0b1.dist-info/METADATA +345 -0
- cu_cli-0.1.0b1.dist-info/RECORD +56 -0
- cu_cli-0.1.0b1.dist-info/WHEEL +5 -0
- cu_cli-0.1.0b1.dist-info/entry_points.txt +3 -0
- cu_cli-0.1.0b1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT license.
|
|
3
|
+
|
|
4
|
+
"""Internal live model-setup command used by the generated azd hook."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
import rich_click as click
|
|
12
|
+
|
|
13
|
+
from ..client import build_client, resolve
|
|
14
|
+
from ..profile import Profile
|
|
15
|
+
from ..core.infra_models import (
|
|
16
|
+
DeployableModel,
|
|
17
|
+
deploy_models,
|
|
18
|
+
deployable_models,
|
|
19
|
+
fetch_account_models,
|
|
20
|
+
recommended_models,
|
|
21
|
+
select_requested_models,
|
|
22
|
+
supported_model_names,
|
|
23
|
+
write_models_file,
|
|
24
|
+
)
|
|
25
|
+
from ..errors import CuCliError, friendly_errors
|
|
26
|
+
from ..output import console
|
|
27
|
+
from ._help import common_commands
|
|
28
|
+
from ._options import print_runtime_context, with_auth_options
|
|
29
|
+
|
|
30
|
+
NO_MODEL_ANALYZERS = (
|
|
31
|
+
"prebuilt-digitalParse",
|
|
32
|
+
"prebuilt-read",
|
|
33
|
+
"prebuilt-layout",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _parse_picker(raw: str, candidates: list[DeployableModel]) -> list[DeployableModel]:
|
|
38
|
+
indices: list[int] = []
|
|
39
|
+
for chunk in raw.split(","):
|
|
40
|
+
chunk = chunk.strip()
|
|
41
|
+
if not chunk:
|
|
42
|
+
continue
|
|
43
|
+
try:
|
|
44
|
+
index = int(chunk)
|
|
45
|
+
except ValueError as exc:
|
|
46
|
+
raise ValueError(f"'{chunk}' is not a number") from exc
|
|
47
|
+
if index == 0:
|
|
48
|
+
if len([part for part in raw.split(",") if part.strip()]) != 1:
|
|
49
|
+
raise ValueError("0 (no models) cannot be combined with model selections")
|
|
50
|
+
return []
|
|
51
|
+
if not 1 <= index <= len(candidates):
|
|
52
|
+
raise ValueError(f"'{index}' is out of range (0..{len(candidates)})")
|
|
53
|
+
if index not in indices:
|
|
54
|
+
indices.append(index)
|
|
55
|
+
|
|
56
|
+
selected = [candidates[index - 1] for index in indices]
|
|
57
|
+
names = [model.name.lower() for model in selected]
|
|
58
|
+
if len(names) != len(set(names)):
|
|
59
|
+
raise ValueError("select only one version of each model family")
|
|
60
|
+
return selected
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _prompt_for_models(candidates: list[DeployableModel]) -> list[DeployableModel]:
|
|
64
|
+
console.print("\n[bold]Select live CU-supported models to deploy[/bold]")
|
|
65
|
+
console.print(
|
|
66
|
+
" [yellow][0][/yellow] None - "
|
|
67
|
+
+ ", ".join(NO_MODEL_ANALYZERS)
|
|
68
|
+
+ " only (no language or embeddings models)"
|
|
69
|
+
)
|
|
70
|
+
for index, model in enumerate(candidates, start=1):
|
|
71
|
+
console.print(
|
|
72
|
+
f" [yellow][{index}][/yellow] {model.name:<30} {model.version:<12} "
|
|
73
|
+
f"{model.kind:<10} {model.sku_name}"
|
|
74
|
+
)
|
|
75
|
+
try:
|
|
76
|
+
recommended = recommended_models(candidates)
|
|
77
|
+
default_choice = ",".join(
|
|
78
|
+
str(candidates.index(model) + 1) for model in recommended
|
|
79
|
+
)
|
|
80
|
+
except CuCliError:
|
|
81
|
+
default_choice = "0"
|
|
82
|
+
while True:
|
|
83
|
+
raw = click.prompt(
|
|
84
|
+
"Enter numbers (comma-separated)", default=default_choice, show_default=True
|
|
85
|
+
)
|
|
86
|
+
try:
|
|
87
|
+
return _parse_picker(raw, candidates)
|
|
88
|
+
except ValueError as exc:
|
|
89
|
+
console.print(f"[red]{exc}[/red]")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _client(endpoint, api_key, api_version, entra, profile_name, show_runtime_context):
|
|
93
|
+
profile = Profile.load(profile_name=profile_name)
|
|
94
|
+
auth = resolve(
|
|
95
|
+
profile,
|
|
96
|
+
endpoint_override=endpoint,
|
|
97
|
+
api_key_override=api_key,
|
|
98
|
+
api_version_override=api_version,
|
|
99
|
+
force_entra=entra,
|
|
100
|
+
)
|
|
101
|
+
if show_runtime_context:
|
|
102
|
+
print_runtime_context(auth, profile)
|
|
103
|
+
return build_client(
|
|
104
|
+
profile,
|
|
105
|
+
endpoint_override=endpoint,
|
|
106
|
+
api_key_override=api_key,
|
|
107
|
+
api_version_override=api_version,
|
|
108
|
+
force_entra=entra,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@click.command(
|
|
113
|
+
"_infra-models",
|
|
114
|
+
hidden=True,
|
|
115
|
+
epilog=common_commands(
|
|
116
|
+
(
|
|
117
|
+
"cu _infra-models --selection none ...",
|
|
118
|
+
"Skip model deployment for digitalParse, read, and layout.",
|
|
119
|
+
),
|
|
120
|
+
),
|
|
121
|
+
)
|
|
122
|
+
@click.option("--resource-group", required=True)
|
|
123
|
+
@click.option("--account", "account_name", required=True)
|
|
124
|
+
@click.option("--subscription", "subscription_id", required=True)
|
|
125
|
+
@click.option("--selection", required=True,
|
|
126
|
+
help="prompt, recommended, none, or comma-separated model selectors.")
|
|
127
|
+
@click.option("--out", "out_path", required=True, type=click.Path(path_type=Path))
|
|
128
|
+
@click.option("--deploy/--no-deploy", default=True)
|
|
129
|
+
@with_auth_options
|
|
130
|
+
@friendly_errors
|
|
131
|
+
def cmd_infra_models(
|
|
132
|
+
resource_group, account_name, subscription_id, selection, out_path, deploy, endpoint, api_key,
|
|
133
|
+
api_version, entra, profile_name, show_runtime_context, show_calling_time,
|
|
134
|
+
) -> None:
|
|
135
|
+
del show_calling_time
|
|
136
|
+
normalized = selection.strip().lower()
|
|
137
|
+
if normalized == "none":
|
|
138
|
+
write_models_file(out_path, [])
|
|
139
|
+
console.print(
|
|
140
|
+
"[green]ok[/green] no model deployments selected; available analyzers: "
|
|
141
|
+
+ ", ".join(NO_MODEL_ANALYZERS)
|
|
142
|
+
)
|
|
143
|
+
return
|
|
144
|
+
|
|
145
|
+
client = _client(
|
|
146
|
+
endpoint, api_key, api_version, entra, profile_name, show_runtime_context
|
|
147
|
+
)
|
|
148
|
+
analyzer = client.get_analyzer("prebuilt-document")
|
|
149
|
+
supported = supported_model_names(analyzer)
|
|
150
|
+
candidates = deployable_models(
|
|
151
|
+
fetch_account_models(resource_group, account_name, subscription_id),
|
|
152
|
+
supported,
|
|
153
|
+
)
|
|
154
|
+
if not candidates:
|
|
155
|
+
raise CuCliError(
|
|
156
|
+
"no live Content Understanding-supported models are deployable on this "
|
|
157
|
+
"Microsoft Foundry resource."
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
if normalized == "prompt":
|
|
161
|
+
if not sys.stdin.isatty():
|
|
162
|
+
raise CuCliError(
|
|
163
|
+
"live model selection requires an interactive terminal.",
|
|
164
|
+
hint="set --infra-models to 'none', 'recommended', or explicit model names.",
|
|
165
|
+
)
|
|
166
|
+
selected = _prompt_for_models(candidates)
|
|
167
|
+
elif normalized == "recommended":
|
|
168
|
+
selected = recommended_models(candidates)
|
|
169
|
+
else:
|
|
170
|
+
selected = select_requested_models(candidates, selection.split(","))
|
|
171
|
+
|
|
172
|
+
if deploy:
|
|
173
|
+
deploy_models(resource_group, account_name, subscription_id, selected)
|
|
174
|
+
write_models_file(out_path, selected)
|
|
175
|
+
if selected:
|
|
176
|
+
console.print(
|
|
177
|
+
"[green]ok[/green] configured live model deployments: "
|
|
178
|
+
+ ", ".join(model.selector for model in selected)
|
|
179
|
+
)
|
|
180
|
+
else:
|
|
181
|
+
console.print(
|
|
182
|
+
"[green]ok[/green] no model deployments selected; available analyzers: "
|
|
183
|
+
+ ", ".join(NO_MODEL_ANALYZERS)
|
|
184
|
+
)
|