pythonprincess commited on
Commit
8a5d8cb
·
verified ·
1 Parent(s): 1bfa24a

Delete main.py

Browse files
Files changed (1) hide show
  1. main.py +0 -660
main.py DELETED
@@ -1,660 +0,0 @@
1
- # app/main.py
2
- """
3
- 🤖 PENNY - People's Engagement Network Navigator for You
4
- FastAPI Entry Point with Azure-Ready Configuration
5
-
6
- This is Penny's front door. She loads her environment, registers all her endpoints,
7
- and makes sure she's ready to help residents find what they need.
8
-
9
- MISSION: Connect residents to civic resources through a warm, multilingual interface
10
- that removes barriers and empowers communities.
11
- """
12
-
13
- from fastapi import FastAPI, Request, status
14
- from fastapi.responses import JSONResponse
15
- from fastapi.middleware.cors import CORSMiddleware
16
- import logging
17
- import sys
18
- import os
19
- from dotenv import load_dotenv
20
- import pathlib
21
- from typing import Dict, Any, Optional, List
22
- from datetime import datetime, timedelta
23
-
24
- # --- LOGGING CONFIGURATION (Must be set up before other imports) ---
25
- logging.basicConfig(
26
- level=logging.INFO,
27
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
28
- handlers=[
29
- logging.StreamHandler(sys.stdout)
30
- ]
31
- )
32
- logger = logging.getLogger(__name__)
33
-
34
- # --- CRITICAL: FORCE .ENV LOADING BEFORE ANY OTHER IMPORTS ---
35
- # Determine the absolute path to the project root
36
- PROJECT_ROOT = pathlib.Path(__file__).parent.parent
37
-
38
- # Load environment variables into the active Python session IMMEDIATELY
39
- # This ensures Azure Maps keys, API tokens, and model paths are available
40
- try:
41
- load_dotenv(PROJECT_ROOT / ".env")
42
-
43
- # Verify critical environment variables are loaded
44
- REQUIRED_ENV_VARS = ["AZURE_MAPS_KEY"]
45
- missing_vars = [var for var in REQUIRED_ENV_VARS if not os.getenv(var)]
46
- if missing_vars:
47
- logger.warning(f"⚠️ WARNING: Missing required environment variables: {missing_vars}")
48
- logger.warning(f"📁 Looking for .env file at: {PROJECT_ROOT / '.env'}")
49
- else:
50
- logger.info("✅ Environment variables loaded successfully")
51
- except Exception as e:
52
- logger.error(f"❌ Error loading environment variables: {e}")
53
- logger.error(f"📁 Expected .env location: {PROJECT_ROOT / '.env'}")
54
-
55
- # --- NOW SAFE TO IMPORT MODULES THAT DEPEND ON ENV VARS ---
56
- try:
57
- from app.weather_agent import get_weather_for_location
58
- from app.router import router as api_router
59
- from app.location_utils import (
60
- initialize_location_system,
61
- get_all_supported_cities,
62
- validate_city_data_files,
63
- SupportedCities,
64
- get_city_coordinates
65
- )
66
- except ImportError as e:
67
- logger.error(f"❌ Critical import error: {e}")
68
- logger.error("⚠️ Penny cannot start without core modules")
69
- sys.exit(1)
70
-
71
- # --- FASTAPI APP INITIALIZATION ---
72
- app = FastAPI(
73
- title="PENNY - Civic Engagement Assistant",
74
- description=(
75
- "💛 Multilingual civic chatbot connecting residents with local services, "
76
- "government programs, and community resources.\n\n"
77
- "**Powered by:**\n"
78
- "- Transformer models for natural language understanding\n"
79
- "- Azure ML infrastructure for scalable deployment\n"
80
- "- 27-language translation support\n"
81
- "- Real-time weather integration\n"
82
- "- Multi-city civic resource databases\n\n"
83
- "**Supported Cities:** Atlanta, Birmingham, Chesterfield, El Paso, Providence, Seattle"
84
- ),
85
- version="1.0.0",
86
- docs_url="/docs",
87
- redoc_url="/redoc",
88
- contact={
89
- "name": "Penny Support",
90
- "email": "support@pennyai.example"
91
- },
92
- license_info={
93
- "name": "Proprietary",
94
- }
95
- )
96
-
97
- # --- CORS MIDDLEWARE (Configure for your deployment) ---
98
- # Production: Update allowed_origins to restrict to specific domains
99
- allowed_origins = os.getenv("ALLOWED_ORIGINS", "*").split(",")
100
- app.add_middleware(
101
- CORSMiddleware,
102
- allow_origins=allowed_origins,
103
- allow_credentials=True,
104
- allow_methods=["*"],
105
- allow_headers=["*"],
106
- )
107
-
108
- # --- APPLICATION STATE (For health checks and monitoring) ---
109
- app.state.location_system_healthy = False
110
- app.state.startup_time = None
111
- app.state.startup_errors: List[str] = []
112
-
113
- # --- GLOBAL EXCEPTION HANDLER ---
114
- @app.exception_handler(Exception)
115
- async def global_exception_handler(request: Request, exc: Exception) -> JSONResponse:
116
- """
117
- 🛡️ Catches any unhandled exceptions and returns a user-friendly response.
118
- Logs full error details for debugging while keeping responses safe for users.
119
-
120
- Penny stays helpful even when things go wrong!
121
-
122
- Args:
123
- request: FastAPI request object
124
- exc: The unhandled exception
125
-
126
- Returns:
127
- JSONResponse with error details (sanitized for production)
128
- """
129
- logger.error(
130
- f"Unhandled exception on {request.url.path} | "
131
- f"method={request.method} | "
132
- f"error={exc}",
133
- exc_info=True
134
- )
135
-
136
- # Check if debug mode is enabled
137
- debug_mode = os.getenv("DEBUG_MODE", "false").lower() == "true"
138
-
139
- return JSONResponse(
140
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
141
- content={
142
- "error": "An unexpected error occurred. Penny's on it!",
143
- "message": "Our team has been notified and we're working to fix this.",
144
- "detail": str(exc) if debug_mode else None,
145
- "request_path": str(request.url.path),
146
- "timestamp": datetime.utcnow().isoformat()
147
- }
148
- )
149
-
150
- # --- STARTUP EVENT ---
151
- @app.on_event("startup")
152
- async def startup_event() -> None:
153
- """
154
- 🚀 Runs when Penny wakes up.
155
-
156
- Responsibilities:
157
- 1. Validate environment configuration
158
- 2. Initialize location/city systems
159
- 3. Verify data files exist
160
- 4. Log system status
161
- """
162
- try:
163
- app.state.startup_time = datetime.utcnow()
164
- app.state.startup_errors = []
165
-
166
- logger.info("=" * 60)
167
- logger.info("🤖 PENNY STARTUP INITIALIZED")
168
- logger.info("=" * 60)
169
-
170
- # --- Environment Info ---
171
- logger.info(f"📂 Project Root: {PROJECT_ROOT}")
172
- logger.info(f"🌍 Environment: {os.getenv('ENVIRONMENT', 'development')}")
173
- logger.info(f"🐍 Python Version: {sys.version.split()[0]}")
174
-
175
- # --- Azure Configuration Check ---
176
- azure_maps_key = os.getenv("AZURE_MAPS_KEY")
177
- if azure_maps_key:
178
- logger.info("🗺️ Azure Maps: ✅ Configured")
179
- else:
180
- error_msg = "Azure Maps key missing - weather features will be limited"
181
- logger.warning(f"🗺️ Azure Maps: ⚠️ {error_msg}")
182
- app.state.startup_errors.append(error_msg)
183
-
184
- # --- Initialize Location System ---
185
- logger.info("🗺️ Initializing location system...")
186
- try:
187
- location_system_ready = initialize_location_system()
188
- app.state.location_system_healthy = location_system_ready
189
-
190
- if location_system_ready:
191
- logger.info("✅ Location system initialized successfully")
192
-
193
- # Log supported cities
194
- cities = SupportedCities.get_all_cities()
195
- logger.info(f"📍 Supported cities: {len(cities)}")
196
- for city in cities:
197
- logger.info(f" - {city.full_name} ({city.tenant_id})")
198
-
199
- # Validate data files
200
- validation = validate_city_data_files()
201
- missing_data = [
202
- tid for tid, status in validation.items()
203
- if not status["events"] or not status["resources"]
204
- ]
205
- if missing_data:
206
- error_msg = f"Incomplete data for cities: {missing_data}"
207
- logger.warning(f"⚠️ {error_msg}")
208
- app.state.startup_errors.append(error_msg)
209
- else:
210
- error_msg = "Location system initialization failed"
211
- logger.error(f"❌ {error_msg}")
212
- app.state.startup_errors.append(error_msg)
213
-
214
- except Exception as e:
215
- error_msg = f"Error initializing location system: {e}"
216
- logger.error(f"❌ {error_msg}", exc_info=True)
217
- app.state.location_system_healthy = False
218
- app.state.startup_errors.append(error_msg)
219
-
220
- # --- Startup Summary ---
221
- logger.info("=" * 60)
222
- if app.state.startup_errors:
223
- logger.warning(f"⚠️ PENNY STARTED WITH {len(app.state.startup_errors)} WARNING(S)")
224
- for error in app.state.startup_errors:
225
- logger.warning(f" - {error}")
226
- else:
227
- logger.info("🎉 PENNY IS READY TO HELP RESIDENTS!")
228
- logger.info("📖 API Documentation: http://localhost:8000/docs")
229
- logger.info("=" * 60)
230
-
231
- except Exception as e:
232
- logger.error(f"❌ Critical startup error: {e}", exc_info=True)
233
- app.state.startup_errors.append(f"Critical startup failure: {e}")
234
-
235
- # --- SHUTDOWN EVENT ---
236
- @app.on_event("shutdown")
237
- async def shutdown_event() -> None:
238
- """
239
- 👋 Cleanup tasks when Penny shuts down.
240
- """
241
- try:
242
- logger.info("=" * 60)
243
- logger.info("👋 PENNY SHUTTING DOWN")
244
- logger.info("=" * 60)
245
-
246
- # Calculate uptime
247
- if app.state.startup_time:
248
- uptime = datetime.utcnow() - app.state.startup_time
249
- logger.info(f"⏱️ Total uptime: {uptime}")
250
-
251
- # TODO: Add cleanup tasks here
252
- # - Close database connections
253
- # - Save state if needed
254
- # - Release model resources
255
-
256
- logger.info("✅ Shutdown complete. Goodbye for now!")
257
- except Exception as e:
258
- logger.error(f"Error during shutdown: {e}", exc_info=True)
259
-
260
- # --- ROUTER INCLUSION ---
261
- # All API endpoints defined in router.py are registered here
262
- try:
263
- app.include_router(api_router)
264
- logger.info("✅ API router registered successfully")
265
- except Exception as e:
266
- logger.error(f"❌ Failed to register API router: {e}", exc_info=True)
267
-
268
- # ============================================================
269
- # CORE HEALTH & STATUS ENDPOINTS
270
- # ============================================================
271
-
272
- @app.get("/", tags=["Health"])
273
- async def root() -> Dict[str, Any]:
274
- """
275
- 🏠 Root endpoint - confirms Penny is alive and running.
276
-
277
- This is the first thing users/load balancers will hit.
278
- Penny always responds with warmth, even to bots! 💛
279
-
280
- Returns:
281
- Basic status and feature information
282
- """
283
- try:
284
- return {
285
- "message": "💛 Hi! I'm Penny, your civic engagement assistant.",
286
- "status": "operational",
287
- "tagline": "Connecting residents to community resources since 2024",
288
- "docs": "/docs",
289
- "api_version": "1.0.0",
290
- "supported_cities": len(SupportedCities.get_all_cities()),
291
- "features": [
292
- "27-language translation",
293
- "Real-time weather",
294
- "Community events",
295
- "Local resource finder",
296
- "Document processing"
297
- ],
298
- "timestamp": datetime.utcnow().isoformat()
299
- }
300
- except Exception as e:
301
- logger.error(f"Error in root endpoint: {e}", exc_info=True)
302
- return {
303
- "message": "💛 Hi! I'm Penny, your civic engagement assistant.",
304
- "status": "degraded",
305
- "error": "Some features may be unavailable"
306
- }
307
-
308
- @app.get("/health", tags=["Health"])
309
- async def health_check() -> JSONResponse:
310
- """
311
- 🏥 Comprehensive health check for Azure load balancers and monitoring.
312
-
313
- Returns detailed status of all critical components:
314
- - Environment configuration
315
- - Location system
316
- - Data availability
317
- - API components
318
-
319
- Returns:
320
- JSONResponse with health status (200 = healthy, 503 = degraded)
321
- """
322
- try:
323
- # Calculate uptime
324
- uptime = None
325
- if app.state.startup_time:
326
- uptime_delta = datetime.utcnow() - app.state.startup_time
327
- uptime = str(uptime_delta).split('.')[0] # Remove microseconds
328
-
329
- # Validate data files
330
- validation = validate_city_data_files()
331
- cities_with_full_data = sum(
332
- 1 for v in validation.values()
333
- if v.get("events", False) and v.get("resources", False)
334
- )
335
- total_cities = len(SupportedCities.get_all_cities())
336
-
337
- health_status = {
338
- "status": "healthy",
339
- "timestamp": datetime.utcnow().isoformat(),
340
- "uptime": uptime,
341
- "environment": {
342
- "azure_maps_configured": bool(os.getenv("AZURE_MAPS_KEY")),
343
- "debug_mode": os.getenv("DEBUG_MODE", "false").lower() == "true",
344
- "environment_type": os.getenv("ENVIRONMENT", "development")
345
- },
346
- "location_system": {
347
- "status": "operational" if app.state.location_system_healthy else "degraded",
348
- "supported_cities": total_cities,
349
- "cities_with_full_data": cities_with_full_data
350
- },
351
- "api_components": {
352
- "router": "operational",
353
- "weather_agent": "operational" if os.getenv("AZURE_MAPS_KEY") else "degraded",
354
- "translation": "operational",
355
- "document_processing": "operational"
356
- },
357
- "startup_errors": app.state.startup_errors if app.state.startup_errors else None,
358
- "api_version": "1.0.0"
359
- }
360
-
361
- # Determine overall health status
362
- critical_checks = [
363
- app.state.location_system_healthy,
364
- bool(os.getenv("AZURE_MAPS_KEY"))
365
- ]
366
-
367
- all_healthy = all(critical_checks)
368
-
369
- if not all_healthy:
370
- health_status["status"] = "degraded"
371
- logger.warning(f"Health check: System degraded - {health_status}")
372
- return JSONResponse(
373
- status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
374
- content=health_status
375
- )
376
-
377
- return JSONResponse(
378
- status_code=status.HTTP_200_OK,
379
- content=health_status
380
- )
381
-
382
- except Exception as e:
383
- logger.error(f"Health check failed: {e}", exc_info=True)
384
- return JSONResponse(
385
- status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
386
- content={
387
- "status": "error",
388
- "timestamp": datetime.utcnow().isoformat(),
389
- "error": "Health check failed",
390
- "detail": str(e) if os.getenv("DEBUG_MODE", "false").lower() == "true" else None
391
- }
392
- )
393
-
394
- @app.get("/cities", tags=["Location"])
395
- async def list_supported_cities() -> JSONResponse:
396
- """
397
- 📍 Lists all cities Penny currently supports.
398
-
399
- Returns:
400
- List of city information including tenant_id and display name.
401
- Useful for frontend dropdowns and API clients.
402
-
403
- Example Response:
404
- {
405
- "total": 6,
406
- "cities": [
407
- {
408
- "tenant_id": "atlanta_ga",
409
- "name": "Atlanta, GA",
410
- "state": "GA",
411
- "data_status": {"events": true, "resources": true}
412
- }
413
- ]
414
- }
415
- """
416
- try:
417
- cities = get_all_supported_cities()
418
-
419
- # Add validation status for each city
420
- validation = validate_city_data_files()
421
- for city in cities:
422
- tenant_id = city["tenant_id"]
423
- city["data_status"] = validation.get(tenant_id, {
424
- "events": False,
425
- "resources": False
426
- })
427
-
428
- return JSONResponse(
429
- status_code=status.HTTP_200_OK,
430
- content={
431
- "total": len(cities),
432
- "cities": cities,
433
- "message": "These are the cities where Penny can help you find resources!",
434
- "timestamp": datetime.utcnow().isoformat()
435
- }
436
- )
437
- except Exception as e:
438
- logger.error(f"Error listing cities: {e}", exc_info=True)
439
- return JSONResponse(
440
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
441
- content={
442
- "error": "Unable to retrieve city list",
443
- "message": "I'm having trouble loading the city list right now. Please try again in a moment!",
444
- "detail": str(e) if os.getenv("DEBUG_MODE", "false").lower() == "true" else None,
445
- "timestamp": datetime.utcnow().isoformat()
446
- }
447
- )
448
-
449
- # ============================================================
450
- # WEATHER ENDPOINTS
451
- # ============================================================
452
-
453
- @app.get("/weather_direct", tags=["Weather"])
454
- async def weather_direct_endpoint(lat: float, lon: float) -> JSONResponse:
455
- """
456
- 🌤️ Direct weather lookup by coordinates.
457
-
458
- Args:
459
- lat: Latitude (-90 to 90)
460
- lon: Longitude (-180 to 180)
461
-
462
- Returns:
463
- Current weather conditions for the specified location
464
-
465
- Example:
466
- GET /weather_direct?lat=36.8508&lon=-76.2859 (Norfolk, VA)
467
- """
468
- # Validate coordinates
469
- if not (-90 <= lat <= 90):
470
- return JSONResponse(
471
- status_code=status.HTTP_400_BAD_REQUEST,
472
- content={
473
- "error": "Invalid latitude",
474
- "message": "Latitude must be between -90 and 90",
475
- "provided_value": lat
476
- }
477
- )
478
- if not (-180 <= lon <= 180):
479
- return JSONResponse(
480
- status_code=status.HTTP_400_BAD_REQUEST,
481
- content={
482
- "error": "Invalid longitude",
483
- "message": "Longitude must be between -180 and 180",
484
- "provided_value": lon
485
- }
486
- )
487
-
488
- try:
489
- weather = await get_weather_for_location(lat=lat, lon=lon)
490
- return JSONResponse(
491
- status_code=status.HTTP_200_OK,
492
- content={
493
- "latitude": lat,
494
- "longitude": lon,
495
- "weather": weather,
496
- "source": "Azure Maps Weather API",
497
- "message": "Current weather conditions at your location",
498
- "timestamp": datetime.utcnow().isoformat()
499
- }
500
- )
501
- except Exception as e:
502
- logger.error(f"Weather lookup failed for ({lat}, {lon}): {e}", exc_info=True)
503
- return JSONResponse(
504
- status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
505
- content={
506
- "error": "Weather service temporarily unavailable",
507
- "message": "We're having trouble reaching the weather service. Please try again in a moment.",
508
- "latitude": lat,
509
- "longitude": lon,
510
- "timestamp": datetime.utcnow().isoformat()
511
- }
512
- )
513
-
514
- @app.get("/weather/{tenant_id}", tags=["Weather"])
515
- async def weather_by_city(tenant_id: str) -> JSONResponse:
516
- """
517
- 🌤️ Get weather for a supported city by tenant ID.
518
-
519
- Args:
520
- tenant_id: City identifier (e.g., 'atlanta_ga', 'seattle_wa')
521
-
522
- Returns:
523
- Current weather conditions for the specified city
524
-
525
- Example:
526
- GET /weather/atlanta_ga
527
- """
528
- try:
529
- # Get city info
530
- city_info = SupportedCities.get_city_by_tenant_id(tenant_id)
531
- if not city_info:
532
- supported = [c["tenant_id"] for c in get_all_supported_cities()]
533
- return JSONResponse(
534
- status_code=status.HTTP_404_NOT_FOUND,
535
- content={
536
- "error": f"City not found: {tenant_id}",
537
- "message": f"I don't have data for '{tenant_id}' yet. Try one of the supported cities!",
538
- "supported_cities": supported,
539
- "timestamp": datetime.utcnow().isoformat()
540
- }
541
- )
542
-
543
- # Get coordinates
544
- coords = get_city_coordinates(tenant_id)
545
- if not coords:
546
- return JSONResponse(
547
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
548
- content={
549
- "error": "City coordinates not available",
550
- "city": city_info.full_name,
551
- "tenant_id": tenant_id,
552
- "timestamp": datetime.utcnow().isoformat()
553
- }
554
- )
555
-
556
- lat, lon = coords["lat"], coords["lon"]
557
-
558
- weather = await get_weather_for_location(lat=lat, lon=lon)
559
- return JSONResponse(
560
- status_code=status.HTTP_200_OK,
561
- content={
562
- "city": city_info.full_name,
563
- "tenant_id": tenant_id,
564
- "coordinates": {"latitude": lat, "longitude": lon},
565
- "weather": weather,
566
- "source": "Azure Maps Weather API",
567
- "timestamp": datetime.utcnow().isoformat()
568
- }
569
- )
570
- except Exception as e:
571
- logger.error(f"Weather lookup failed for {tenant_id}: {e}", exc_info=True)
572
- return JSONResponse(
573
- status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
574
- content={
575
- "error": "Weather service temporarily unavailable",
576
- "message": "We're having trouble getting the weather right now. Please try again in a moment!",
577
- "tenant_id": tenant_id,
578
- "timestamp": datetime.utcnow().isoformat()
579
- }
580
- )
581
-
582
- # ============================================================
583
- # DEBUG ENDPOINTS (Only available in debug mode)
584
- # ============================================================
585
-
586
- @app.get("/debug/validation", tags=["Debug"], include_in_schema=False)
587
- async def debug_validation() -> JSONResponse:
588
- """
589
- 🧪 Debug endpoint: Shows data file validation status.
590
- Only available when DEBUG_MODE=true
591
- """
592
- if os.getenv("DEBUG_MODE", "false").lower() != "true":
593
- return JSONResponse(
594
- status_code=status.HTTP_403_FORBIDDEN,
595
- content={"error": "Debug endpoints are disabled in production"}
596
- )
597
-
598
- try:
599
- validation = validate_city_data_files()
600
- return JSONResponse(
601
- status_code=status.HTTP_200_OK,
602
- content={
603
- "validation": validation,
604
- "summary": {
605
- "total_cities": len(validation),
606
- "cities_with_events": sum(1 for v in validation.values() if v.get("events", False)),
607
- "cities_with_resources": sum(1 for v in validation.values() if v.get("resources", False))
608
- },
609
- "timestamp": datetime.utcnow().isoformat()
610
- }
611
- )
612
- except Exception as e:
613
- logger.error(f"Debug validation failed: {e}", exc_info=True)
614
- return JSONResponse(
615
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
616
- content={"error": str(e)}
617
- )
618
-
619
- @app.get("/debug/env", tags=["Debug"], include_in_schema=False)
620
- async def debug_environment() -> JSONResponse:
621
- """
622
- 🧪 Debug endpoint: Shows environment configuration.
623
- Sensitive values are masked. Only available when DEBUG_MODE=true
624
- """
625
- if os.getenv("DEBUG_MODE", "false").lower() != "true":
626
- return JSONResponse(
627
- status_code=status.HTTP_403_FORBIDDEN,
628
- content={"error": "Debug endpoints are disabled in production"}
629
- )
630
-
631
- def mask_sensitive(key: str, value: str) -> str:
632
- """Masks sensitive environment variables."""
633
- sensitive_keys = ["key", "secret", "password", "token"]
634
- if any(s in key.lower() for s in sensitive_keys):
635
- return f"{value[:4]}...{value[-4:]}" if len(value) > 8 else "***"
636
- return value
637
-
638
- try:
639
- env_vars = {
640
- key: mask_sensitive(key, value)
641
- for key, value in os.environ.items()
642
- if key.startswith(("AZURE_", "PENNY_", "DEBUG_", "ENVIRONMENT"))
643
- }
644
-
645
- return JSONResponse(
646
- status_code=status.HTTP_200_OK,
647
- content={
648
- "environment_variables": env_vars,
649
- "project_root": str(PROJECT_ROOT),
650
- "location_system_healthy": app.state.location_system_healthy,
651
- "startup_errors": app.state.startup_errors,
652
- "timestamp": datetime.utcnow().isoformat()
653
- }
654
- )
655
- except Exception as e:
656
- logger.error(f"Debug environment check failed: {e}", exc_info=True)
657
- return JSONResponse(
658
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
659
- content={"error": str(e)}
660
- )