Spaces:
Sleeping
Sleeping
File size: 13,164 Bytes
1109b1e 6b8b942 1109b1e dcbbbea 1109b1e 43f6120 7a2d50a 1109b1e c95f62f 1109b1e 6b8b942 1109b1e c95f62f 1109b1e dcbbbea 1109b1e f576150 dcbbbea 99ca88e 1109b1e c95f62f 1109b1e 72ad95a 1109b1e dcbbbea 1109b1e 528d02a 1109b1e 528d02a 1109b1e 7ad0c80 528d02a 1109b1e dcbbbea 1109b1e 43f6120 72ad95a 43f6120 72ad95a 43f6120 72ad95a 43f6120 72ad95a 43f6120 72ad95a 43f6120 72ad95a 43f6120 72ad95a 43f6120 72ad95a 43f6120 1109b1e 43f6120 1109b1e 43f6120 1109b1e 528d02a 43f6120 1109b1e 528d02a 1109b1e 43f6120 1109b1e 43f6120 7a2d50a 43f6120 ba3a178 1109b1e 7a2d50a 01c00a1 7a2d50a 1109b1e 7a2d50a 1109b1e 7a2d50a 1109b1e b9d0416 528d02a ceb3e78 528d02a b9d0416 7a2d50a 1109b1e 528d02a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
import os
import gradio as gr
from dotenv import load_dotenv
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.tools import tool
from langchain.pydantic_v1 import BaseModel, Field
import requests
from datetime import datetime
from typing import List
from langchain.tools import Tool
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import PydanticOutputParser
from langchain.memory import ConversationBufferMemory
from langchain.agents import AgentExecutor, create_tool_calling_agent
import uuid
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
import gradio as gr
import base64
load_dotenv(dotenv_path='api.env.txt')
Langchain_API_KEY = os.getenv('LANGCHAIN_API')
GOOGLE_API_KEY = os.getenv('GOOGLE_API')
WEATHER_API_KEY = os.getenv('WEATHER_API')
LOCATION_API_KEY = os.getenv('LOCATION_API')
os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY
llm = ChatGoogleGenerativeAI(
model="gemini-1.5-flash",
temperature=0,
max_tokens=None,
timeout=None,
max_retries=2,
)
def get_location_from_ip():
"""Get the location of the user based on their IP address."""
response = requests.get(f"https://api.geoapify.com/v1/ipinfo?apiKey={LOCATION_API_KEY}").json()
return response
class WeatherInput(BaseModel):
city: str = Field(default=None, description="The city to get the weather for.")
@tool("get_weather_by_location", args_schema=WeatherInput, return_direct=True)
def get_weather_by_location(city: str = None):
"""Get the weather based on the user's location if no city is specified."""
if (city == '') or (city == None) or (not city):
location = get_location_from_ip()
city = location['city']['name']
url = f"https://api.tomorrow.io/v4/timelines?apikey={WEATHER_API_KEY}"
payload = {
"location": city,
"fields": ["temperature", "humidity", "windSpeed"],
"units": "metric",
"timesteps": ["1d"],
"startTime": "now",
"endTime": "nowPlus5d",
"timezone": "auto"
}
headers = {
"accept": "application/json",
"content-type": "application/json"
}
response = requests.post(url, json=payload, headers=headers).json()
return format_weather_response(response, city)
def format_weather_response(weather_data, city):
"""Format the weather data into a readable string."""
intervals = weather_data['data']['timelines'][0]['intervals']
response = f"Weather forecast for {city}:\n\n"
for interval in intervals:
date = datetime.fromisoformat(interval['startTime']).strftime("%A, %B %d")
temp = round(interval['values']['temperature'], 1)
humidity = round(interval['values']['humidity'], 1)
wind_speed = round(interval['values']['windSpeed'], 1)
response += f"{date}:\n"
response += f" Temperature: {temp}°C\n"
response += f" Humidity: {humidity}%\n"
response += f" Wind Speed: {wind_speed * 3.6:.1f} km/h\n\n"
return response
get_weather_tool = Tool(
name="get_weather_by_location",
func=get_weather_by_location,
description="Get the current weather for a specific location. If no location is provided, it will return the weather for the current location."
)
class DailyWeather(BaseModel):
date: str
temperature: float
condition: str
humidity: float
wind_speed: float
advice: str
class WeatherOutput(BaseModel):
location: str = Field(description="The location or the city for which the weather is reported")
forecast: List[DailyWeather] = Field(description="The weather forecast for multiple days")
parser = PydanticOutputParser(pydantic_object=WeatherOutput)
prompt = ChatPromptTemplate.from_messages([
("system", """You are WeatherWise, a highly knowledgeable, friendly, and efficient weather assistant. Your primary mission is to provide comprehensive and accurate weather information for cities worldwide, while offering personalized advice tailored to the weather conditions. Approach each interaction with warmth and enthusiasm, as if you're chatting with a good friend about their day. Follow these detailed instructions:
1. **Warm Welcome**: Begin each conversation with a friendly greeting, mentioning the current time of day (e.g., "Good morning!" or "Good evening!") to add a personal touch.
2. **City-Specific Requests**:
- When a user mentions a specific city, immediately use the get_weather_by_location tool to fetch weather data for today and the next few days.
- Always include the city's name in your response for clarity, and express enthusiasm about the location (e.g., "Ah, lovely Paris! Let's see what the weather has in store for the City of Light.").
3. **Current Location Assumption**:
- If a user asks about the weather without mentioning a city (e.g., "What's the weather like today?"), assume they're asking about their current location and take action: Use the get_weather_by_location tool with an empty string.
- Use the get_weather_by_location tool with an empty string as input to retrieve local weather information.
If a user asks about the weather without mentioning a specific city, assume they're asking about their current location. This applies to various phrasings such as:
"What's the weather like today?"
"How's the weather?"
"Will it rain this week?"
"Should I bring a jacket?"
"Is it sunny outside?"
"What's the temperature right now?"
"Any chance of snow soon?"
"Will it be windy later?"
"What's the forecast for the weekend?"
"Is it a good day for outdoor activities?"
In all these cases, use the get_weather_by_location tool with an empty string as input to retrieve local weather information based on the user's current location.
4. **Data Presentation**:
- Use the format_weather tool to present information in a clear, concise, and visually appealing format.
- Include essential details such as temperature (in both Celsius and Fahrenheit), precipitation chance, humidity, wind speed and direction, and overall weather conditions.
- For multi-day forecasts, present a brief overview followed by day-by-day breakdowns.
5. **Personalized Advice**:
Offer tailored, friendly advice based on the weather conditions for each day:
- **Sunny**: "It's a beautiful day! Perfect for a picnic in the park or exploring the city. Don't forget your sunscreen and shades!"
- **Rainy**: "Looks like a cozy day indoors or a chance to splash in puddles! Keep an umbrella handy and maybe curl up with a good book later."
- **Cold**: "Brr! Time to bundle up in your favorite warm layers. How about making some hot cocoa and enjoying the crisp air on a short walk?"
- **Hot**: "Whew, it's a scorcher! Stay cool with light, breathable clothing and plenty of water. Maybe treat yourself to some ice cream?"
6. **Clarifications**:
If the user's request is ambiguous, ask for clarification in a friendly manner:
- "I'd love to help! Could you please specify which city you're curious about?"
- "Just to make sure I give you the most accurate info, which day of the week are you most interested in?"
7. **Avoid Repetition**:
- Keep track of the conversation history to provide context-aware responses.
- If repeating information, frame it as a helpful reminder (e.g., "As I mentioned earlier, but it's worth repeating because it's important...").
8. **Handling Follow-ups**:
- Anticipate potential follow-up questions and offer to provide more details proactively.
- For example: "I've given you an overview, but if you'd like more details about a specific day or any particular weather aspect, just ask!"
9. **Friendly and Informative Tone**:
- Use a conversational, upbeat tone as if chatting with a friend.
- Incorporate weather-related expressions or puns to add a touch of humor when appropriate.
- Show empathy for less-than-ideal weather conditions (e.g., "I know rainy days can be a bummer, but think of how happy the plants are!").
10. **Local Insights**:
- When possible, offer brief, relevant insights about the location in relation to the weather (e.g., "Did you know Paris is actually quite lovely in the rain? It's when the city truly earns its nickname 'City of Light' with all the reflections!").
11. **Closing**:
- End each interaction on a positive note, offering to help with any other weather-related questions.
- Wish the user well based on the forecast (e.g., "Enjoy the sunshine!" or "Stay dry out there!").
Always prioritize accuracy and clarity while maintaining a warm, friendly demeanor. Your goal is to make talking about the weather as enjoyable and helpful as possible!"""),
("human", "{input}"),
("ai", "Good day! I'm WeatherWise, your friendly neighborhood weather expert. I'm excited to help you plan your days with pinpoint weather forecasts and some cheerful advice to boot. What would you like to know about the weather? Whether it's for your location or anywhere around the globe, I'm all ears!"),
("human", "{input}"),
("ai", "Absolutely! I'm thrilled to help you with that. Let me fetch the latest weather information and whip up some tailored advice just for you. Give me just a moment while I consult my meteorological crystal ball!"),
("placeholder", "{agent_scratchpad}"),
])
tools = [get_weather_tool]
message_history = ChatMessageHistory()
agent = create_tool_calling_agent(llm, tools, prompt=prompt)
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
output_parser=parser
)
agent_with_chat_history = RunnableWithMessageHistory(
agent_executor,
lambda session_id: message_history,
input_messages_key="input",
history_messages_key="chat_history",
)
session_ids = {}
def gradio_interface(user_input, session_id):
if session_id not in session_ids:
new_session_id = str(uuid.uuid4())
session_ids[session_id] = new_session_id
else:
new_session_id = session_ids[session_id]
result = agent_with_chat_history.invoke(
{"input": user_input},
config={"configurable": {"session_id": new_session_id}}
)
return [[user_input, result['output']]]
def encode_image(image_path):
with open(image_path, "rb") as image_file:
return base64.b64encode(image_file.read()).decode('utf-8')
# Encode the image
image_path = "productmanagerinterview_logo.jpeg"
encoded_image = encode_image(image_path)
info_text = f"""
<div style="display: flex; align-items: flex-start;">
<img src="data:image/jpeg;base64,{encoded_image}" alt="Logo" style="width: 200px; height: 200px; object-fit: cover; margin-right: 20px;">
<div>
<h2>Product Manager Accelerator Program</h2>
<p>The Product Manager Accelerator Program is designed to support PM professionals through every stage of their career. From students looking for entry-level jobs to Directors looking to take on a leadership role, our program has helped over hundreds of students fulfill their career aspirations.</p>
<p>Our Product Manager Accelerator community are ambitious and committed. Through our program they have learnt, honed and developed new PM and leadership skills, giving them a strong foundation for their future endeavours.</p>
<p>Learn product management for free today on our <a href="https://www.youtube.com/c/drnancyli?sub_confirmation=1" target="_blank">YouTube channel</a></p>
<h3>Interested in PM Accelerator Pro?</h3>
<ol>
<li>Attend the <a href="https://www.drnancyli.com/masterclass" target="_blank">Product Masterclass</a> to learn more about the program details, price, different packages, and stay until the end to get FREE AI Course. Learn how to create a killer product portfolio in two weeks that will help you land any PM job (traditional or AI) even if you were laid off or have zero PM experience.</li>
<li>Reserve your early bird ticket and submit an application to talk to our Head of Admission</li>
<li>Successful applicants join our PMA Pro community to receive customized coaching!</li>
</ol>
</div>
</div>
"""
with gr.Blocks() as demo:
gr.Markdown("# Weather Assistant - Done By Mohamed Boghdady")
chatbot = gr.Chatbot()
with gr.Row():
txt = gr.Textbox(
show_label=False,
placeholder="Ask about the weather in any city...",
lines=1,
container=False
)
submit_btn = gr.Button("Submit")
session_id_box = gr.Textbox(visible=False, value=str(uuid.uuid4()))
# Add info button
info_btn = gr.Button("Info")
info_box = gr.HTML(visible=False, value=info_text)
# Set up event handlers
submit_btn.click(gradio_interface, inputs=[txt, session_id_box], outputs=chatbot)
txt.submit(gradio_interface, inputs=[txt, session_id_box], outputs=chatbot)
info_btn.click(lambda: gr.update(visible=True), outputs=info_box)
demo.launch(share=True) |