jteng2127 commited on
Commit
12d1ae3
Β·
1 Parent(s): 094c1d3
Files changed (3) hide show
  1. app.py +34 -57
  2. gemini_api.py +168 -0
  3. pdf_convert.py +17 -0
app.py CHANGED
@@ -1,63 +1,40 @@
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
 
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
8
-
9
-
10
- def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
19
-
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
-
26
- messages.append({"role": "user", "content": message})
27
-
28
- response = ""
29
-
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
60
- )
61
 
62
 
63
  if __name__ == "__main__":
 
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
 
4
+ from gemini_api import get_travel_info, get_travel_recommendations
5
+ from pdf_convert import markdown_to_pdf_weasyprint
6
+
7
+ def generate_response(input_text):
8
+ user_query = input_text.strip()
9
+ if not user_query:
10
+ print("Please enter a valid travel query!")
11
+ return
12
+
13
+ travel_info = get_travel_info(user_query)
14
+
15
+ if travel_info and travel_info.get("location"):
16
+ travel_recommendations = get_travel_recommendations(
17
+ travel_info.get("intent"),
18
+ travel_info.get("location"),
19
+ travel_info.get("departure_date"),
20
+ travel_info.get("duration"),
21
+ travel_info.get("budget"),
22
+ travel_info.get("num_people"),
23
+ )
24
+ pdf = markdown_to_pdf_weasyprint(travel_recommendations)
25
+ else:
26
+ print("Could not extract travel information. Please refine your query.")
27
+
28
+ return pdf
29
+
30
+ with gr.Blocks() as demo:
31
+ gr.Markdown("## PDF Processing with Gemini API")
32
+ message = "I want to go to Taipei with 6 people, we have three thousand USD for 5 days. we plan we depart at February 2nd"
33
+ input_text = gr.Textbox(label="User Request", value=message, placeholder="Enter your travel detail here")
34
+ output_pdf = gr.File(label="Download Output PDF")
35
+ submit = gr.Button("Generate")
36
+
37
+ submit.click(fn=generate_response, inputs=input_text, outputs=output_pdf)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
 
40
  if __name__ == "__main__":
gemini_api.py ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import google.generativeai as genai
2
+ import re
3
+ import json
4
+ import os
5
+
6
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
7
+
8
+ genai.configure(api_key=GEMINI_API_KEY)
9
+
10
+ # model = genai.GenerativeModel('gemini-1.5-pro') # Or 'gemini-pro'
11
+ model = genai.GenerativeModel('gemini-2.0-flash')
12
+
13
+ def get_travel_info(user_input):
14
+ """Uses Gemini AI to extract travel intent and location from user input."""
15
+
16
+ prompt = f"""
17
+ You are a travel assistant. Your job is to extract the travel intent, location, and departure date from a user's query.
18
+ The intent can be anything from planning a trip to finding a hotel to suggesting a restaurant.
19
+ The location is the destination of the travel.
20
+ If the location is not specified, return None.
21
+ If the intent is not related to travel, return the intent and location in JSON format ONLY, like this:
22
+ If either the intent, the location, the departure_date, duration, budget, or num_people is not found, return null for that field.
23
+
24
+ ```json
25
+ {{
26
+ "intent": "the extracted intent",
27
+ "location": "the extracted location",
28
+ "departure_date": "the extracted departure date",
29
+ "duration": "the extracted duration",
30
+ "budget": "the extracted budget",
31
+ "num_people": "the extracted number of people"
32
+ }}
33
+ ```
34
+
35
+ User Query: I want to plan a trip to Paris for 5 days with a budget of $2000 for 2 people, leaving on March 15th.
36
+ ```json
37
+ {{
38
+ "intent": "plan a trip",
39
+ "location": "Paris",
40
+ "departure_date": "March 15th",
41
+ "duration": "5 days",
42
+ "budget": "$2000",
43
+ "num_people": "2"
44
+ }}
45
+ ```
46
+
47
+ User Query: Find a hotel in New York City for 3 nights with a budget of $1500 for 1 person, leaving on April 10th.
48
+ ```json
49
+ {{
50
+ "intent": "Find a hotel",
51
+ "location": "New York City",
52
+ "departure_date": "April 10th",
53
+ "duration": "3 nights",
54
+ "budget": "$1500",
55
+ "num_people": "1"
56
+ }}
57
+ ```
58
+
59
+ User Query: What is the weather like today?
60
+ ```json
61
+ {{
62
+ "intent": null,
63
+ "location": null,
64
+ "departure_date": null,
65
+ "duration": null,
66
+ "budget": null,
67
+ "num_people": null
68
+ }}
69
+ ```
70
+
71
+ User Query: {user_input}
72
+ """
73
+
74
+ response = model.generate_content(prompt)
75
+ response_text = response.text
76
+ # print(f"Raw Gemini Response: {response_text}") # Debugging
77
+
78
+ try:
79
+ # Use regular expression to find the JSON string within the response
80
+ match = re.search(r"\{.*?\}", response_text, re.DOTALL)
81
+ if match:
82
+ json_string = match.group(0).strip()
83
+ data = json.loads(json_string)
84
+ intent = data.get("intent")
85
+ location = data.get("location")
86
+ departure_date = data.get("departure_date")
87
+ duration = data.get("duration")
88
+ budget = data.get("budget")
89
+ num_people = data.get("num_people")
90
+ return {
91
+ "intent": intent,
92
+ "location": location,
93
+ "departure_date": departure_date,
94
+ "duration": duration,
95
+ "budget": budget,
96
+ "num_people": num_people
97
+ }
98
+ else:
99
+ print("Error: No JSON found in Gemini response.")
100
+ return None
101
+
102
+ except json.JSONDecodeError:
103
+ print("Error: Could not decode JSON after extraction.")
104
+ return None
105
+ except Exception as e:
106
+ print(f"An unexpected error occurred: {e}")
107
+ return None
108
+
109
+ def get_travel_recommendations(intent, location, departure_date, duration, budget, num_people):
110
+ """Uses Gemini AI to provide travel recommendations based on intent and location."""
111
+
112
+ prompt = f"""
113
+ You are a travel assistant. Based on the given intent, location, duration, budget, and number of people, provide helpful travel recommendations in Markdown format.
114
+ Attractions should provide at least 10 recommendations.
115
+ Accommodations should provide at least 5 recommendations.
116
+ Activities should provide at least 10 recommendations.
117
+ Food should provide at least 10 recommendations.
118
+ Keep in mind the budget and the number of people when suggesting accommodations and activities.
119
+
120
+ Intent: {intent}
121
+ Location: {location}
122
+ Departure Date: {departure_date}
123
+ Duration: {duration}
124
+ Budget: {budget}
125
+ Number of people: {num_people}
126
+
127
+ Your response should look like this:
128
+
129
+ # 🌍 Travel Guide: {location}
130
+
131
+ ## 🌀️ Weather:
132
+ - Weather 1
133
+
134
+ ## ✈️ Flight:
135
+ - Flight 1
136
+ - Flight 2
137
+
138
+ ## 🏨 Accommodations:
139
+ - Hotel 1
140
+ - Hotel 2
141
+
142
+ ## πŸ’³ Mobile Payment:
143
+ - Mobile Payment 1
144
+ - Mobile Payment 2
145
+
146
+ ## πŸš— Local Transportations:
147
+ - Local Transportations 1
148
+ - Local Transportations 2
149
+
150
+ ## 🏰 Attractions:
151
+ - Attraction 1
152
+ - Attraction 2
153
+
154
+ ## πŸš€ Activities:
155
+ - Activity 1
156
+ - Activity 2
157
+
158
+ ## 🍽️ Foods:
159
+ - Foods 1
160
+ - Foods 2
161
+
162
+ ## πŸ’‘ Tips for Planning:
163
+ - Tips for Planning 1
164
+ - Tips for Planning 2
165
+ """
166
+
167
+ response = model.generate_content(prompt)
168
+ return response.text
pdf_convert.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import markdown
2
+ from weasyprint import HTML, CSS
3
+
4
+ def markdown_to_pdf_weasyprint(md_content, output_pdf="travel_guide.pdf"):
5
+ html_content = markdown.markdown(md_content)
6
+ css = CSS(string="""
7
+ @font-face {
8
+ font-family: 'Noto Color Emoji';
9
+ src: local('Noto Color Emoji'), url(https://github.com/googlefonts/noto-emoji/blob/main/fonts/NotoColorEmoji.ttf?raw=true) format('truetype');
10
+ }
11
+ body {
12
+ font-family: 'Noto Color Emoji', sans-serif;
13
+ font-size: 14px;
14
+ }
15
+ """)
16
+ HTML(string=html_content).write_pdf(output_pdf, stylesheets=[css])
17
+ return output_pdf