Aniket2006 commited on
Commit
fe5cad6
·
1 Parent(s): f66abc9

Security: Load API keys from environment variable instead of hardcoding

Browse files
Files changed (2) hide show
  1. app.py +3 -30
  2. groq_client.py +8 -28
app.py CHANGED
@@ -476,43 +476,16 @@ def generate_heatmap_image(data: np.ndarray, index_type: str, gaussian_sigma: fl
476
  # LLM ANALYSIS (for risk metrics)
477
  # ============================================================================
478
 
479
- # Groq API keys with cascading fallback (21 keys total)
480
- GROQ_API_KEYS = [
481
- # Original keys
482
- "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",
483
- "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",
484
- "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",
485
- "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",
486
- "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",
487
- "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",
488
- "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",
489
- "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",
490
- "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",
491
- # Keys added 2025-12-09 (batch 1)
492
- "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",
493
- "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",
494
- "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",
495
- "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",
496
- "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",
497
- "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",
498
- "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",
499
- "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",
500
- "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",
501
- # Keys added 2025-12-09 (batch 2)
502
- "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",
503
- "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",
504
- "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",
505
- ]
506
 
507
  def run_llm_analysis(metric: str, stress_context: dict, indices_data: dict,
508
  time_series_data: dict = None, weather_data: dict = None) -> dict:
509
  """Call Groq LLM with full context from stress detection, timeseries, and weather.
510
- Uses cascading fallback through 4 API keys if one fails."""
511
  from groq import Groq
512
  import json
513
 
514
- GROQ_MODEL = "llama-3.3-70b-versatile"
515
-
516
  # Format stress context
517
  stress_text = format_stress_context(stress_context)
518
 
 
476
  # LLM ANALYSIS (for risk metrics)
477
  # ============================================================================
478
 
479
+ # Import API keys from centralized module (loaded from environment)
480
+ from groq_client import GROQ_API_KEYS, GROQ_MODEL
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
 
482
  def run_llm_analysis(metric: str, stress_context: dict, indices_data: dict,
483
  time_series_data: dict = None, weather_data: dict = None) -> dict:
484
  """Call Groq LLM with full context from stress detection, timeseries, and weather.
485
+ Uses cascading fallback through API keys."""
486
  from groq import Groq
487
  import json
488
 
 
 
489
  # Format stress context
490
  stress_text = format_stress_context(stress_context)
491
 
groq_client.py CHANGED
@@ -4,12 +4,13 @@ AGROW Centralized Groq Client
4
  Shared LLM client with key rotation and fallback for all AGROW backend services.
5
 
6
  Features:
7
- - Centralized API key pool (15 keys)
8
  - Automatic key rotation on rate limits (429)
9
  - Exponential backoff per key
10
  - Detailed logging for debugging
11
  """
12
 
 
13
  import time
14
  import logging
15
  from typing import Optional
@@ -23,33 +24,12 @@ logger = logging.getLogger("GroqClient")
23
  # GROQ API CONFIGURATION
24
  # ============================================================================
25
 
26
- # Full pool of Groq API keys for rotation
27
- GROQ_API_KEYS = [
28
- # Original keys
29
- "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",
30
- "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",
31
- "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",
32
- "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",
33
- "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",
34
- "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",
35
- "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",
36
- "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",
37
- "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",
38
- # Keys added 2025-12-09 (batch 1)
39
- "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",
40
- "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",
41
- "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",
42
- "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",
43
- "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",
44
- "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",
45
- "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",
46
- "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",
47
- "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",
48
- # Keys added 2025-12-09 (batch 2)
49
- "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",
50
- "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",
51
- "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",
52
- ]
53
 
54
  GROQ_MODEL = "llama-3.3-70b-versatile"
55
 
 
4
  Shared LLM client with key rotation and fallback for all AGROW backend services.
5
 
6
  Features:
7
+ - Centralized API key pool loaded from environment
8
  - Automatic key rotation on rate limits (429)
9
  - Exponential backoff per key
10
  - Detailed logging for debugging
11
  """
12
 
13
+ import os
14
  import time
15
  import logging
16
  from typing import Optional
 
24
  # GROQ API CONFIGURATION
25
  # ============================================================================
26
 
27
+ # Load API keys from environment variable (comma-separated)
28
+ GROQ_API_KEYS_ENV = os.environ.get("GROQ_API_KEYS", "")
29
+ GROQ_API_KEYS = [key.strip() for key in GROQ_API_KEYS_ENV.split(",") if key.strip()]
30
+
31
+ if not GROQ_API_KEYS:
32
+ logger.warning("[GroqClient] GROQ_API_KEYS environment variable not set or empty!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  GROQ_MODEL = "llama-3.3-70b-versatile"
35