Courses/Streamlit: 20 Real Apps/Module 5: APIs & Automation
Module 5 · Lesson 125 minBeginner

Project 14: Weather App

What you'll build
Make your first API call and render live weather for any city.

Introduction

In this project you will build a real-time weather app using Python, Streamlit, and the free OpenWeatherMap API. Type any city name and instantly see the current temperature, humidity, wind speed, and weather description. This is one of two API-driven builds here — the recipe finder uses the identical requests pattern with a different API.

Prerequisites

  • Python 3.8+python.org
  • Libraries — Install with pip:
  • code
    pip install streamlit requests
  • OpenWeatherMap API Key — Sign up free at openweathermap.org and copy your key from the dashboard.
  • Step 1: Create the Script

    Create weather_app.py and paste the following:

    code
    import streamlit as st
    import requests
    
    st.set_page_config(page_title="Weather App", page_icon="🌤️")
    st.title("🌤️ Real-Time Weather App")
    
    API_KEY = "YOUR_OPENWEATHERMAP_API_KEY"
    
    city = st.text_input("Enter a city name:", placeholder="e.g. Mumbai, London, New York")
    
    def get_weather(city):
        url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric"
        return requests.get(url).json()
    
    if st.button("Get Weather") and city:
        data = get_weather(city)
        if data.get("cod") == 200:
            col1, col2 = st.columns(2)
            with col1:
                st.metric("🌡️ Temperature", f"{data['main']['temp']} °C")
                st.metric("💧 Humidity", f"{data['main']['humidity']}%")
            with col2:
                st.metric("💨 Wind Speed", f"{data['wind']['speed']} m/s")
                st.metric("☁️ Condition", data['weather'][0]['description'].title())
            st.success(f"Showing weather for **{data['name']}, {data['sys']['country']}**")
        else:
            st.error("City not found. Please check the spelling and try again.")

    Step 2: Add Your API Key

    Replace YOUR_OPENWEATHERMAP_API_KEY with the key you copied from the OpenWeatherMap dashboard.

    Step 3: Run the App

    code
    streamlit run weather_app.py

    Step 4: Use the App

    Type a city name and click Get Weather. The app displays current conditions in a clean two-column layout with metric cards.

    How It Works

    The app follows the standard API request cycle: build a URL with the city and your key, call requests.get(), check response.status_code, then pull fields out of the JSON payload. OpenWeatherMap returns a deeply nested dictionary, so the code extracts weather[0]["description"], main["temp"], and similar paths — always with .get() so a missing field returns None instead of crashing.

    A detail worth noticing: the temperature is fetched in metric units by passing &units=metric, which is much easier than converting Kelvin yourself. Display-wise, st.metric() pairs the temperature with a delta arrow, and st.image() renders the icon using the icon code from the response.

    Because the rerun model fires a fresh API call on every widget change, real apps add caching — wrapping the fetch in @st.cache_data(ttl=600) means repeated lookups within ten minutes are served instantly. The same caching idea powers the Pandas dashboard.

    Key Concepts

  • `requests.get()` — Sends the HTTP GET request to the OpenWeatherMap API.
  • `response.json()` — Parses the JSON response into a Python dictionary.
  • `st.metric()` — Renders each weather value as a styled metric card.
  • `st.columns()` — Splits the layout into two side-by-side columns.
  • What to Try Next

  • Show a 5-day forecast using the /forecast endpoint.
  • Add weather icons from OpenWeatherMap's icon library.
  • Allow users to switch between Celsius and Fahrenheit using a toggle.
  • Common Errors & Fixes

  • 401 Unauthorized — new API keys take up to a couple of hours to activate, and the key must be passed as appid, not api_key. Double-check both before debugging anything else.
  • 404 city not found — the city name needs the country code for ambiguous names: "London,UK" not "London".
  • KeyError: 'main' — you are parsing an error response. Always branch on status_code == 200 before reading weather fields.
  • SSL errors on corporate networks — proxy interception; try requests.get(url, verify=False) temporarily to confirm, then fix the proxy cert store.
  • Rate limit exceeded (429) — you are re-fetching on every widget interaction; wrap the API call in @st.cache_data(ttl=600) so repeat lookups reuse the cache.
  • FAQ

    Is the OpenWeatherMap API free?

    Yes — the free tier allows 60 calls/minute and 1,000,000 calls/month, far more than a personal app needs.

    Can I show a 5-day forecast?

    Yes — use the /forecast endpoint instead of /weather and render the list with st.line_chart() for temperatures, similar to the data dashboard.

    How do I hide my API key?

    Store it in an environment variable or st.secrets, never in the code you push to GitHub.

    Can I use geolocation instead of typing a city?

    Yes — get coordinates in the browser with JavaScript and pass them to the /weather endpoint's lat/lon parameters, which are more precise than city names.

    Adapted from: Weather App using Python, Streamlit, and OpenWeatherMap API

    Checkpoint
    Typing a city shows real current conditions with icons and temperature.
    What you learned
    • The request-parse-display cycle
    • Status code guards
    • API keys via environment