Skip to main content

How to Build a Command-Line Weather App with Python

Updated 4 min readMarkdown

📌 Quick Info

  • Topic: Building a real CLI app with Python and APIs

  • Target Audience: Beginners who know basic Python and want a real project

  • Goal: Combine everything you've learned into one working tool

  • Format: freeCodeCamp (1,500+ words, code-heavy, step-by-step)


1. Introduction

"You've learned the basics of Python. You've written a few scripts. But now you want to build something real. In this tutorial, you'll build a command-line weather app that fetches live data from an API and displays it in your terminal."


2. Prerequisites

Before starting, make sure you have:

  • Python 3.8+ installed

  • The requests library (pip install requests)

  • An understanding of functions and dictionaries

  • A terminal or command prompt open


3. What We're Building

By the end of this tutorial, you will have a CLI app that works like this:

python weather.py Karachi

And outputs:

Weather in Karachi:
Temperature: 32.4°C
Wind Speed: 12.5 km/h
Conditions: Clear

4. Step 1: Setting Up the Project

Create a new file called weather.py. This is where all the code will live.


5. Step 2: Getting Coordinates from a City Name

The weather API we're using requires latitude and longitude, not a city name. So we need to convert the city name to coordinates first. We'll use the Open-Meteo Geocoding API for this.

import requests

def get_coordinates(city):
    url = "<https://geocoding-api.open-meteo.com/v1/search>"
    params = {"name": city, "count": 1}
    response = requests.get(url, params=params)
    data = response.json()

    if "results" not in data:
        return None

    result = data["results"][0]
    return result["latitude"], result["longitude"]

How this works:

  • We construct a GET request with the city name as a parameter.

  • We convert the response to JSON using .json().

  • We check if "results" is missing. If it is, the city wasn't found, so we return None.

  • If it exists, we grab the latitude and longitude from the first result.


6. Step 3: Fetching the Weather Data

Now that we have the coordinates, we can fetch the weather from Open-Meteo.

def get_weather(lat, lon):
    url = "<https://api.open-meteo.com/v1/forecast>"
    params = {
        "latitude": lat,
        "longitude": lon,
        "current_weather": True
    }
    response = requests.get(url, params=params)
    return response.json()["current_weather"]

How this works:

  • We pass the latitude, longitude, and current_weather=True to the API.

  • We return the specific current_weather part of the JSON response.


7. Step 4: Putting It All Together

Now Let’s create the main() function that ties everything together.

import sys

def main():
    if len(sys.argv) < 2:
        print("Usage: python weather.py <city>")
        return

    city = sys.argv[1]
    coords = get_coordinates(city)

    if not coords:
        print(f"Couldn't find city: {city}")
        return

    weather = get_weather(*coords)
    print(f"\nWeather in {city}:")
    print(f"Temperature: {weather['temperature']}°C")
    print(f"Wind Speed: {weather['windspeed']} km/h")

How this works:

  • We check sys.argv to see if the user provided a city.

  • We call get_coordinates(). If it fails, we exit gracefully.

  • We call get_weather() with the coordinates and print the results.


8. Step 5: Handling Errors

What happens if the API is down? Or if the user types a city with an empty string? Let's add error handling.

def get_weather(lat, lon):
    try:
        response = requests.get(url, params=params, timeout=5)
        response.raise_for_status()
        return response.json()["current_weather"]
    except requests.exceptions.RequestException:
        return None

If get_weather returns None, we can handle it gracefully in main().


9. Testing the App

Run the app with a few different cities:

python weather.py Karachi
python weather.py London
python weather.py "New York"

Make sure to test edge cases like empty strings, invalid cities, and no arguments at all.


10. Conclusion

You just built a real command-line tool. You learned how to:

  • Fetch data from an API

  • Covert city names to coordinates

  • Handle JSON responses

  • Use sys.argv for terminal input

  • Handle errors gracefully

Where to go next:

  • Add a forecast for the next 3 days

  • Save favorite cities to a JSON file

  • Format the output with colors

  • Turn it into a web app with Flask

About the author

  • I'm a technical writer who focuses on deep-dive Python tutorials. I write about the "why" behind the code, not just the syntax. 33+ articles published on Dev.to. Excited to be contributing to freeCodeCamp!

No comments yet. Be the first to comment.