gisam commited on
Commit
4bf2ffa
·
1 Parent(s): 929b0ec

added travel assistant app

Browse files
.vscode/launch.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Solara: Launch",
6
+ "type": "python",
7
+ "request": "launch",
8
+ "program": "C:/Users/Sam/.conda/envs/solara/Scripts/solara.exe",
9
+ "args": [
10
+ "run",
11
+ "C:/Users/Sam/Projects/solara-projects/pages/02_openAI.py"
12
+ ],
13
+ "console": "integratedTerminal",
14
+ "justMyCode": true,
15
+ "env": {
16
+ "PYTHONNOUSERSITE": "True"
17
+ }
18
+ }
19
+ ]
20
+ }
pages/.vscode/launch.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Solara: Launch",
6
+ "type": "python",
7
+ "request": "launch",
8
+ "program": "C:/Users/Sam/.conda/envs/solara/Scripts/solara.exe",
9
+ "args": [
10
+ "run",
11
+ "C:/Users/Sam/Projects/solara-projects/pages/02_openAI.py"
12
+ ],
13
+ "console": "integratedTerminal",
14
+ "justMyCode": true,
15
+ "env": {
16
+ "PYTHONNOUSERSITE": "True"
17
+ }
18
+ }
19
+ ]
20
+ }
pages/01_leafmap.py DELETED
@@ -1,33 +0,0 @@
1
- import leafmap
2
- import solara
3
-
4
- zoom = solara.reactive(2)
5
- center = solara.reactive((20, 0))
6
-
7
-
8
- class Map(leafmap.Map):
9
- def __init__(self, **kwargs):
10
- super().__init__(**kwargs)
11
- # Add what you want below
12
-
13
-
14
-
15
- @solara.component
16
- def Page():
17
- with solara.Column(style={"min-width": "500px"}):
18
- # solara components support reactive variables
19
- # solara.SliderInt(label="Zoom level", value=zoom, min=1, max=20)
20
- # using 3rd party widget library require wiring up the events manually
21
- # using zoom.value and zoom.set
22
- Map.element( # type: ignore
23
- zoom=zoom.value,
24
- on_zoom=zoom.set,
25
- center=center.value,
26
- on_center=center.set,
27
- scroll_wheel_zoom=True,
28
- toolbar_ctrl=False,
29
- data_ctrl=False,
30
- height="780px",
31
- )
32
- # solara.Text(f"Zoom: {zoom.value}")
33
- # solara.Text(f"Center: {center.value}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/01_openAI.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ from typing import List, Dict, Any
4
+ import leafmap
5
+ import solara
6
+ import solara.lab
7
+ from solara.website.utils import apidoc
8
+ from ipyleaflet import Marker, Icon
9
+ import openai
10
+ f#rom dotenv import load_dotenv
11
+
12
+ # Load environment variables
13
+ #load_dotenv()
14
+
15
+ # Initialize OpenAI client
16
+ client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
17
+
18
+ # Function to get response from OpenAI API
19
+ def get_bot_response(user_message: str) -> str:
20
+ max_retries = 5
21
+ for attempt in range(max_retries):
22
+ try:
23
+ print(f"Sending message to assistant: {user_message}") # Debug print
24
+
25
+ # Create a new thread
26
+ thread = client.beta.threads.create()
27
+ print(f"Thread created: {thread.id}") # Debug print
28
+
29
+ # Add the user's message to the thread
30
+ client.beta.threads.messages.create(
31
+ thread_id=thread.id, role="user", content=user_message
32
+ )
33
+
34
+ # Create a run for the assistant to process the thread
35
+ run = client.beta.threads.runs.create(
36
+ thread_id=thread.id,
37
+ assistant_id="asst_T72b3iw4R9d74NEZ2MvvdSY8",
38
+ )
39
+ print(f"Run created: {run.id}") # Debug print
40
+
41
+ # Poll for completion with a timeout
42
+ start_time = time.time()
43
+ while True:
44
+ run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
45
+ if run.status == "completed":
46
+ print("Run completed") # Debug print
47
+ break
48
+ elif run.status == "failed":
49
+ print("Run failed") # Debug print
50
+ return "Sorry, I couldn't process the request. Please try again later."
51
+ elif time.time() - start_time > 60: # Timeout after 60 seconds
52
+ print("Run timeout") # Debug print
53
+ return "Sorry, the request timed out. Please try again later."
54
+ time.sleep(1) # Add a delay to avoid hitting the rate limit
55
+
56
+ # Retrieve messages in the thread
57
+ messages = client.beta.threads.messages.list(thread_id=thread.id)
58
+ print(f"Messages retrieved: {len(messages.data)}") # Debug print
59
+
60
+ # Find the most recent assistant response
61
+ for msg in reversed(messages.data):
62
+ if msg.role == "assistant":
63
+ if msg.content:
64
+ content = msg.content[0]
65
+ print(f"Assistant response content: {content}") # Debug print
66
+ if hasattr(content, 'text'):
67
+ return content.text.value.strip()
68
+ elif hasattr(content, 'value'):
69
+ return content.value.strip()
70
+
71
+ return "Sorry, I couldn't fetch a response. Please try again later."
72
+ except Exception as e:
73
+ print(f"Failed to get response from OpenAI: {str(e)}")
74
+ return "Sorry, I couldn't fetch a response. Please try again later."
75
+
76
+ # Function to get location info using the assistant
77
+ def get_location_info(lat: float, lon: float) -> str:
78
+ user_message = (
79
+ f"Provide interesting facts, historical details, cultural insights, popular attractions, and travel advice "
80
+ f"for the location at latitude {lat} and longitude {lon}."
81
+ )
82
+ print(f"Generated user message: {user_message}") # Debug print
83
+ return get_bot_response(user_message)
84
+
85
+ # Function to handle map clicks
86
+ def handle_map_click(**kwargs):
87
+ latlon = kwargs.get('coordinates')
88
+ if kwargs.get('type') == 'click' and latlon:
89
+ print(f"Coordinates received: {latlon}") # Debug print
90
+ clicked_coordinates.set((latlon[0], latlon[1]))
91
+
92
+ # Set "thinking" message in the chatbox
93
+ messages.value = [{"role": "assistant", "content": "Thinking... please wait."}]
94
+
95
+ # Get the actual response
96
+ info = get_location_info(latlon[0], latlon[1])
97
+ print(f"Assistant response: {info}") # Debug print
98
+
99
+ # Update the chatbox with the actual response
100
+ messages.value = [{"role": "assistant", "content": info}]
101
+
102
+ # Clear existing markers and add a new one for the most recent click
103
+ for layer in kwargs['map_instance'].layers:
104
+ if isinstance(layer, Marker):
105
+ kwargs['map_instance'].remove_layer(layer)
106
+
107
+ marker = Marker(location=[latlon[0], latlon[1]], draggable=False)
108
+ kwargs['map_instance'].add_layer(marker)
109
+
110
+ # Custom Map class
111
+ class Map(leafmap.Map):
112
+ def __init__(self, **kwargs):
113
+ super().__init__(**kwargs)
114
+ self.on_interaction(lambda **kwargs: handle_map_click(map_instance=self, **kwargs))
115
+ self.fit_bounds([[49.674, -14.015], [61.061, 2.091]])
116
+ self.min_zoom = 3
117
+
118
+ # Reactive variables
119
+ zoom = solara.reactive(3)
120
+ center = solara.reactive((0, 0))
121
+ messages = solara.reactive([{"role": "assistant", "content": "Welcome! Click on the map to get travel advice and interesting facts about the location."}]) # This will hold our chat messages
122
+ clicked_coordinates = solara.reactive((0, 0)) # This will hold the latest clicked coordinates
123
+
124
+ # Main Page component
125
+ @solara.component
126
+ def Page():
127
+ with solara.Row(style={"gap": "20px", "padding": "20px"}):
128
+ # Map View Column
129
+ with solara.Column(style={"flex": "2"}):
130
+ with solara.Card( margin=0, style={"padding": "10px", "box-shadow": "0 4px 8px rgba(0,0,0,0.1)"}):
131
+ Map.element(
132
+ zoom=zoom.value,
133
+ on_zoom=zoom.set,
134
+ center=center.value,
135
+ on_center=center.set,
136
+ scroll_wheel_zoom=True,
137
+ toolbar_ctrl=False,
138
+ draw_control=False,
139
+ data_ctrl=False,
140
+ height="680px",
141
+ )
142
+ solara.Markdown(f"Zoom: {zoom.value} Center: {center.value} Clicked Coordinates: {clicked_coordinates.value}")
143
+
144
+ # Chat Box Column
145
+ with solara.Column(style={"flex": "1"}):
146
+ with solara.Card(style={"padding": "10px", "box-shadow": "0 4px 8px rgba(0,0,0,0.1)"}):
147
+ with solara.lab.ChatBox():
148
+ for item in messages.value[-1:]:
149
+ with solara.lab.ChatMessage(
150
+ user=item["role"] == "user",
151
+ name="Travel Assistant" if item["role"] == "assistant" else "User",
152
+ style={"background-color": "#f4f4f8", "border-radius": "10px", "padding": "10px", "margin-bottom": "10px"}
153
+ ):
154
+ solara.Markdown(item["content"])
155
+
156
+ # Render the Page component
157
+ Page()
requirements.txt CHANGED
@@ -1,4 +1,8 @@
1
  leafmap
2
  solara
3
  geopandas
4
- pydantic< 2.0
 
 
 
 
 
1
  leafmap
2
  solara
3
  geopandas
4
+ pydantic< 2.0
5
+ openai
6
+ dotenv
7
+ transformers
8
+ ipyleaflet