Back to Tutorials
Python

Weather App with Tkinter GUI & API

Build a desktop weather app with a graphical interface - enter any city and get real-time temperature, humidity, and weather conditions using a free API.

~40 mins Intermediate Python 3 Tkinter GUI
Skills & Concepts You'll Gain
Tech Used: Python 3, Tkinter (built-in), requests library, OpenWeatherMap API (free)
Requirements
  • Python 3 installed
  • Internet connection
  • Free OpenWeatherMap account
  • VS Code or any editor
Libraries to Install
  • requests (pip install)
  • tkinter (built-in with Python)
Step 1

Get Your Free API Key

This app uses the OpenWeatherMap API to fetch real weather data. You need a free API key:

  1. Go to openweathermap.org and click Sign Up
  2. Create a free account and verify your email
  3. Go to My Profile → API Keys
  4. Copy your Default API Key - it looks like: a1b2c3d4e5f6g7h8i9j0...
  5. Wait 10–15 minutes after signing up before the key becomes active
If you get Error 401 when running the app, your API key is not yet activated. Wait 15 minutes and try again. This is normal for new accounts.
Step 2

Install the requests Library

Tkinter is already built into Python, but we need to install requests:

CMD / Terminal
pip install requests

Create a new file called weather_app.py in a folder of your choice.

Step 3

Write the Code

Copy this complete code into your weather_app.py file. Replace YOUR_API_KEY with your actual key from Step 1:

weather_app.py
# Weather App with Tkinter GUI - NKDevSpace Tutorial

import tkinter as tk
import requests

# ── Replace with your OpenWeatherMap API key ──
API_KEY = "YOUR_API_KEY"

def get_weather():
    """Fetch weather data from the API and display it."""
    city = city_entry.get().strip()

    if city == "":
        result_label.config(text="Please enter a city name.", fg="#ef4444")
        return

    url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric"

    try:
        response = requests.get(url, timeout=5)
        data = response.json()

        if data["cod"] == 200:
            # Extract the data we need from the JSON response
            temp      = data["main"]["temp"]
            feels     = data["main"]["feels_like"]
            humidity  = data["main"]["humidity"]
            condition = data["weather"][0]["description"].title()
            wind      = data["wind"]["speed"]
            country   = data["sys"]["country"]

            result = (
                f"📍 {city.title()}, {country}\n\n"
                f"🌡️  Temperature : {temp}°C  (Feels like {feels}°C)\n"
                f"💧  Humidity    : {humidity}%\n"
                f"☁️  Condition   : {condition}\n"
                f"💨  Wind Speed  : {wind} m/s"
            )
            result_label.config(text=result, fg="#e2e8f0")

        elif data["cod"] == "404":
            result_label.config(text="City not found! Check the spelling.", fg="#ef4444")
        else:
            result_label.config(text=f"Error: {data.get('message', 'Unknown error')}", fg="#ef4444")

    except requests.exceptions.ConnectionError:
        result_label.config(text="No internet connection. Please check your network.", fg="#ef4444")
    except requests.exceptions.Timeout:
        result_label.config(text="Request timed out. Try again.", fg="#ef4444")
    except Exception as e:
        result_label.config(text=f"Something went wrong: {str(e)}", fg="#ef4444")

# ── Build the GUI window ──
root = tk.Tk()
root.title("Weather App - NKDevSpace")
root.geometry("420x380")
root.resizable(False, False)
root.configure(bg="#0d1117")

# Title label
title_label = tk.Label(
    root,
    text="🌤️ Weather App",
    font=("Poppins", 18, "bold"),
    bg="#0d1117",
    fg="#4f8ef7"
)
title_label.pack(pady=(24, 6))

subtitle = tk.Label(
    root,
    text="Enter a city to get real-time weather",
    font=("Poppins", 10),
    bg="#0d1117",
    fg="#8899b0"
)
subtitle.pack()

# City input field
city_entry = tk.Entry(
    root,
    font=("Poppins", 13),
    width=24,
    bg="#161b27",
    fg="#e2e8f0",
    insertbackground="white",
    relief="flat",
    bd=8
)
city_entry.pack(pady=16)
city_entry.focus()  # Auto-focus the input field

# Search button
search_btn = tk.Button(
    root,
    text="Get Weather",
    font=("Poppins", 11, "bold"),
    bg="#2563eb",
    fg="white",
    activebackground="#1d4ed8",
    activeforeground="white",
    relief="flat",
    padx=20,
    pady=8,
    cursor="hand2",
    command=get_weather
)
search_btn.pack()

# Result display label
result_label = tk.Label(
    root,
    text="",
    font=("Poppins", 11),
    bg="#0d1117",
    fg="#e2e8f0",
    justify="left",
    wraplength=380
)
result_label.pack(pady=20, padx=20)

# Allow pressing Enter to search
root.bind('', lambda event: get_weather())

# Start the GUI event loop
root.mainloop()
Step 4

Code Explanation

root = tk.Tk()
Creates the main application window. Tk() is the root window - everything else (labels, buttons, inputs) is placed inside it. root.mainloop() at the end starts the event loop that keeps the window open and responsive.
requests.get(url, timeout=5)
Sends an HTTP GET request to the OpenWeatherMap API URL. The timeout=5 means if the server doesn't respond within 5 seconds, it raises a Timeout error instead of hanging forever. The response comes back as JSON data.
data["main"]["temp"]
The API returns a JSON object (like a Python dictionary). We access nested values using keys. data["main"] gets the "main" section, then ["temp"] gets the temperature from inside it. units=metric in the URL ensures the temperature is in Celsius.
result_label.config(text=result, fg="#e2e8f0")
.config() updates a widget's properties after it's been created. Here we update the label's text and text color. We use this to show results or error messages in different colors (white for success, red for errors).
root.bind('<Return>', lambda event: get_weather())
This binds the Enter key to the get_weather function. So users can press Enter instead of clicking the button. The lambda is needed because bind passes an event argument, but our function doesn't need it.
Step 5

Run the Program

  1. Open your terminal and navigate to your project folder:
    CMD / Terminal
    cd path\to\your\folder
  2. Run the app:
    CMD / Terminal
    python weather_app.py
  3. A window will open - type a city name like Chennai or London
  4. Click Get Weather or press Enter
  5. You should see the temperature, humidity, condition, and wind speed!
Try cities like Kuppam, Bangalore, Mumbai, New York, Tokyo. The API supports thousands of cities worldwide.
Step 6

Try It Yourself - Challenges

Previous Tutorial All Tutorials