MYousafRana commited on
Commit
b91a8b9
·
verified ·
1 Parent(s): 1626f55

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +131 -233
main.py CHANGED
@@ -1,233 +1,131 @@
1
- # # main.py
2
- # import os
3
- # from fastapi import FastAPI, HTTPException
4
- # from fastapi.middleware.cors import CORSMiddleware
5
- # from dotenv import load_dotenv
6
- #
7
- # from models import TravelDataInput, PlanResponse, ChatInput, ChatResponse
8
- # from image_searcher import ImageSearcher, create_image_queries, extract_destination
9
- # from gemini_utils import create_travel_plan_prompt, generate_with_gemini, create_chat_prompt
10
- # from rag_utils import get_relevant_plan
11
- #
12
- # # Load environment variables (especially API keys)
13
- # load_dotenv()
14
- # PEXELS_API_KEY = os.getenv("PEXELS_API_KEY", "LB4mRviLcvE72R2645m3f4NpYGBMpPucVctpvzJAsCJYC2dhbGVpLraK") # Replace or set in env
15
- # GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY", "AIzaSyDuDPP0eWWA0UsGBBIeOI7Fl0WcPli4Sdo") # Replace or set in env
16
- #
17
- # if not PEXELS_API_KEY or not GOOGLE_API_KEY:
18
- # print("Warning: API keys not found. Please set PEXELS_API_KEY and GOOGLE_API_KEY environment variables.")
19
- #
20
- # # Initialize app and image searcher
21
- # app = FastAPI(title="Travel Recommendation API")
22
- # image_searcher = ImageSearcher(PEXELS_API_KEY)
23
- #
24
- # # CORS (Cross-Origin Resource Sharing) - Allow frontend access
25
- # app.add_middleware(
26
- # CORSMiddleware,
27
- # allow_origins=["*"], # Adjust in production
28
- # allow_credentials=True,
29
- # allow_methods=["*"],
30
- # allow_headers=["*"],
31
- # )
32
- #
33
- # @app.get("/", summary="Root endpoint for health check")
34
- # def read_root():
35
- # return {"message": "Travel Recommendation API is running!"}
36
- #
37
- # @app.post("/generate_plan", response_model=PlanResponse, summary="Generate a travel plan")
38
- # async def generate_plan_endpoint(travel_input: TravelDataInput):
39
- # travel_data = travel_input.model_dump() # Use model_dump() for Pydantic v2
40
- # source = "generated"
41
- # plan_text = None
42
- #
43
- # # 1. Try RAG first
44
- # try:
45
- # relevant_plan = get_relevant_plan(travel_data)
46
- # if relevant_plan:
47
- # plan_text = relevant_plan
48
- # source = "index"
49
- # except Exception as e:
50
- # print(f"RAG check failed (continuing with generation): {e}")
51
- #
52
- # # 2. If no RAG plan, generate with Gemini
53
- # if not plan_text:
54
- # try:
55
- # prompt = create_travel_plan_prompt(travel_data)
56
- # plan_text = generate_with_gemini(prompt)
57
- # source = "generated"
58
- # except Exception as e:
59
- # print(f"Gemini generation failed: {e}")
60
- # raise HTTPException(status_code=500, detail=f"Failed to generate plan: {e}")
61
- #
62
- # if not plan_text:
63
- # raise HTTPException(status_code=500, detail="Could not retrieve or generate a travel plan.")
64
- #
65
- # # 3. Extract destination & get images
66
- # try:
67
- # destination = extract_destination(plan_text, travel_data) or "Suggested Destination"
68
- # image_queries = create_image_queries(travel_data, destination)
69
- # images = image_searcher.search_all_sources(image_queries, num_images=6)
70
- # except Exception as e:
71
- # print(f"Image search failed: {e}")
72
- # images = [] # Return empty list if image search fails
73
- # image_queries = []
74
- #
75
- # return PlanResponse(
76
- # plan_text=plan_text,
77
- # destination_used=destination,
78
- # images=images,
79
- # image_queries_used=image_queries,
80
- # source=source
81
- # )
82
- #
83
- # @app.post("/chat", response_model=ChatResponse, summary="Chat about the travel plan")
84
- # async def chat_endpoint(chat_input: ChatInput):
85
- # try:
86
- # prompt = create_chat_prompt(
87
- # chat_input.plan_text,
88
- # chat_input.destination,
89
- # chat_input.num_days,
90
- # [msg.model_dump() for msg in chat_input.chat_history], # Convert Pydantic to dict
91
- # chat_input.user_input
92
- # )
93
- # response = generate_with_gemini(prompt, max_tokens=1024, temperature=0.5)
94
- # return ChatResponse(assistant_response=response)
95
- # except Exception as e:
96
- # print(f"Chat generation failed: {e}")
97
- # raise HTTPException(status_code=500, detail=f"Failed to get chat response: {e}")
98
- #
99
- # # To run locally: uvicorn main:app --reload
100
-
101
- # PEXELS_API_KEY = "LB4mRviLcvE72R2645m3f4NpYGBMpPucVctpvzJAsCJYC2dhbGVpLraK"
102
- # GOOGLE_API_KEY = "AIzaSyDuDPP0eWWA0UsGBBIeOI7Fl0WcPli4Sdo"
103
-
104
- import re
105
- import os
106
- import json
107
- from typing import List
108
- from fastapi import FastAPI, HTTPException
109
- from fastapi.middleware.cors import CORSMiddleware
110
- from pydantic import BaseModel
111
-
112
- from models import TravelDataInput, PlanResponse
113
- from image_searcher import ImageSearcher, create_image_queries, extract_destination
114
- from gemini_utils import create_travel_plan_prompt, generate_with_gemini
115
- from rag_utils import get_relevant_plan
116
-
117
- # API keys
118
- PEXELS_API_KEY = "LB4mRviLcvE72R2645m3f4NpYGBMpPucVctpvzJAsCJYC2dhbGVpLraK"
119
- GOOGLE_API_KEY = "AIzaSyDuDPP0eWWA0UsGBBIeOI7Fl0WcPli4Sdo"
120
-
121
- # App setup
122
- app = FastAPI(title="Travel Recommendation API")
123
- image_searcher = ImageSearcher(PEXELS_API_KEY)
124
-
125
- app.add_middleware(
126
- CORSMiddleware,
127
- allow_origins=["*"],
128
- allow_credentials=True,
129
- allow_methods=["*"],
130
- allow_headers=["*"],
131
- )
132
-
133
- @app.get("/", summary="Root endpoint for health check")
134
- def read_root():
135
- return {"message": "Travel Recommendation API is running!"}
136
-
137
- @app.post("/generate_plan", response_model=PlanResponse, summary="Generate a travel plan")
138
- async def generate_plan_endpoint(travel_input: TravelDataInput):
139
- travel_data = travel_input.model_dump()
140
- source = "generated"
141
- plan_text = None
142
-
143
- # Step 1: RAG
144
- try:
145
- relevant_plan = get_relevant_plan(travel_data)
146
- if relevant_plan:
147
- plan_text = relevant_plan
148
- source = "index"
149
- except Exception as e:
150
- print(f"RAG check failed: {e}")
151
-
152
- # Step 2: Generate if RAG fails
153
- if not plan_text:
154
- try:
155
- prompt = create_travel_plan_prompt(travel_data)
156
- plan_text = generate_with_gemini(prompt)
157
- except Exception as e:
158
- print(f"Gemini generation failed: {e}")
159
- raise HTTPException(status_code=500, detail=f"Failed to generate plan: {e}")
160
-
161
- if not plan_text:
162
- raise HTTPException(status_code=500, detail="Could not retrieve or generate a travel plan.")
163
-
164
- # Step 3: Get destination & images
165
- try:
166
- destination = extract_destination(plan_text, travel_data) or "Suggested Destination"
167
- image_queries = create_image_queries(travel_data, destination)
168
- images = image_searcher.search_all_sources(image_queries, num_images=6)
169
- except Exception as e:
170
- print(f"Image search failed: {e}")
171
- images = []
172
- image_queries = []
173
-
174
- return PlanResponse(
175
- plan_text=plan_text,
176
- destination_used=destination,
177
- images=images,
178
- image_queries_used=image_queries,
179
- source=source,
180
- )
181
-
182
- # ========== EXTRACTION ENDPOINT ==========
183
-
184
- class ExtractionInput(BaseModel):
185
- plan_text: str
186
-
187
- @app.post("/extract_package", summary="Extract structured package data from plan text")
188
- async def extract_package_endpoint(data: ExtractionInput):
189
- extraction_prompt = f"""
190
- Extract ONLY the following fields from the travel plan below and return STRICTLY in raw JSON format. No extra explanation, no markdown, no text.
191
-
192
- Required JSON format:
193
- {{
194
- "packageName": string,
195
- "packageDescription": string,
196
- "packageDestination": string,
197
- "packageDays": integer,
198
- "packageNights": integer,
199
- "packageAccommodation": string,
200
- "packageTransportation": string,
201
- "packageMeals": string,
202
- "packageActivities": string,
203
- "packagePrice": float,
204
- "packageDiscountPrice": float,
205
- "packageOffer": boolean,
206
- "packageRating": 0,
207
- "packageTotalRatings": 0
208
- }}
209
-
210
- TRAVEL PLAN:
211
- \"\"\"
212
- {data.plan_text}
213
- \"\"\"
214
- """
215
-
216
- try:
217
- raw_response = generate_with_gemini(extraction_prompt)
218
- print("Gemini raw response:", raw_response)
219
-
220
- # Extract the JSON body from the response
221
- json_match = re.search(r'\{.*\}', raw_response, re.DOTALL)
222
- if not json_match:
223
- raise ValueError("No JSON object found in Gemini response")
224
-
225
- json_str = json_match.group(0)
226
- structured_package = json.loads(json_str)
227
-
228
- except Exception as e:
229
- print("Gemini extraction failed:", e)
230
- print("Prompt was:\n", extraction_prompt)
231
- raise HTTPException(status_code=500, detail="Failed to extract structured package data.")
232
-
233
- return structured_package
 
1
+ from dotenv import load_dotenv
2
+ import re
3
+ import os
4
+ import json
5
+ from typing import List
6
+ from fastapi import FastAPI, HTTPException
7
+ from fastapi.middleware.cors import CORSMiddleware
8
+ from pydantic import BaseModel
9
+
10
+ from models import TravelDataInput, PlanResponse
11
+ from image_searcher import ImageSearcher, create_image_queries, extract_destination
12
+ from gemini_utils import create_travel_plan_prompt, generate_with_gemini
13
+ from rag_utils import get_relevant_plan
14
+
15
+
16
+ load_dotenv()
17
+ PEXELS_API_KEY = os.getenv("PEXELS_API_KEY")
18
+ GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
19
+ # App setup
20
+ app = FastAPI(title="Travel Recommendation API")
21
+ image_searcher = ImageSearcher(PEXELS_API_KEY)
22
+
23
+ app.add_middleware(
24
+ CORSMiddleware,
25
+ allow_origins=["*"],
26
+ allow_credentials=True,
27
+ allow_methods=["*"],
28
+ allow_headers=["*"],
29
+ )
30
+
31
+ @app.get("/", summary="Root endpoint for health check")
32
+ def read_root():
33
+ return {"message": "Travel Recommendation API is running!"}
34
+
35
+ @app.post("/generate_plan", response_model=PlanResponse, summary="Generate a travel plan")
36
+ async def generate_plan_endpoint(travel_input: TravelDataInput):
37
+ travel_data = travel_input.model_dump()
38
+ source = "generated"
39
+ plan_text = None
40
+
41
+ # Step 1: RAG
42
+ try:
43
+ relevant_plan = get_relevant_plan(travel_data)
44
+ if relevant_plan:
45
+ plan_text = relevant_plan
46
+ source = "index"
47
+ except Exception as e:
48
+ print(f"RAG check failed: {e}")
49
+
50
+ # Step 2: Generate if RAG fails
51
+ if not plan_text:
52
+ try:
53
+ prompt = create_travel_plan_prompt(travel_data)
54
+ plan_text = generate_with_gemini(prompt)
55
+ except Exception as e:
56
+ print(f"Gemini generation failed: {e}")
57
+ raise HTTPException(status_code=500, detail=f"Failed to generate plan: {e}")
58
+
59
+ if not plan_text:
60
+ raise HTTPException(status_code=500, detail="Could not retrieve or generate a travel plan.")
61
+
62
+ # Step 3: Get destination & images
63
+ try:
64
+ destination = extract_destination(plan_text, travel_data) or "Suggested Destination"
65
+ image_queries = create_image_queries(travel_data, destination)
66
+ images = image_searcher.search_all_sources(image_queries, num_images=6)
67
+ except Exception as e:
68
+ print(f"Image search failed: {e}")
69
+ images = []
70
+ image_queries = []
71
+
72
+ return PlanResponse(
73
+ plan_text=plan_text,
74
+ destination_used=destination,
75
+ images=images,
76
+ image_queries_used=image_queries,
77
+ source=source,
78
+ )
79
+
80
+ # ========== EXTRACTION ENDPOINT ==========
81
+
82
+ class ExtractionInput(BaseModel):
83
+ plan_text: str
84
+
85
+ @app.post("/extract_package", summary="Extract structured package data from plan text")
86
+ async def extract_package_endpoint(data: ExtractionInput):
87
+ extraction_prompt = f"""
88
+ Extract ONLY the following fields from the travel plan below and return STRICTLY in raw JSON format. No extra explanation, no markdown, no text.
89
+
90
+ Required JSON format:
91
+ {{
92
+ "packageName": string,
93
+ "packageDescription": string,
94
+ "packageDestination": string,
95
+ "packageDays": integer,
96
+ "packageNights": integer,
97
+ "packageAccommodation": string,
98
+ "packageTransportation": string,
99
+ "packageMeals": string,
100
+ "packageActivities": string,
101
+ "packagePrice": float,
102
+ "packageDiscountPrice": float,
103
+ "packageOffer": boolean,
104
+ "packageRating": 0,
105
+ "packageTotalRatings": 0
106
+ }}
107
+
108
+ TRAVEL PLAN:
109
+ \"\"\"
110
+ {data.plan_text}
111
+ \"\"\"
112
+ """
113
+
114
+ try:
115
+ raw_response = generate_with_gemini(extraction_prompt)
116
+ print("Gemini raw response:", raw_response)
117
+
118
+ # Extract the JSON body from the response
119
+ json_match = re.search(r'\{.*\}', raw_response, re.DOTALL)
120
+ if not json_match:
121
+ raise ValueError("No JSON object found in Gemini response")
122
+
123
+ json_str = json_match.group(0)
124
+ structured_package = json.loads(json_str)
125
+
126
+ except Exception as e:
127
+ print("Gemini extraction failed:", e)
128
+ print("Prompt was:\n", extraction_prompt)
129
+ raise HTTPException(status_code=500, detail="Failed to extract structured package data.")
130
+
131
+ return structured_package