๐Ÿ‡ฏ๐Ÿ‡ต ๆ—ฅๆœฌ่ชž | ๐Ÿ‡บ๐Ÿ‡ธ English | ๐Ÿ‡ช๐Ÿ‡ธ Espaรฑol | ๐Ÿ‡ต๐Ÿ‡น Portuguรชs | ๐Ÿ‡น๐Ÿ‡ญ เน„เธ—เธข | ๐Ÿ‡จ๐Ÿ‡ณ ไธญๆ–‡

[Copy-Paste Ready] Build a Weather Forecast CLI App with Python and an API! A Step-by-Step Guide for Beginners

"I've started programming, but I don't know what to make..." "I'm studying, but I feel like giving up because I can't build anything that actually works..."

Just a few months ago, I had the exact same worries. I started self-studying from zero programming knowledge with the help of AI, and now I can even run my own websites. From this experience, I've learned that the most important thing in the early stages of learning is the "experience of building something with your own hands and seeing it work."

In this article, I'll provide a more detailed guide than anywhere else on how to create a simple command-line (CLI) app using Python that tells you the weather forecast, so that even programming beginners can feel the joy of "It works! This is fun!"

Here's what the finished product will look like. What happens when you type a command in the terminal (the black screen)...?

$ python weather.py Tokyo

[ Weather in Tokyo (JP) ]
Weather: clear sky โ˜€๏ธ
Temperature: 28.5ยฐC (Feels like: 29.1ยฐC)
Humidity: 65%
Wind Speed: 3.1 m/s

It's not difficult at all! Just by copying and pasting, you can get this running on your computer right away. I'll be sharing the points where I actually got stuck, so please follow along with confidence.

STEP 1: Prepare for Your Adventure! - Getting a Weather API Key

First, there's the question of where to get the weather information. The weather forecasts we see on TV and our smartphones are based on data observed by specialized agencies like meteorological observatories, right?

This time, we'll use a service called OpenWeatherMap. By using a mechanism called an API provided by this service, we can freely retrieve weather data from around the world in our programs.

There's no need to think too hard about "What's an API?". For now, just think of it as a kind of "password (key) for retrieving weather data from a program." I'll explain the steps to get this key (API key).

  1. Go to the OpenWeatherMap API page, and click the "Subscribe" button under "Current Weather Data."
  2. Click the "Get API key" button in the free plan and create an account (set your email address, password, etc.).
  3. Once registration is complete, your dedicated API key will be issued in the "API keys" tab of your dashboard. This string of about 32 alphanumeric characters is the "password" I mentioned earlier.

[Crucially Important] Never tell your API key to anyone or publish it on social media or GitHub!
This key is for your use only. If it falls into the hands of someone with malicious intent, they could make a large number of unauthorized requests, and you could be billed for it. Treat it with the same care as your precious house key.


STEP 2: Gather Your Tools! - The `requests` Library

Once you have your API key, the next step is to prepare the tools to use the API from Python. That tool is a library called `requests`.

A library is like a "toolbox" that comes with a set of convenient functions. With `requests`, you can access websites and APIs with just a few lines of code.

Open your PC's terminal (Command Prompt or PowerShell on Windows, Terminal on Mac) and run the following command.

pip install requests

If you see a message like `Successfully installed...`, you're all set. Now you're ready to communicate with the weather API!

STEP 3: Let's Try a Simple Run!

It's finally time to code. First, let's write a very simple piece of code to get the weather for a specific city (Tokyo, in this case). Create a file named `weather.py` in your editor and paste the following code into it.

import requests
import json

# Replace with your API key obtained in STEP 1
API_KEY = "Paste_your_API_key_here"
CITY_NAME = "Tokyo"

# Construct the API request URL
api_url = f"https://api.openweathermap.org/data/2.5/weather?q={CITY_NAME}&appid={API_KEY}&units=metric&lang=en"

try:
    # Actually send the request to the API
    response = requests.get(api_url)
    response.raise_for_status() # Raise an exception if there's an error

    # Convert the result from JSON format to a Python dictionary
    data = response.json()

    # Display the data in a readable format
    print(json.dumps(data, indent=2, ensure_ascii=False))

except requests.exceptions.RequestException as e:
    print(f"A communication error occurred: {e}")
except Exception as e:
    print(f"An unexpected error occurred: {e}")

After pasting the code, don't forget to replace the `API_KEY = "Paste_your_API_key_here"` part with your own API key that you just obtained.

Once you've replaced it, let's run this file from the terminal.

$ python weather.py

How did it go? If you see a lot of text (data) like the one below, you've succeeded!

{
  "coord": {
    "lon": 139.6917,
    "lat": 35.6895
  },
  "weather": [
    {
      "id": 800,
      "main": "Clear",
      "description": "clear sky",
      "icon": "01d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 28.5,
    "feels_like": 29.1,
    "temp_min": 27.21,
    "temp_max": 29.58,
    "pressure": 1012,
    "humidity": 65
  },
  "visibility": 10000,
  "wind": {
    "speed": 3.09,
    "deg": 190
  },
  // ...and so on
}

This is the raw state of the "current weather data for Tokyo" sent from OpenWeatherMap. The next step is to extract only the necessary information from this data format called JSON.

[Sticking Point Explained] How to Read JSON Data
JSON is made up of a combination of `{}` (curly braces) and `[]` (square brackets).

In Python, JSON's `{}` can be treated as a "dictionary" and `[]` as a "list," making them very compatible. For example, if you want to get the temperature (`temp`), you can access `temp` inside the larger `main` block, so you would write `data['main']['temp']`. Simple, right?

STEP 4: Let's Seriously Upgrade the App!

Now for the main event. Instead of changing the code every time, let's evolve it into a proper CLI app where the user can input a city name and see only the necessary information displayed clearly.

This time, to create a more serious CLI app, we'll use Python's standard library, `argparse`. Using this, you can pass information at runtime, like `python weather.py Tokyo`.

Please completely replace the contents of `weather.py` with the following. The way the API key is managed has also been changed to a more secure form.

import requests
import argparse
import os

def get_weather_emoji(weather_main):
    """Returns an emoji from the English name of the weather"""
    if weather_main == "Clear":
        return "โ˜€๏ธ"
    elif weather_main == "Clouds":
        return "โ˜๏ธ"
    elif weather_main == "Rain":
        return "๐ŸŒง๏ธ"
    elif weather_main == "Drizzle":
        return "๐ŸŒฆ๏ธ"
    elif weather_main == "Thunderstorm":
        return "โ›ˆ๏ธ"
    elif weather_main == "Snow":
        return "โ„๏ธ"
    else:
        return "๐ŸŒซ๏ธ" # Mist, Smoke, Haze, Dust, Fog, Sand, Ash, Squall, Tornado

def format_weather_data(data):
    """Formats the API response and returns it as a string"""
    try:
        city_name = data["name"]
        country = data["sys"]["country"]
        weather_description = data["weather"][0]["description"]
        weather_main = data["weather"][0]["main"]
        emoji = get_weather_emoji(weather_main)
        temp = data["main"]["temp"]
        feels_like = data["main"]["feels_like"]
        humidity = data["main"]["humidity"]
        wind_speed = data["wind"]["speed"]

        # Assemble the output string for easy reading
        output = f"[ Weather in {city_name} ({country}) ]\n"
        output += f"Weather: {weather_description} {emoji}\n"
        output += f"Temperature: {temp}ยฐC (Feels like: {feels_like}ยฐC)\n"
        output += f"Humidity: {humidity}%\n"
        output += f"Wind Speed: {wind_speed} m/s"
        
        return output
    except KeyError:
        return "Failed to parse weather data. The response format may be invalid."

def main():
    # 1. Get the API key from an environment variable
    #    to manage the key more securely
    api_key = os.getenv("OPENWEATHERMAP_API_KEY")
    if not api_key:
        print("Error: The environment variable 'OPENWEATHERMAP_API_KEY' is not set.")
        print("Please set the API key and run again.")
        return # Exit the program

    # 2. Set up command-line arguments
    parser = argparse.ArgumentParser(description="Displays the current weather information for a specified city.")
    parser.add_argument("city", help="The name of the city to get weather information for (e.g., Tokyo)")
    parser.add_argument("-u", "--units", choices=["metric", "imperial"], default="metric", 
                        help="Specify the unit of temperature ('metric' for Celsius, 'imperial' for Fahrenheit)")
    
    args = parser.parse_args()
    
    # 3. Send a request to the API
    base_url = "https://api.openweathermap.org/data/2.5/weather"
    params = {
        "q": args.city,
        "appid": api_key,
        "units": args.units,
        "lang": "en"
    }

    try:
        response = requests.get(base_url, params=params)
        # Raise an exception for 4xx and 5xx error codes
        response.raise_for_status()

        weather_data = response.json()
        
        # 4. Display the results
        formatted_output = format_weather_data(weather_data)
        print(formatted_output)

    except requests.exceptions.HTTPError as e:
        if e.response.status_code == 401:
            print("Error: Invalid API key. Please check if the correct API key is set.")
        elif e.response.status_code == 404:
            print(f"Error: City '{args.city}' not found. Please check the city name.")
        else:
            print(f"An HTTP error occurred: {e}")
    except requests.exceptions.RequestException as e:
        print(f"A communication error occurred: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")


if __name__ == "__main__":
    main()

[Important] How to Securely Set an API Key (Environment Variables)

I mentioned that it's risky to write your API key directly in the code. So, we'll use a mechanism called "environment variables," which is also used in professional settings. This is a way to have your PC itself remember the API key.

For Mac / Linux:

export OPENWEATHERMAP_API_KEY="your_api_key"

For Windows (Command Prompt):

set OPENWEATHERMAP_API_KEY="your_api_key"

For Windows (PowerShell):

$Env:OPENWEATHERMAP_API_KEY="your_api_key"

Run the above command in your terminal (the setting will be reset when you close the terminal). Now, the code `os.getenv("OPENWEATHERMAP_API_KEY")` will be able to read the key you set on your PC.

Once you're ready, let's run it!

$ python weather.py London

Did it successfully display the weather in London?

Now, let's try displaying the weather in New York City in Fahrenheit.

$ python weather.py "New York" -u imperial

Don't forget to enclose the city name in `"` (double quotes) if it contains spaces. If the temperature is displayed in Fahrenheit (ยฐF), you've succeeded!

Try deliberately entering a wrong city name or setting the wrong API key to see that the error messages are displayed correctly. This is "robust error handling."

Conclusion: Beyond "It Works!"

Great job! You've now completed your very own original weather forecast CLI app. More than just copying and pasting code, you should have learned the following:

The most important thing in learning to program is to accumulate these "small successes." Based on the app you built today, try to customize it with your own ideas, like "let's display multiple cities at once," "let's add an hourly forecast," or "let's send the results to Line."

Use the "joy of making things that work" as your fuel and continue your adventure in the world of programming!

To the Next Step

Everyone who programs in Python eventually encounters "indentation errors." Be sure to read our article that thoroughly explains why they happen and how to fix them.

Causes and Solutions for IndentationError