aakashdg commited on
Commit
5e0795d
·
verified ·
1 Parent(s): 8b7d437

feat (testing location selector ui)

Browse files
Files changed (1) hide show
  1. app.py +486 -155
app.py CHANGED
@@ -1,34 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """
2
- Farmer.Chat Backend - FastAPI Application
3
- Deploy to Hugging Face Space: https://huggingface.co/spaces/aakashdg/farmer-chat-backend
4
  """
5
 
6
  from fastapi import FastAPI, HTTPException
7
  from fastapi.middleware.cors import CORSMiddleware
8
- from fastapi.responses import FileResponse, JSONResponse
9
- from pydantic import BaseModel, Field
10
  from typing import Optional, Dict, Any
11
  import os
12
- import asyncio
13
- import time
14
  from datetime import datetime
15
 
16
- # Import pipeline components
17
  from src.pipeline import FarmerChatPipeline
18
- from src.pdf_generator import generate_pdf_report
19
 
20
- # CRITICAL FIX: Import OpenAI with httpx configuration
21
- from openai import OpenAI
22
- import httpx
23
-
24
- # Initialize FastAPI
25
- app = FastAPI(
26
- title="Farmer.Chat Backend",
27
- description="Multi-stage MCP pipeline for agricultural intelligence",
28
- version="2.0.0"
29
- )
30
 
31
- # CORS - Allow all origins for demo (restrict in production)
32
  app.add_middleware(
33
  CORSMiddleware,
34
  allow_origins=["*"],
@@ -37,180 +242,306 @@ app.add_middleware(
37
  allow_headers=["*"],
38
  )
39
 
40
- # Initialize OpenAI client with FIXED httpx configuration
41
- OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
42
- if not OPENAI_API_KEY:
43
- raise ValueError("OPENAI_API_KEY environment variable not set!")
44
-
45
- # FIX: Create httpx client without proxy support
46
- http_client = httpx.Client(
47
- timeout=httpx.Timeout(60.0),
48
- limits=httpx.Limits(max_keepalive_connections=5, max_connections=10)
49
- )
50
-
51
- # Initialize OpenAI with custom http client (bypasses proxy issues)
52
- openai_client = OpenAI(
53
- api_key=OPENAI_API_KEY,
54
- http_client=http_client
55
- )
56
 
57
- print("✅ OpenAI client initialized with custom httpx client")
58
- print(f" Model: gpt-4o")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
- # Default location (Bangalore Agricultural Region)
61
- DEFAULT_LOCATION = {
62
- "name": "Bangalore Agricultural Region",
63
- "lat": 12.8716,
64
- "lon": 77.4946
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  }
66
 
67
- # Initialize pipeline
68
- pipeline = FarmerChatPipeline(openai_client, DEFAULT_LOCATION)
69
 
70
- # Request/Response Models
71
- class QueryRequest(BaseModel):
72
- query: str = Field(..., min_length=3, max_length=500, description="Farmer's question")
73
- location: Optional[Dict[str, Any]] = Field(None, description="Custom location (lat, lon, name)")
74
-
75
- class Config:
76
- json_schema_extra = {
77
- "example": {
78
- "query": "Should I plant rice today?",
79
- "location": {
80
- "name": "Bangalore",
81
- "lat": 12.8716,
82
- "lon": 77.4946
83
- }
84
- }
85
- }
86
 
87
 
88
- class QueryResponse(BaseModel):
89
- success: bool
90
- query: str
91
- advice: str
92
- routing: Dict[str, Any]
93
- data: Dict[str, Any]
94
- execution_time_seconds: float
95
  timestamp: str
 
96
 
97
 
98
- # Health check
99
  @app.get("/")
100
  async def root():
101
  return {
102
- "service": "Farmer.Chat Backend",
103
- "status": "operational",
104
- "version": "2.0.0",
105
  "endpoints": {
106
- "query": "/api/query",
107
- "health": "/api/health",
108
- "servers": "/api/servers"
109
  }
110
  }
111
 
112
 
113
- @app.get("/api/health")
114
- async def health_check():
115
- """Health check endpoint"""
116
- return {
117
- "status": "healthy",
118
- "timestamp": datetime.now().isoformat(),
119
- "openai_configured": bool(OPENAI_API_KEY),
120
- "location": DEFAULT_LOCATION
121
- }
122
-
123
-
124
- @app.get("/api/servers")
125
- async def list_servers():
126
- """List available MCP servers"""
127
- from src.executor import MCP_SERVER_REGISTRY
128
-
129
  return {
130
- "total_servers": len(MCP_SERVER_REGISTRY),
131
- "servers": MCP_SERVER_REGISTRY
 
 
132
  }
133
 
134
 
135
- @app.post("/api/query", response_model=QueryResponse)
136
- async def process_query(request: QueryRequest):
137
  """
138
- Main query endpoint - processes farmer questions through MCP pipeline
 
139
  """
140
  try:
141
- start_time = time.time()
142
-
143
- # Use custom location if provided, otherwise default
144
- location = request.location if request.location else DEFAULT_LOCATION
145
 
146
- # Update pipeline location if changed
147
- if request.location:
148
- pipeline.location = location
 
 
149
 
150
- # Process query through pipeline
151
- result = await pipeline.process_query(request.query, verbose=False)
152
 
153
- execution_time = time.time() - start_time
154
-
155
- return QueryResponse(
156
- success=True,
157
- query=request.query,
158
- advice=result["advice"],
159
- routing=result["routing"],
160
- data=result["compiled_data"],
161
- execution_time_seconds=round(execution_time, 2),
162
- timestamp=datetime.now().isoformat()
163
- )
164
 
165
- except Exception as e:
166
- raise HTTPException(status_code=500, detail=str(e))
167
-
 
 
 
168
 
169
- @app.post("/api/export-pdf")
170
- async def export_pdf(request: QueryRequest):
171
- """
172
- Export query result as PDF
173
- """
174
- try:
175
- # Process query
176
- result = await pipeline.process_query(request.query, verbose=False)
177
-
178
- # Generate PDF
179
- pdf_path = generate_pdf_report(
180
- query=request.query,
181
- advice=result["advice"],
182
- data=result["compiled_data"],
183
- location=pipeline.location
184
- )
185
 
186
- # Return PDF file
187
- return FileResponse(
188
- pdf_path,
189
- media_type="application/pdf",
190
- filename=f"farmer-chat-report-{int(time.time())}.pdf"
 
191
  )
192
 
 
 
193
  except Exception as e:
194
  raise HTTPException(status_code=500, detail=str(e))
195
 
196
 
197
- # Error handlers
198
- @app.exception_handler(404)
199
- async def not_found_handler(request, exc):
200
- return JSONResponse(
201
- status_code=404,
202
- content={"error": "Endpoint not found", "path": str(request.url)}
203
- )
204
-
205
-
206
- @app.exception_handler(500)
207
- async def server_error_handler(request, exc):
208
- return JSONResponse(
209
- status_code=500,
210
- content={"error": "Internal server error", "detail": str(exc)}
211
- )
212
 
213
 
214
  if __name__ == "__main__":
215
  import uvicorn
216
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
 
1
+ # """
2
+ # Farmer.Chat Backend - FastAPI Application
3
+ # Deploy to Hugging Face Space: https://huggingface.co/spaces/aakashdg/farmer-chat-backend
4
+ # """
5
+
6
+ # from fastapi import FastAPI, HTTPException
7
+ # from fastapi.middleware.cors import CORSMiddleware
8
+ # from fastapi.responses import FileResponse, JSONResponse
9
+ # from pydantic import BaseModel, Field
10
+ # from typing import Optional, Dict, Any
11
+ # import os
12
+ # import asyncio
13
+ # import time
14
+ # from datetime import datetime
15
+
16
+ # # Import pipeline components
17
+ # from src.pipeline import FarmerChatPipeline
18
+ # from src.pdf_generator import generate_pdf_report
19
+
20
+ # # CRITICAL FIX: Import OpenAI with httpx configuration
21
+ # from openai import OpenAI
22
+ # import httpx
23
+
24
+ # # Initialize FastAPI
25
+ # app = FastAPI(
26
+ # title="Farmer.Chat Backend",
27
+ # description="Multi-stage MCP pipeline for agricultural intelligence",
28
+ # version="2.0.0"
29
+ # )
30
+
31
+ # # CORS - Allow all origins for demo (restrict in production)
32
+ # app.add_middleware(
33
+ # CORSMiddleware,
34
+ # allow_origins=["*"],
35
+ # allow_credentials=True,
36
+ # allow_methods=["*"],
37
+ # allow_headers=["*"],
38
+ # )
39
+
40
+ # # Initialize OpenAI client with FIXED httpx configuration
41
+ # OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
42
+ # if not OPENAI_API_KEY:
43
+ # raise ValueError("OPENAI_API_KEY environment variable not set!")
44
+
45
+ # # FIX: Create httpx client without proxy support
46
+ # http_client = httpx.Client(
47
+ # timeout=httpx.Timeout(60.0),
48
+ # limits=httpx.Limits(max_keepalive_connections=5, max_connections=10)
49
+ # )
50
+
51
+ # # Initialize OpenAI with custom http client (bypasses proxy issues)
52
+ # openai_client = OpenAI(
53
+ # api_key=OPENAI_API_KEY,
54
+ # http_client=http_client
55
+ # )
56
+
57
+ # print("✅ OpenAI client initialized with custom httpx client")
58
+ # print(f" Model: gpt-4o")
59
+
60
+ # # Default location (Bangalore Agricultural Region)
61
+ # DEFAULT_LOCATION = {
62
+ # "name": "Bangalore Agricultural Region",
63
+ # "lat": 12.8716,
64
+ # "lon": 77.4946
65
+ # }
66
+
67
+ # # Initialize pipeline
68
+ # pipeline = FarmerChatPipeline(openai_client, DEFAULT_LOCATION)
69
+
70
+ # # Request/Response Models
71
+ # class QueryRequest(BaseModel):
72
+ # query: str = Field(..., min_length=3, max_length=500, description="Farmer's question")
73
+ # location: Optional[Dict[str, Any]] = Field(None, description="Custom location (lat, lon, name)")
74
+
75
+ # class Config:
76
+ # json_schema_extra = {
77
+ # "example": {
78
+ # "query": "Should I plant rice today?",
79
+ # "location": {
80
+ # "name": "Bangalore",
81
+ # "lat": 12.8716,
82
+ # "lon": 77.4946
83
+ # }
84
+ # }
85
+ # }
86
+
87
+
88
+ # class QueryResponse(BaseModel):
89
+ # success: bool
90
+ # query: str
91
+ # advice: str
92
+ # routing: Dict[str, Any]
93
+ # data: Dict[str, Any]
94
+ # execution_time_seconds: float
95
+ # timestamp: str
96
+
97
+
98
+ # # Health check
99
+ # @app.get("/")
100
+ # async def root():
101
+ # return {
102
+ # "service": "Farmer.Chat Backend",
103
+ # "status": "operational",
104
+ # "version": "2.0.0",
105
+ # "endpoints": {
106
+ # "query": "/api/query",
107
+ # "health": "/api/health",
108
+ # "servers": "/api/servers"
109
+ # }
110
+ # }
111
+
112
+
113
+ # @app.get("/api/health")
114
+ # async def health_check():
115
+ # """Health check endpoint"""
116
+ # return {
117
+ # "status": "healthy",
118
+ # "timestamp": datetime.now().isoformat(),
119
+ # "openai_configured": bool(OPENAI_API_KEY),
120
+ # "location": DEFAULT_LOCATION
121
+ # }
122
+
123
+
124
+ # @app.get("/api/servers")
125
+ # async def list_servers():
126
+ # """List available MCP servers"""
127
+ # from src.executor import MCP_SERVER_REGISTRY
128
+
129
+ # return {
130
+ # "total_servers": len(MCP_SERVER_REGISTRY),
131
+ # "servers": MCP_SERVER_REGISTRY
132
+ # }
133
+
134
+
135
+ # @app.post("/api/query", response_model=QueryResponse)
136
+ # async def process_query(request: QueryRequest):
137
+ # """
138
+ # Main query endpoint - processes farmer questions through MCP pipeline
139
+ # """
140
+ # try:
141
+ # start_time = time.time()
142
+
143
+ # # Use custom location if provided, otherwise default
144
+ # location = request.location if request.location else DEFAULT_LOCATION
145
+
146
+ # # Update pipeline location if changed
147
+ # if request.location:
148
+ # pipeline.location = location
149
+
150
+ # # Process query through pipeline
151
+ # result = await pipeline.process_query(request.query, verbose=False)
152
+
153
+ # execution_time = time.time() - start_time
154
+
155
+ # return QueryResponse(
156
+ # success=True,
157
+ # query=request.query,
158
+ # advice=result["advice"],
159
+ # routing=result["routing"],
160
+ # data=result["compiled_data"],
161
+ # execution_time_seconds=round(execution_time, 2),
162
+ # timestamp=datetime.now().isoformat()
163
+ # )
164
+
165
+ # except Exception as e:
166
+ # raise HTTPException(status_code=500, detail=str(e))
167
+
168
+
169
+ # @app.post("/api/export-pdf")
170
+ # async def export_pdf(request: QueryRequest):
171
+ # """
172
+ # Export query result as PDF
173
+ # """
174
+ # try:
175
+ # # Process query
176
+ # result = await pipeline.process_query(request.query, verbose=False)
177
+
178
+ # # Generate PDF
179
+ # pdf_path = generate_pdf_report(
180
+ # query=request.query,
181
+ # advice=result["advice"],
182
+ # data=result["compiled_data"],
183
+ # location=pipeline.location
184
+ # )
185
+
186
+ # # Return PDF file
187
+ # return FileResponse(
188
+ # pdf_path,
189
+ # media_type="application/pdf",
190
+ # filename=f"farmer-chat-report-{int(time.time())}.pdf"
191
+ # )
192
+
193
+ # except Exception as e:
194
+ # raise HTTPException(status_code=500, detail=str(e))
195
+
196
+
197
+ # # Error handlers
198
+ # @app.exception_handler(404)
199
+ # async def not_found_handler(request, exc):
200
+ # return JSONResponse(
201
+ # status_code=404,
202
+ # content={"error": "Endpoint not found", "path": str(request.url)}
203
+ # )
204
+
205
+
206
+ # @app.exception_handler(500)
207
+ # async def server_error_handler(request, exc):
208
+ # return JSONResponse(
209
+ # status_code=500,
210
+ # content={"error": "Internal server error", "detail": str(exc)}
211
+ # )
212
+
213
+
214
+ # if __name__ == "__main__":
215
+ # import uvicorn
216
+ # uvicorn.run(app, host="0.0.0.0", port=7860)
217
+
218
  """
219
+ Alert Summary Generator Backend
220
+ Modified FastAPI app with location-based alert generation
221
  """
222
 
223
  from fastapi import FastAPI, HTTPException
224
  from fastapi.middleware.cors import CORSMiddleware
225
+ from pydantic import BaseModel
 
226
  from typing import Optional, Dict, Any
227
  import os
 
 
228
  from datetime import datetime
229
 
230
+ # Import existing pipeline components
231
  from src.pipeline import FarmerChatPipeline
232
+ from src.client import get_openai_client
233
 
234
+ app = FastAPI(title="Farmer.chat Alert Summary API")
 
 
 
 
 
 
 
 
 
235
 
236
+ # CORS middleware
237
  app.add_middleware(
238
  CORSMiddleware,
239
  allow_origins=["*"],
 
242
  allow_headers=["*"],
243
  )
244
 
245
+ # Initialize OpenAI client and pipeline
246
+ openai_client = get_openai_client()
247
+ DEFAULT_LOCATION = {"latitude": 25.5941, "longitude": 85.1376} # Patna default
248
+ pipeline = FarmerChatPipeline(openai_client, DEFAULT_LOCATION)
 
 
 
 
 
 
 
 
 
 
 
 
249
 
250
+ # Bihar location data
251
+ BIHAR_DATA = {
252
+ "Araria": ["Araria", "Forbesganj", "Jokihat", "Raniganj"],
253
+ "Arwal": ["Arwal", "Kaler", "Karpi", "Kurtha"],
254
+ "Aurangabad": ["Aurangabad", "Daudnagar", "Obra", "Nabinagar"],
255
+ "Banka": ["Banka", "Amarpur", "Barahat", "Belhar"],
256
+ "Begusarai": ["Begusarai", "Bakhri", "Barauni", "Teghra"],
257
+ "Bhagalpur": ["Bhagalpur", "Sabour", "Nathnagar", "Kahalgaon"],
258
+ "Bhojpur": ["Arrah", "Jagdishpur", "Piro", "Shahpur"],
259
+ "Buxar": ["Buxar", "Dumraon", "Chausa", "Simri"],
260
+ "Darbhanga": ["Darbhanga", "Baheri", "Jale", "Benipur"],
261
+ "East Champaran": ["Motihari", "Raxaul", "Chakia", "Dhaka"],
262
+ "Gaya": ["Gaya", "Bodh Gaya", "Tekari", "Sherghati"],
263
+ "Gopalganj": ["Gopalganj", "Barauli", "Baikunthpur", "Kateya"],
264
+ "Jamui": ["Jamui", "Jhajha", "Sikandra", "Sono"],
265
+ "Jehanabad": ["Jehanabad", "Ghoshi", "Makhdumpur", "Modanganj"],
266
+ "Kaimur": ["Bhabua", "Mohania", "Ramgarh", "Chainpur"],
267
+ "Katihar": ["Katihar", "Barsoi", "Manihari", "Pranpur"],
268
+ "Khagaria": ["Khagaria", "Gogri", "Mansi", "Alauli"],
269
+ "Kishanganj": ["Kishanganj", "Bahadurganj", "Thakurganj", "Kochadhaman"],
270
+ "Lakhisarai": ["Lakhisarai", "Barahiya", "Halsi", "Surajgarha"],
271
+ "Madhepura": ["Madhepura", "Bihariganj", "Murliganj", "Udakishunganj"],
272
+ "Madhubani": ["Madhubani", "Jhanjharpur", "Benipatti", "Phulparas"],
273
+ "Munger": ["Munger", "Jamalpur", "Kharagpur", "Tarapur"],
274
+ "Muzaffarpur": ["Muzaffarpur", "Motipur", "Kanti", "Saraiya"],
275
+ "Nalanda": ["Bihar Sharif", "Rajgir", "Hilsa", "Islampur"],
276
+ "Nawada": ["Nawada", "Rajauli", "Hisua", "Warsaliganj"],
277
+ "Patna": ["Patna", "Danapur", "Masaurhi", "Phulwari", "Barh"],
278
+ "Purnia": ["Purnia", "Banmankhi", "Dhamdaha", "Baisi"],
279
+ "Rohtas": ["Sasaram", "Dehri", "Bikramganj", "Nokha"],
280
+ "Saharsa": ["Saharsa", "Simri Bakhtiyarpur", "Salkhua", "Sonbarsa"],
281
+ "Samastipur": ["Samastipur", "Rosera", "Dalsinghsarai", "Patori"],
282
+ "Saran": ["Chhapra", "Marhaura", "Dariapur", "Amnour"],
283
+ "Sheikhpura": ["Sheikhpura", "Barbigha", "Chewara", "Ghatkusumbha"],
284
+ "Sheohar": ["Sheohar", "Piprahi", "Tariyani", "Dumri Katsari"],
285
+ "Sitamarhi": ["Sitamarhi", "Bairgania", "Belsand", "Parihar"],
286
+ "Siwan": ["Siwan", "Maharajganj", "Goriakothi", "Barharia"],
287
+ "Supaul": ["Supaul", "Birpur", "Triveniganj", "Nirmali"],
288
+ "Vaishali": ["Hajipur", "Mahnar", "Lalganj", "Raghopur"],
289
+ "West Champaran": ["Bettiah", "Bagaha", "Narkatiaganj", "Ramnagar"],
290
+ }
291
 
292
+ # Location coordinates
293
+ LOCATIONS = {
294
+ "alauli": {'latitude': 25.6392, 'longitude': 86.3854},
295
+ "amarpur": {'latitude': 25.0217, 'longitude': 86.8932},
296
+ "amnour": {'latitude': 25.9264, 'longitude': 84.9129},
297
+ "araria": {'latitude': 26.1346, 'longitude': 87.4654},
298
+ "arrah": {'latitude': 25.5603, 'longitude': 84.6632},
299
+ "arwal": {'latitude': 25.2369, 'longitude': 84.6738},
300
+ "aurangabad": {'latitude': 24.7863, 'longitude': 84.4145},
301
+ "bagaha": {'latitude': 27.059, 'longitude': 84.2065},
302
+ "bahadurganj": {'latitude': 26.2702, 'longitude': 87.8373},
303
+ "baheri": {'latitude': 26.0043, 'longitude': 86.0405},
304
+ "baikunthpur": {'latitude': 26.2817, 'longitude': 84.7428},
305
+ "bairgania": {'latitude': 26.7401, 'longitude': 85.2755},
306
+ "baisi": {'latitude': 25.8396, 'longitude': 87.7509},
307
+ "bakhri": {'latitude': 25.5743, 'longitude': 86.244},
308
+ "banka": {'latitude': 24.8669, 'longitude': 86.9126},
309
+ "banmankhi": {'latitude': 25.8976, 'longitude': 87.1659},
310
+ "barahat": {'latitude': 24.8869, 'longitude': 87.0296},
311
+ "barahiya": {'latitude': 25.2636, 'longitude': 86.0055},
312
+ "barauli": {'latitude': 26.3966, 'longitude': 84.6005},
313
+ "barauni": {'latitude': 25.4315, 'longitude': 86.0284},
314
+ "barbigha": {'latitude': 25.207, 'longitude': 85.7715},
315
+ "barh": {'latitude': 25.451, 'longitude': 85.7002},
316
+ "barharia": {'latitude': 26.3156, 'longitude': 84.456},
317
+ "barsoi": {'latitude': 25.6206, 'longitude': 87.9744},
318
+ "begusarai": {'latitude': 25.4139, 'longitude': 86.1349},
319
+ "belhar": {'latitude': 24.906, 'longitude': 86.6074},
320
+ "belsand": {'latitude': 26.4323, 'longitude': 85.3946},
321
+ "benipatti": {'latitude': 26.4435, 'longitude': 85.9105},
322
+ "benipur": {'latitude': 26.0754, 'longitude': 86.1245},
323
+ "bettiah": {'latitude': 26.8023, 'longitude': 84.5074},
324
+ "bhabua": {'latitude': 25.0763, 'longitude': 83.6336},
325
+ "bhagalpur": {'latitude': 25.2495, 'longitude': 86.9828},
326
+ "bihar sharif": {'latitude': 25.1939, 'longitude': 85.5209},
327
+ "bihariganj": {'latitude': 25.741, 'longitude': 86.9758},
328
+ "bikramganj": {'latitude': 25.2184, 'longitude': 84.2324},
329
+ "birpur": {'latitude': 26.5152, 'longitude': 87.0085},
330
+ "bodh gaya": {'latitude': 24.6776, 'longitude': 84.9727},
331
+ "buxar": {'latitude': 25.5612, 'longitude': 83.9813},
332
+ "chainpur": {'latitude': 24.9811, 'longitude': 83.4203},
333
+ "chakia": {'latitude': 26.4704, 'longitude': 84.9933},
334
+ "chausa": {'latitude': 25.4514, 'longitude': 83.8621},
335
+ "chewara": {'latitude': 25.054, 'longitude': 85.9335},
336
+ "chhapra": {'latitude': 25.7784, 'longitude': 84.7515},
337
+ "dalsinghsarai": {'latitude': 25.6727, 'longitude': 85.8124},
338
+ "danapur": {'latitude': 25.6359, 'longitude': 85.0474},
339
+ "darbhanga": {'latitude': 26.157, 'longitude': 85.8995},
340
+ "dariapur": {'latitude': 25.8275, 'longitude': 85.0565},
341
+ "daudnagar": {'latitude': 25.044, 'longitude': 84.4323},
342
+ "dehri": {'latitude': 24.9259, 'longitude': 84.1729},
343
+ "dhaka": {'latitude': 26.6924, 'longitude': 85.1986},
344
+ "dhamdaha": {'latitude': 25.7378, 'longitude': 87.2338},
345
+ "dumraon": {'latitude': 25.5238, 'longitude': 84.16},
346
+ "dumri katsari": {'latitude': 26.4691, 'longitude': 85.2195},
347
+ "forbesganj": {'latitude': 26.2784, 'longitude': 87.2988},
348
+ "gaya": {'latitude': 24.7964, 'longitude': 85.008},
349
+ "ghatkusumbha": {'latitude': 25.2127, 'longitude': 85.9308},
350
+ "ghoshi": {'latitude': 25.1296, 'longitude': 85.0976},
351
+ "gogri": {'latitude': 25.4294, 'longitude': 86.7107},
352
+ "gopalganj": {'latitude': 26.5382, 'longitude': 84.4589},
353
+ "goriakothi": {'latitude': 26.2448, 'longitude': 84.575},
354
+ "hajipur": {'latitude': 25.6906, 'longitude': 85.209},
355
+ "halsi": {'latitude': 25.0332, 'longitude': 86.0554},
356
+ "hilsa": {'latitude': 25.3007, 'longitude': 85.2494},
357
+ "hisua": {'latitude': 24.8457, 'longitude': 85.3954},
358
+ "islampur": {'latitude': 25.0969, 'longitude': 85.2604},
359
+ "jagdishpur": {'latitude': 25.4819, 'longitude': 84.4569},
360
+ "jale": {'latitude': 26.3563, 'longitude': 85.769},
361
+ "jamalpur": {'latitude': 25.3139, 'longitude': 86.4897},
362
+ "jamui": {'latitude': 24.9669, 'longitude': 86.174},
363
+ "jehanabad": {'latitude': 25.2265, 'longitude': 84.9911},
364
+ "jhajha": {'latitude': 24.7729, 'longitude': 86.3863},
365
+ "jhanjharpur": {'latitude': 26.2872, 'longitude': 86.3404},
366
+ "jokihat": {'latitude': 26.0816, 'longitude': 87.5935},
367
+ "kahalgaon": {'latitude': 25.2652, 'longitude': 87.2835},
368
+ "kaler": {'latitude': 25.1549, 'longitude': 84.5414},
369
+ "kanti": {'latitude': 26.1819, 'longitude': 85.2711},
370
+ "karpi": {'latitude': 25.1714, 'longitude': 84.7256},
371
+ "kateya": {'latitude': 26.5723, 'longitude': 84.0811},
372
+ "katihar": {'latitude': 25.5434, 'longitude': 87.569},
373
+ "khagaria": {'latitude': 25.5064, 'longitude': 86.4663},
374
+ "kharagpur": {'latitude': 25.133, 'longitude': 86.5248},
375
+ "kishanganj": {'latitude': 26.1014, 'longitude': 87.9508},
376
+ "kochadhaman": {'latitude': 26.1014, 'longitude': 87.9508},
377
+ "kurtha": {'latitude': 25.1333, 'longitude': 84.8113},
378
+ "lakhisarai": {'latitude': 25.1678, 'longitude': 86.0594},
379
+ "lalganj": {'latitude': 25.8521, 'longitude': 85.1896},
380
+ "madhepura": {'latitude': 25.926, 'longitude': 86.8204},
381
+ "madhubani": {'latitude': 26.3489, 'longitude': 86.0772},
382
+ "maharajganj": {'latitude': 26.141, 'longitude': 84.5318},
383
+ "mahnar": {'latitude': 25.622, 'longitude': 85.5091},
384
+ "makhdumpur": {'latitude': 25.0739, 'longitude': 84.9879},
385
+ "manihari": {'latitude': 25.3414, 'longitude': 87.6195},
386
+ "mansi": {'latitude': 25.546, 'longitude': 86.5504},
387
+ "marhaura": {'latitude': 25.9302, 'longitude': 84.795},
388
+ "masaurhi": {'latitude': 25.3516, 'longitude': 84.9873},
389
+ "modanganj": {'latitude': 25.2591, 'longitude': 85.1584},
390
+ "mohania": {'latitude': 25.1677, 'longitude': 83.6216},
391
+ "motihari": {'latitude': 26.6507, 'longitude': 84.9115},
392
+ "motipur": {'latitude': 26.2571, 'longitude': 85.1689},
393
+ "munger": {'latitude': 25.3774, 'longitude': 86.4731},
394
+ "murliganj": {'latitude': 25.8764, 'longitude': 86.9369},
395
+ "muzaffarpur": {'latitude': 26.1183, 'longitude': 85.3858},
396
+ "nabinagar": {'latitude': 24.6428, 'longitude': 84.0968},
397
+ "narkatiaganj": {'latitude': 27.0969, 'longitude': 84.4585},
398
+ "nathnagar": {'latitude': 25.2184, 'longitude': 86.9177},
399
+ "nawada": {'latitude': 24.9348, 'longitude': 85.5488},
400
+ "nirmali": {'latitude': 26.3789, 'longitude': 86.7324},
401
+ "nokha": {'latitude': 25.0832, 'longitude': 84.0932},
402
+ "obra": {'latitude': 24.9377, 'longitude': 84.4326},
403
+ "parihar": {'latitude': 26.7512, 'longitude': 85.6799},
404
+ "patna": {'latitude': 25.6093, 'longitude': 85.1235},
405
+ "patori": {'latitude': 25.622, 'longitude': 85.5869},
406
+ "phulparas": {'latitude': 26.386, 'longitude': 86.4547},
407
+ "phulwari": {'latitude': 25.543, 'longitude': 85.0523},
408
+ "piprahi": {'latitude': 26.3489, 'longitude': 86.0772},
409
+ "piro": {'latitude': 25.3383, 'longitude': 84.3541},
410
+ "pranpur": {'latitude': 25.4876, 'longitude': 87.7082},
411
+ "purnia": {'latitude': 25.7774, 'longitude': 87.4731},
412
+ "raghopur": {'latitude': 25.5714, 'longitude': 85.3241},
413
+ "rajauli": {'latitude': 24.6343, 'longitude': 85.5609},
414
+ "rajgir": {'latitude': 25.03, 'longitude': 85.4207},
415
+ "ramgarh": {'latitude': 25.304, 'longitude': 83.6808},
416
+ "ramnagar": {'latitude': 27.2909, 'longitude': 84.2936},
417
+ "raniganj": {'latitude': 26.0553, 'longitude': 87.3077},
418
+ "raxaul": {'latitude': 26.9869, 'longitude': 84.8447},
419
+ "rosera": {'latitude': 25.7798, 'longitude': 86.0425},
420
+ "sabour": {'latitude': 25.2282, 'longitude': 87.0636},
421
+ "saharsa": {'latitude': 25.8759, 'longitude': 86.5927},
422
+ "salkhua": {'latitude': 25.6653, 'longitude': 86.5498},
423
+ "samastipur": {'latitude': 25.8597, 'longitude': 85.7839},
424
+ "saraiya": {'latitude': 26.0701, 'longitude': 85.1843},
425
+ "sasaram": {'latitude': 24.951, 'longitude': 84.0149},
426
+ "shahpur": {'latitude': 25.6593, 'longitude': 84.4295},
427
+ "sheikhpura": {'latitude': 25.1493, 'longitude': 85.8766},
428
+ "sheohar": {'latitude': 26.5158, 'longitude': 85.2849},
429
+ "sherghati": {'latitude': 24.5939, 'longitude': 84.8479},
430
+ "sikandra": {'latitude': 24.9251, 'longitude': 86.0462},
431
+ "simri": {'latitude': 25.6499, 'longitude': 84.1384},
432
+ "simri bakhtiyarpur": {'latitude': 25.7209, 'longitude': 86.5975},
433
+ "sitamarhi": {'latitude': 26.5943, 'longitude': 85.5004},
434
+ "siwan": {'latitude': 26.2185, 'longitude': 84.3585},
435
+ "sonbarsa": {'latitude': 25.7013, 'longitude': 86.7794},
436
+ "sono": {'latitude': 24.6998, 'longitude': 86.2794},
437
+ "supaul": {'latitude': 26.0846, 'longitude': 86.5785},
438
+ "surajgarha": {'latitude': 25.188, 'longitude': 86.2868},
439
+ "tarapur": {'latitude': 25.1039, 'longitude': 86.647},
440
+ "tariyani": {'latitude': 26.5158, 'longitude': 85.2849},
441
+ "teghra": {'latitude': 25.4727, 'longitude': 85.9368},
442
+ "tekari": {'latitude': 24.9411, 'longitude': 84.843},
443
+ "thakurganj": {'latitude': 26.4275, 'longitude': 88.129},
444
+ "triveniganj": {'latitude': 26.127, 'longitude': 86.8873},
445
+ "udakishunganj": {'latitude': 25.926, 'longitude': 86.8204},
446
+ "warsaliganj": {'latitude': 24.9348, 'longitude': 85.5488},
447
  }
448
 
 
 
449
 
450
+ class LocationRequest(BaseModel):
451
+ location_name: str
452
+ district: Optional[str] = None
 
 
 
 
 
 
 
 
 
 
 
 
 
453
 
454
 
455
+ class AlertResponse(BaseModel):
456
+ location: str
457
+ coordinates: Dict[str, float]
458
+ alert_summary: str
 
 
 
459
  timestamp: str
460
+ district: Optional[str] = None
461
 
462
 
 
463
  @app.get("/")
464
  async def root():
465
  return {
466
+ "message": "Farmer.chat Alert Summary API",
467
+ "version": "1.0.0",
 
468
  "endpoints": {
469
+ "/locations": "Get all available districts and villages",
470
+ "/generate-alert": "Generate alert summary for a location"
 
471
  }
472
  }
473
 
474
 
475
+ @app.get("/locations")
476
+ async def get_locations():
477
+ """Get all available districts and villages in Bihar"""
 
 
 
 
 
 
 
 
 
 
 
 
 
478
  return {
479
+ "state": "Bihar",
480
+ "districts": BIHAR_DATA,
481
+ "total_districts": len(BIHAR_DATA),
482
+ "total_villages": sum(len(villages) for villages in BIHAR_DATA.values())
483
  }
484
 
485
 
486
+ @app.post("/generate-alert", response_model=AlertResponse)
487
+ async def generate_alert(request: LocationRequest):
488
  """
489
+ Generate comprehensive alert summary for a specific location.
490
+ Automatically queries all MCP servers (Weather, Soil, Water, Elevation, Pests).
491
  """
492
  try:
493
+ # Get coordinates for the location
494
+ location_key = request.location_name.lower()
495
+ coords = LOCATIONS.get(location_key)
 
496
 
497
+ if not coords:
498
+ raise HTTPException(
499
+ status_code=404,
500
+ detail=f"Location '{request.location_name}' not found in database"
501
+ )
502
 
503
+ # Update pipeline location
504
+ pipeline.location = coords
505
 
506
+ # Create comprehensive query for alert generation
507
+ alert_query = f"""Generate a comprehensive agricultural alert summary for {request.location_name}, Bihar.
 
 
 
 
 
 
 
 
 
508
 
509
+ Please provide:
510
+ 1. Weather conditions and forecast
511
+ 2. Soil analysis and recommendations
512
+ 3. Water availability status
513
+ 4. Elevation and topography considerations
514
+ 5. Pest risk assessment and preventive measures
515
 
516
+ Format the response as a clear, actionable alert summary for farmers."""
517
+
518
+ # Process through the pipeline
519
+ result = await pipeline.process(alert_query, coords)
 
 
 
 
 
 
 
 
 
 
 
 
520
 
521
+ return AlertResponse(
522
+ location=request.location_name.title(),
523
+ coordinates=coords,
524
+ alert_summary=result,
525
+ timestamp=datetime.utcnow().isoformat(),
526
+ district=request.district
527
  )
528
 
529
+ except HTTPException:
530
+ raise
531
  except Exception as e:
532
  raise HTTPException(status_code=500, detail=str(e))
533
 
534
 
535
+ @app.get("/health")
536
+ async def health_check():
537
+ return {
538
+ "status": "healthy",
539
+ "timestamp": datetime.utcnow().isoformat(),
540
+ "pipeline_initialized": pipeline is not None
541
+ }
 
 
 
 
 
 
 
 
542
 
543
 
544
  if __name__ == "__main__":
545
  import uvicorn
546
+ port = int(os.getenv("PORT", 7860))
547
+ uvicorn.run(app, host="0.0.0.0", port=port)