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.
Files changed (56) hide show
  1. cu_cli/__init__.py +17 -0
  2. cu_cli/__main__.py +11 -0
  3. cu_cli/apiversion.py +124 -0
  4. cu_cli/cli.py +138 -0
  5. cu_cli/client.py +138 -0
  6. cu_cli/commands/__init__.py +4 -0
  7. cu_cli/commands/_command_spec.py +94 -0
  8. cu_cli/commands/_help.py +33 -0
  9. cu_cli/commands/_infra_models.py +184 -0
  10. cu_cli/commands/_infra_wizard.py +630 -0
  11. cu_cli/commands/_model_setup.py +46 -0
  12. cu_cli/commands/_options.py +112 -0
  13. cu_cli/commands/analyze.py +631 -0
  14. cu_cli/commands/analyzer.py +1462 -0
  15. cu_cli/commands/defaults.py +172 -0
  16. cu_cli/commands/doctor.py +166 -0
  17. cu_cli/commands/env_var.py +67 -0
  18. cu_cli/commands/infra.py +302 -0
  19. cu_cli/commands/profile_cmd.py +525 -0
  20. cu_cli/commands/upgrade.py +120 -0
  21. cu_cli/core/__init__.py +17 -0
  22. cu_cli/core/analyze.py +44 -0
  23. cu_cli/core/analyzers.py +30 -0
  24. cu_cli/core/azure_resources.py +486 -0
  25. cu_cli/core/defaults.py +18 -0
  26. cu_cli/core/doctor.py +42 -0
  27. cu_cli/core/foundry.py +68 -0
  28. cu_cli/core/infra_models.py +367 -0
  29. cu_cli/core/inputs.py +209 -0
  30. cu_cli/core/schema.py +24 -0
  31. cu_cli/errors.py +174 -0
  32. cu_cli/exit_codes.py +20 -0
  33. cu_cli/modality.py +24 -0
  34. cu_cli/output.py +179 -0
  35. cu_cli/profile.py +30 -0
  36. cu_cli/py.typed +0 -0
  37. cu_cli/resources/__init__.py +4 -0
  38. cu_cli/resources/azd_template/README.md +187 -0
  39. cu_cli/resources/azd_template/azure.yaml +27 -0
  40. cu_cli/resources/azd_template/hooks/postprovision.ps1 +320 -0
  41. cu_cli/resources/azd_template/hooks/postprovision.sh +299 -0
  42. cu_cli/resources/azd_template/infra/main.bicep +115 -0
  43. cu_cli/resources/azd_template/infra/main.parameters.json +30 -0
  44. cu_cli/resources/azd_template/infra/models.json +1 -0
  45. cu_cli/resources/azd_template/infra/modules/foundry.bicep +122 -0
  46. cu_cli/schema_validate.py +28 -0
  47. cu_cli/spec_validate.py +18 -0
  48. cu_cli/telemetry.py +42 -0
  49. cu_cli/update_check.py +154 -0
  50. cu_cli/update_provider.py +92 -0
  51. cu_cli/windows_self_upgrade.py +245 -0
  52. cu_cli-0.1.0b1.dist-info/METADATA +345 -0
  53. cu_cli-0.1.0b1.dist-info/RECORD +56 -0
  54. cu_cli-0.1.0b1.dist-info/WHEEL +5 -0
  55. cu_cli-0.1.0b1.dist-info/entry_points.txt +3 -0
  56. 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
+ )