Spaces:
Sleeping
Sleeping
File size: 5,989 Bytes
0a724f2 a6588d7 91df2eb 0a724f2 a6588d7 0a724f2 618eca1 0a724f2 81807f2 0a724f2 81807f2 0a724f2 09673f2 0a724f2 623e0e1 | 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 | import os
import json
import requests
import gradio as gr
from openai import OpenAI
# Load API keys from Hugging Face Secrets
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
WEATHER_API_KEY = os.environ["WEATHER_API_KEY"]
client = OpenAI(api_key=OPENAI_API_KEY)
# Weather Function
def get_current_weather(location, unit='celsius'):
url = (
f"http://api.openweathermap.org/data/2.5/weather"
f"?q={location}"
f"&appid={WEATHER_API_KEY}"
f"&units=metric"
)
response = requests.get(url)
data = response.json()
if response.status_code != 200:
return {"error": data.get("message", "Weather data unavailable")}
return {
"location": location,
"temperature": data["main"]["temp"],
"humidity": data["main"]["humidity"],
"weather": data["weather"][0]["description"]
}
# Chat logic
def weather_chat(user_message):
try:
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get current weather information for a city",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
},
"required": ["location"]
}
}
}
]
messages = [
{
"role": "system",
"content": """
You are a professional weather bot/assistant.
Rules:
- Answer weather-related questions.
- Use Celsius and Fahrenheit only.
- If the question is unrelated to weather, politely decline.
"""
},
{"role": "user", "content": user_message}
]
response = client.chat.completions.create(
model="gpt-5-nano",
messages=messages,
tools=tools
)
assistant_message = response.choices[0].message
if assistant_message.tool_calls:
tool_call = assistant_message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
weather_data = get_current_weather(args["location"])
messages.append(assistant_message)
messages.append(
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(weather_data)
}
)
final_response = client.chat.completions.create(
model="gpt-5-nano",
messages=messages
)
return final_response.choices[0].message.content
else:
return assistant_message.content
except Exception:
return "Hello! I'm here to provide weather updates only. Please ask me questions related to weather."
# -----------------------------
# Custom Modern Theme + CSS
# -----------------------------
custom_css = """
body {
background: linear-gradient(135deg, #0f172a, #1e293b);
}
.gradio-container {
font-family: 'Poppins', sans-serif;
}
.main-title {
text-align: center;
font-size: 52px;
font-weight: 900;
margin-bottom: 15px;
background: linear-gradient(
90deg,
#ff6b6b,
#feca57,
#48dbfb,
#1dd1a1,
#5f27cd,
#ff9ff3
);
background-size: 400% 400%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradientMove 8s ease infinite;
}
@keyframes gradientMove {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
.sub-title {
text-align: center;
color: #91AC80;
font-size: 18px;
margin-bottom: 25px;
}
.weather-box {
border-radius: 20px;
padding: 20px;
background: rgba(255,255,255,0.08);
backdrop-filter: blur(10px);
box-shadow: 0px 8px 32px rgba(0,0,0,0.3);
}
footer {
visibility: hidden;
}
"""
def respond(message, chat_history):
if not message:
return "", history
response = weather_chat(message)
history.append({"role": "user", "content": message})
history.append({"role": "assistant", "content": response})
return "", history
with gr.Blocks() as demo:
gr.HTML(
'''
<div class="main-title">π¦οΈ SkyMind WeatherAI π€οΈ</div>
<div class="sub-title">Intelligent Real-time Weather Updates Forecast Assistant π</div>
'''
)
with gr.Column(elem_classes="weather-card"):
chatbot = gr.Chatbot(
#type="messages",
height=500,
#bubble_full_width=False,
avatar_images=(None, "https://cdn-icons-png.flaticon.com/512/1779/1779940.png"),
allow_tags=False
)
msg = gr.Textbox(
placeholder="Ask weather like: Weather in Dubai, Mumbai, Shanghai?...",
lines=1,
show_label=False
)
with gr.Row():
submit_btn = gr.Button("π Get Weather", variant="primary")
copy_btn = gr.Button("π Copy Answer")
copy_js = """
function copyToClipboard() {
const messages = document.querySelectorAll('.message.bot');
if (messages.length > 0) {
const latestMessage = messages[messages.length - 1].innerText;
navigator.clipboard.writeText(latestMessage);
alert("β
Weather response copied!");
}
}
"""
msg.submit(respond, [msg, chatbot], [msg, chatbot])
submit_btn.click(respond, [msg, chatbot], [msg, chatbot])
copy_btn.click(None, None, None, js=copy_js)
demo.launch(share=True, css=custom_css, theme=gr.themes.Soft())
|