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( '''
🌦️ SkyMind WeatherAI 🌤️
Intelligent Real-time Weather Updates Forecast Assistant 🌍
''' ) 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())