Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -19,17 +19,26 @@ from typing import Dict, List, Any
|
|
| 19 |
# Load environment variables
|
| 20 |
load_dotenv()
|
| 21 |
|
| 22 |
-
# Environment-based configuration
|
| 23 |
SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY", "")
|
| 24 |
MODAL_TOKEN_ID = os.getenv("MODAL_TOKEN_ID", "")
|
| 25 |
MODAL_TOKEN_SECRET = os.getenv("MODAL_TOKEN_SECRET", "")
|
| 26 |
USDA_NASS_API_KEY = os.getenv("USDA_NASS_API_KEY", "")
|
| 27 |
-
|
|
|
|
|
|
|
| 28 |
GRADIO_SERVER_NAME = os.getenv("GRADIO_SERVER_NAME", "0.0.0.0")
|
| 29 |
-
GRADIO_SHARE = os.getenv("GRADIO_SHARE", "false").lower() == "
|
| 30 |
DEBUG_MODE = os.getenv("DEBUG_MODE", "false").lower() == "true"
|
| 31 |
CONTEXT7_ENABLED = os.getenv("CONTEXT7_ENABLED", "true").lower() == "true"
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
# MCP Server Configuration
|
| 34 |
MCP_SERVER_ENABLED = True
|
| 35 |
MCP_TOOLS_AVAILABLE = [
|
|
@@ -55,7 +64,7 @@ class MCPAgriculturalAI:
|
|
| 55 |
async def generate_analysis(self, prompt: str, context: Dict) -> str:
|
| 56 |
"""Generate real AI analysis using SambaNova API"""
|
| 57 |
if not self.available:
|
| 58 |
-
return
|
| 59 |
|
| 60 |
try:
|
| 61 |
headers = {
|
|
@@ -80,7 +89,7 @@ class MCPAgriculturalAI:
|
|
| 80 |
"max_tokens": 2000
|
| 81 |
}
|
| 82 |
|
| 83 |
-
async with httpx.AsyncClient(timeout=
|
| 84 |
response = await client.post(
|
| 85 |
f"{self.base_url}/chat/completions",
|
| 86 |
headers=headers,
|
|
@@ -91,10 +100,50 @@ class MCPAgriculturalAI:
|
|
| 91 |
result = response.json()
|
| 92 |
return result["choices"][0]["message"]["content"]
|
| 93 |
else:
|
| 94 |
-
return
|
| 95 |
|
| 96 |
except Exception as e:
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
def get_system_status(self) -> Dict:
|
| 100 |
"""Get comprehensive system status for MCP"""
|
|
@@ -1099,16 +1148,74 @@ if __name__ == "__main__":
|
|
| 1099 |
print(f"📍 Server Configuration: {GRADIO_SERVER_NAME}:{GRADIO_SERVER_PORT}")
|
| 1100 |
print(f"🔧 Environment: {'Production' if not DEBUG_MODE else 'Development'}")
|
| 1101 |
print(f"🤖 MCP Server: {'✅ Enabled' if MCP_SERVER_ENABLED else '❌ Disabled'}")
|
| 1102 |
-
print(f"🔑 Environment file: {'.env loaded' if os.path.exists('.env') else 'using
|
| 1103 |
|
| 1104 |
-
|
| 1105 |
-
|
|
|
|
| 1106 |
|
| 1107 |
-
|
| 1108 |
-
|
| 1109 |
-
|
| 1110 |
-
|
| 1111 |
-
|
| 1112 |
-
|
| 1113 |
-
|
| 1114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
# Load environment variables
|
| 20 |
load_dotenv()
|
| 21 |
|
| 22 |
+
# Environment-based configuration with Spaces compatibility
|
| 23 |
SAMBANOVA_API_KEY = os.getenv("SAMBANOVA_API_KEY", "")
|
| 24 |
MODAL_TOKEN_ID = os.getenv("MODAL_TOKEN_ID", "")
|
| 25 |
MODAL_TOKEN_SECRET = os.getenv("MODAL_TOKEN_SECRET", "")
|
| 26 |
USDA_NASS_API_KEY = os.getenv("USDA_NASS_API_KEY", "")
|
| 27 |
+
OPENWEATHER_API_KEY = os.getenv("OPENWEATHER_API_KEY", "")
|
| 28 |
+
# Hugging Face Spaces uses port 7860 by default
|
| 29 |
+
GRADIO_SERVER_PORT = int(os.getenv("GRADIO_SERVER_PORT", "7860"))
|
| 30 |
GRADIO_SERVER_NAME = os.getenv("GRADIO_SERVER_NAME", "0.0.0.0")
|
| 31 |
+
GRADIO_SHARE = os.getenv("GRADIO_SHARE", "false").lower() == "true" # Disable share for Spaces
|
| 32 |
DEBUG_MODE = os.getenv("DEBUG_MODE", "false").lower() == "true"
|
| 33 |
CONTEXT7_ENABLED = os.getenv("CONTEXT7_ENABLED", "true").lower() == "true"
|
| 34 |
|
| 35 |
+
# Detect if running in Hugging Face Spaces
|
| 36 |
+
IS_SPACES = os.getenv("SPACE_ID") is not None
|
| 37 |
+
if IS_SPACES:
|
| 38 |
+
print("🤗 Running in Hugging Face Spaces environment")
|
| 39 |
+
GRADIO_SHARE = False # Never share when in Spaces
|
| 40 |
+
DEBUG_MODE = False # Disable debug in production Spaces
|
| 41 |
+
|
| 42 |
# MCP Server Configuration
|
| 43 |
MCP_SERVER_ENABLED = True
|
| 44 |
MCP_TOOLS_AVAILABLE = [
|
|
|
|
| 64 |
async def generate_analysis(self, prompt: str, context: Dict) -> str:
|
| 65 |
"""Generate real AI analysis using SambaNova API"""
|
| 66 |
if not self.available:
|
| 67 |
+
return self._get_fallback_analysis(prompt, context)
|
| 68 |
|
| 69 |
try:
|
| 70 |
headers = {
|
|
|
|
| 89 |
"max_tokens": 2000
|
| 90 |
}
|
| 91 |
|
| 92 |
+
async with httpx.AsyncClient(timeout=10.0) as client: # Reduced timeout for Spaces
|
| 93 |
response = await client.post(
|
| 94 |
f"{self.base_url}/chat/completions",
|
| 95 |
headers=headers,
|
|
|
|
| 100 |
result = response.json()
|
| 101 |
return result["choices"][0]["message"]["content"]
|
| 102 |
else:
|
| 103 |
+
return self._get_fallback_analysis(prompt, context)
|
| 104 |
|
| 105 |
except Exception as e:
|
| 106 |
+
print(f"AI API Error (falling back to template): {str(e)}")
|
| 107 |
+
return self._get_fallback_analysis(prompt, context)
|
| 108 |
+
|
| 109 |
+
def _get_fallback_analysis(self, prompt: str, context: Dict) -> str:
|
| 110 |
+
"""Provide fallback analysis when AI API is unavailable"""
|
| 111 |
+
location = context.get("location", {})
|
| 112 |
+
region = context.get("region", {})
|
| 113 |
+
farm = context.get("farm", {})
|
| 114 |
+
|
| 115 |
+
lat = location.get("lat", 0)
|
| 116 |
+
lon = location.get("lon", 0)
|
| 117 |
+
region_name = region.get("name", "Unknown Region")
|
| 118 |
+
|
| 119 |
+
return f"""
|
| 120 |
+
### 🌾 Agricultural Analysis (Fallback Mode)
|
| 121 |
+
|
| 122 |
+
**Location**: {lat:.4f}°N, {lon:.4f}°E ({region_name})
|
| 123 |
+
**Status**: AI analysis temporarily unavailable - using expert templates
|
| 124 |
+
|
| 125 |
+
**Crop Recommendations:**
|
| 126 |
+
• **Wheat**: Excellent choice for temperate climates
|
| 127 |
+
• **Corn**: High yield potential with proper irrigation
|
| 128 |
+
• **Barley**: Good rotation crop with disease resistance
|
| 129 |
+
|
| 130 |
+
**Economic Projections:**
|
| 131 |
+
• Expected revenue: €2,500-3,500/hectare
|
| 132 |
+
• Operating costs: €1,200-1,600/hectare
|
| 133 |
+
• Net profit potential: €1,300-1,900/hectare
|
| 134 |
+
|
| 135 |
+
**Risk Assessment:**
|
| 136 |
+
• Weather risk: Moderate (use crop insurance)
|
| 137 |
+
• Market volatility: Low to moderate
|
| 138 |
+
• Disease pressure: Standard prevention recommended
|
| 139 |
+
|
| 140 |
+
**Sustainability Score: 80/100**
|
| 141 |
+
• Water efficiency: Good
|
| 142 |
+
• Soil health: Maintained with rotation
|
| 143 |
+
• Carbon impact: Neutral to positive
|
| 144 |
+
|
| 145 |
+
*Note: This is a template analysis. For AI-powered insights, please configure API keys.*
|
| 146 |
+
"""
|
| 147 |
|
| 148 |
def get_system_status(self) -> Dict:
|
| 149 |
"""Get comprehensive system status for MCP"""
|
|
|
|
| 1148 |
print(f"📍 Server Configuration: {GRADIO_SERVER_NAME}:{GRADIO_SERVER_PORT}")
|
| 1149 |
print(f"🔧 Environment: {'Production' if not DEBUG_MODE else 'Development'}")
|
| 1150 |
print(f"🤖 MCP Server: {'✅ Enabled' if MCP_SERVER_ENABLED else '❌ Disabled'}")
|
| 1151 |
+
print(f"🔑 Environment file: {'.env loaded' if os.path.exists('.env') else 'using environment variables'}")
|
| 1152 |
|
| 1153 |
+
if IS_SPACES:
|
| 1154 |
+
print("🤗 Optimized for Hugging Face Spaces deployment")
|
| 1155 |
+
print("💡 Tip: Set API keys in Spaces Settings > Repository secrets for full functionality")
|
| 1156 |
|
| 1157 |
+
# Create and launch the MCP-enabled application
|
| 1158 |
+
try:
|
| 1159 |
+
app = create_mcp_application()
|
| 1160 |
+
|
| 1161 |
+
# Spaces-optimized launch configuration
|
| 1162 |
+
if IS_SPACES:
|
| 1163 |
+
# Simplified launch for Spaces
|
| 1164 |
+
app.launch(
|
| 1165 |
+
server_name="0.0.0.0",
|
| 1166 |
+
server_port=7860,
|
| 1167 |
+
share=False,
|
| 1168 |
+
show_error=True,
|
| 1169 |
+
inbrowser=False,
|
| 1170 |
+
favicon_path=None,
|
| 1171 |
+
prevent_thread_lock=False
|
| 1172 |
+
)
|
| 1173 |
+
else:
|
| 1174 |
+
# Full configuration for local/other deployments
|
| 1175 |
+
app.launch(
|
| 1176 |
+
server_name=GRADIO_SERVER_NAME,
|
| 1177 |
+
server_port=GRADIO_SERVER_PORT,
|
| 1178 |
+
share=GRADIO_SHARE,
|
| 1179 |
+
show_error=DEBUG_MODE,
|
| 1180 |
+
inbrowser=True,
|
| 1181 |
+
favicon_path=None
|
| 1182 |
+
)
|
| 1183 |
+
except Exception as e:
|
| 1184 |
+
print(f"❌ Error launching application: {e}")
|
| 1185 |
+
if IS_SPACES:
|
| 1186 |
+
print("🔧 Creating minimal fallback interface...")
|
| 1187 |
+
# Create a minimal fallback interface for Spaces
|
| 1188 |
+
import gradio as gr
|
| 1189 |
+
|
| 1190 |
+
def fallback_message():
|
| 1191 |
+
return """
|
| 1192 |
+
# 🌾 CropCortex MCP Server - Startup Error
|
| 1193 |
+
|
| 1194 |
+
The application encountered an error during startup. This is likely due to:
|
| 1195 |
+
|
| 1196 |
+
1. **Missing API Keys**: Configure SambaNova API key in Spaces settings
|
| 1197 |
+
2. **Dependencies**: Some packages may need to be installed
|
| 1198 |
+
3. **Environment**: Check that all required environment variables are set
|
| 1199 |
+
|
| 1200 |
+
## Quick Fix:
|
| 1201 |
+
1. Go to your Space settings
|
| 1202 |
+
2. Add `SAMBANOVA_API_KEY` in Repository secrets
|
| 1203 |
+
3. Restart the Space
|
| 1204 |
+
|
| 1205 |
+
## Fallback Mode:
|
| 1206 |
+
The application is running in basic mode with limited functionality.
|
| 1207 |
+
"""
|
| 1208 |
+
|
| 1209 |
+
fallback_app = gr.Interface(
|
| 1210 |
+
fn=lambda: fallback_message(),
|
| 1211 |
+
inputs=[],
|
| 1212 |
+
outputs=gr.Markdown(),
|
| 1213 |
+
title="CropCortex MCP - Fallback Mode",
|
| 1214 |
+
description="Agricultural Intelligence Platform (Limited Mode)"
|
| 1215 |
+
)
|
| 1216 |
+
|
| 1217 |
+
fallback_app.launch(
|
| 1218 |
+
server_name="0.0.0.0",
|
| 1219 |
+
server_port=7860,
|
| 1220 |
+
share=False
|
| 1221 |
+
)
|