-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathvalidate_setup.py
More file actions
318 lines (254 loc) · 10.7 KB
/
Copy pathvalidate_setup.py
File metadata and controls
318 lines (254 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#!/usr/bin/env python3
"""
validate_setup.py — Validate environment configuration before running the TSG Builder.
Checks:
1. Required environment variables are set
2. Azure credentials work (can authenticate)
3. Azure AI Project is accessible
4. Agent reference file exists (if agent was created)
"""
import os
import sys
from pathlib import Path
from dotenv import load_dotenv, find_dotenv
def print_ok(msg: str) -> None:
print(f" ✓ {msg}")
def print_fail(msg: str) -> None:
print(f" ✗ {msg}")
def print_warn(msg: str) -> None:
print(f" ⚠ {msg}")
def check_env_vars() -> tuple[bool, dict[str, str]]:
"""Check that required environment variables are set."""
print("\n[1/6] Checking environment variables...")
required = ["PROJECT_ENDPOINT", "MODEL_DEPLOYMENT_NAME"]
optional = ["AGENT_NAME"]
env_vars = {}
all_ok = True
for var in required:
value = os.getenv(var)
if value:
env_vars[var] = value
# Mask sensitive parts for display
if "subscriptions" in value.lower():
display = value[:50] + "..." if len(value) > 50 else value
else:
display = value
print_ok(f"{var} = {display}")
else:
print_fail(f"{var} is not set (REQUIRED)")
all_ok = False
for var in optional:
value = os.getenv(var)
if value:
env_vars[var] = value
print_ok(f"{var} = {value} (optional)")
else:
print_warn(f"{var} is not set (optional)")
return all_ok, env_vars
def check_dotenv_file() -> bool:
"""Check if .env file exists."""
print("\n[0/6] Checking .env file...")
dotenv_path = find_dotenv()
if dotenv_path:
print_ok(f"Found .env at: {dotenv_path}")
return True
else:
print_fail(".env file not found. Run 'make ui' to auto-create and configure.")
return False
def check_azure_auth() -> bool:
"""Check Azure authentication works."""
print("\n[2/6] Checking Azure authentication...")
try:
from azure.identity import DefaultAzureCredential
credential = DefaultAzureCredential()
# Try to get a token for Azure management
token = credential.get_token("https://cognitiveservices.azure.com/.default")
if token:
print_ok("Azure authentication successful (DefaultAzureCredential)")
return True
except Exception as e:
print_fail(f"Azure authentication failed: {e}")
print(" Hint: Run 'az login' or ensure your credentials are configured.")
return False
def check_project_connection(endpoint: str) -> bool:
"""Check connection to Azure AI Project."""
print("\n[3/6] Checking Azure AI Project connection...")
try:
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
project = AIProjectClient(endpoint=endpoint, credential=DefaultAzureCredential())
# Try a simple operation to verify connectivity
with project:
# Just creating the client and context manager is enough to verify
print_ok(f"Connected to project at: {endpoint}")
return True
except Exception as e:
print_fail(f"Failed to connect to project: {e}")
print(" Hint: Verify PROJECT_ENDPOINT is correct and you have access.")
return False
def check_model_deployment(endpoint: str, deployment_name: str) -> tuple[bool, bool]:
"""Check if the specified model deployment exists and is compatible.
Returns:
(found, compatible): found=True if deployment exists,
compatible=True if model is supported,
compatible=False if model is unsupported.
"""
from error_utils import classify_model, ModelTier
print("\n[4/6] Checking model deployment...")
try:
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
with AIProjectClient(endpoint=endpoint, credential=DefaultAzureCredential()) as project:
deployment = project.deployments.get(name=deployment_name)
underlying_model = getattr(deployment, "model_name", None) or ""
result = classify_model(underlying_model, deployment.name)
if result.tier == ModelTier.SUPPORTED:
print_ok(result.message)
return True, True
else:
# BLOCKED
print_fail(result.message)
return True, False
except Exception as e:
error_str = str(e)
# Try to list available deployments, filtered to compatible models only
compatible_names = []
try:
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
with AIProjectClient(endpoint=endpoint, credential=DefaultAzureCredential()) as project:
for dep in project.deployments.list():
dep_model = getattr(dep, "model_name", None) or ""
dep_class = classify_model(dep_model, dep.name)
if dep_class.tier != ModelTier.BLOCKED:
compatible_names.append(dep.name)
except Exception:
pass
if compatible_names:
print_warn(f"Deployment '{deployment_name}' not found.")
print(f" Compatible deployments: {', '.join(compatible_names[:5])}")
elif "404" in error_str or "NotFound" in error_str:
print_warn(f"Deployment '{deployment_name}' not found in project")
else:
print_warn(f"Could not verify deployment: {str(e)[:80]}")
return False, False
def check_agent_ref() -> bool:
"""Check if agent IDs file exists."""
print("\n[5/6] Checking pipeline agents...")
agent_ids_file = Path(".agent_ids.json")
if agent_ids_file.exists():
import json
try:
data = json.loads(agent_ids_file.read_text(encoding="utf-8"))
prefix = data.get("name_prefix", "TSG")
print_ok(f"3 pipeline agents configured ({prefix})")
return True
except (json.JSONDecodeError, IOError) as e:
print_warn(f"Agent IDs file exists but is invalid: {e}")
return True
else:
print_warn("No agents created yet. Use the Setup wizard in the web UI.")
return True # Not a failure, just not created yet
def check_dependencies() -> bool:
"""Check that required Python packages are installed with correct versions."""
print("\n[6/6] Checking Python dependencies...")
all_ok = True
# Check azure-ai-projects version (must be v2: 2.0.0+)
try:
import azure.ai.projects
version = azure.ai.projects.__version__
major = int(version.split(".")[0])
if major >= 2:
print_ok(f"azure-ai-projects {version} (v2 SDK ✓)")
else:
print_fail(f"azure-ai-projects {version} is v1 (classic Foundry)")
print(" Need v2 SDK: pip install azure-ai-projects")
all_ok = False
except ImportError:
print_fail("azure-ai-projects is not installed. Run: pip install azure-ai-projects")
all_ok = False
except (ValueError, IndexError):
print_warn(f"azure-ai-projects installed but couldn't parse version")
# Check that azure-ai-agents is NOT installed (it forces classic mode)
try:
import azure.ai.agents
print_warn("azure-ai-agents is installed - this forces classic Foundry mode!")
print(" Recommend: pip uninstall azure-ai-agents")
except ImportError:
print_ok("azure-ai-agents not installed (good for v2)")
# Check other required packages
other_packages = [
("azure.identity", "azure-identity"),
("dotenv", "python-dotenv"),
("openai", "openai"),
("flask", "flask"),
]
for module_name, package_name in other_packages:
try:
__import__(module_name)
print_ok(f"{package_name} is installed")
except ImportError:
print_fail(f"{package_name} is not installed. Run: pip install {package_name}")
all_ok = False
return all_ok
def main():
print("=" * 60)
print("TSG Builder - Environment Validation")
print("=" * 60)
# Load .env first
load_dotenv(find_dotenv())
# Run all checks
results = []
warnings = []
results.append(("Dependencies", check_dependencies()))
results.append((".env file", check_dotenv_file()))
env_ok, env_vars = check_env_vars()
results.append(("Environment variables", env_ok))
project_connected = False
if env_ok:
results.append(("Azure authentication", check_azure_auth()))
if "PROJECT_ENDPOINT" in env_vars:
project_connected = check_project_connection(env_vars["PROJECT_ENDPOINT"])
results.append(("Project connection", project_connected))
# Run deployment and model compatibility checks
if project_connected:
endpoint = env_vars["PROJECT_ENDPOINT"]
model_name = env_vars.get("MODEL_DEPLOYMENT_NAME", "")
if model_name:
found, compatible = check_model_deployment(endpoint, model_name)
if not found:
warnings.append("Model Deployment")
elif not compatible:
# Incompatible model — treat as failure (blocking)
results.append(("Model Deployment", False))
else:
results.append(("Model Deployment", True))
results.append(("Agent ID", check_agent_ref()))
# Summary
print("\n" + "=" * 60)
print("Summary")
print("=" * 60)
all_passed = True
for name, passed in results:
status = "✓ PASS" if passed else "✗ FAIL"
print(f" {status}: {name}")
if not passed:
all_passed = False
# Show warnings (not blocking)
for name in warnings:
print(f" ⚠ WARN: {name}")
print()
if all_passed:
print("All checks passed! You're ready to run the TSG Builder.")
print("\nNext steps:")
if not Path(".agent_ids.json").exists():
print(" 1. Run the UI: make ui")
print(" 2. Use the Setup wizard to create agents")
else:
print(" Run the UI: make ui")
sys.exit(0)
else:
print("Some checks failed. Please fix the issues above before proceeding.")
sys.exit(1)
if __name__ == "__main__":
main()