<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Sameer Qaiser - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Sameer Qaiser - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 29 Oct 2026 03:33:40 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/sameerqaiser17/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Command-Line Weather App with Python ]]>
                </title>
                <description>
                    <![CDATA[ After doing a few basic Python projects, I got a bit bored of programs that just take input and print something back. I wanted to make something that actually gets data from the internet. So, I built  ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-a-command-line-weather-app-with-python/</link>
                <guid isPermaLink="false">6ae266148842cb1aa91f5625</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Beginner Developers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ webdev ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sameer Qaiser ]]>
                </dc:creator>
                <pubDate>Wed, 28 Oct 2026 21:16:04 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/b79396ff-d6f7-4e08-a4e0-282b0eb881da.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>After doing a few basic Python projects, I got a bit bored of programs that just take input and print something back. I wanted to make something that actually gets data from the internet.</p>
<p>So, I built this little weather app. If APIs still feel a bit abstract to you, don't worry. Just remember that an API is basically a way for your program to ask another program for information.</p>
<p>The idea is straightforward: you type a city name in the terminal, and it shows you the current temperature and wind speed. It's nothing fancy, but it’s a nice way to get comfortable with APIs, HTTP requests, and command-line arguments.</p>
<p>By the end of this tutorial, you'll know how to make HTTP requests, parse JSON data, handle errors gracefully, and build a script you can actually use from your terminal.</p>
<h3 id="heading-what-well-cover">What We'll Cover:</h3>
<ul>
<li><a href="#heading-what-you-need-to-get-started">What You Need to Get Started</a></li>
<li><a href="#heading-how-to-turn-a-city-name-into-coordinates">How to Turn a City Name into Coordinates</a></li>
<li><a href="#heading-how-to-get-the-actual-weather-data">How to Get the Actual Weather Data</a></li>
<li><a href="#heading-how-to-run-it-from-the-terminal">How to Run it From the Terminal</a></li>
<li><a href="#heading-lets-test-it-out">Let’s Test it Out</a></li>
<li><a href="#heading-what-i-might-add-next">What I Might Add Next</a></li>
<li><a href="#heading-final-thoughts">Final Thoughts</a></li>
</ul>
<h2 id="heading-what-you-need-to-get-started">What You Need to Get Started</h2>
<p>Before we start, make sure you have:</p>
<ul>
<li>Python installed</li>
<li>A code editor (l use VS Code)</li>
<li>The <strong>requests</strong> library.</li>
</ul>
<p>If you don’t have requests yet, open your terminal and run:</p>
<pre><code class="language-python">pip install requests
</code></pre>
<h2 id="heading-how-to-turn-a-city-name-into-coordinates">How to Turn a City Name into Coordinates</h2>
<p>Weather APIs usually want latitude and longitude, not city names. So the first thing we need is a way to convert “Karachi” or “New York” into coordinates.</p>
<p>Open-Meteo has a free geocoding API that does exactly that. Here’s the function I used:</p>
<pre><code class="language-python">import requests

def get_coordinates(city_name):
    url = "https://geocoding-api.open-meteo.com/v1/search"

    params = {
        "name": city_name,
        "count": 1
    }

    response = requests.get(url, params=params, timeout=5)
    response.raise_for_status()

    data = response.json()

    if not data.get("results"):
        return None

    latitude = data["results"][0]["latitude"]
    longitude = data["results"][0]["longitude"]

    return latitude, longitude
</code></pre>
<p>It's pretty simple. We send the city name, ask for one result, and pull out the latitude and longitude. If the API doesn’t find anything, we just return None instead of crashing later.</p>
<p>One small warning: some city names exist in multiple places. This code just grabs the first match, so it might not always pick the one you meant. Just make sure you double-check before you use it in your project.</p>
<h2 id="heading-how-to-get-the-actual-weather-data">How to Get the Actual Weather Data</h2>
<p>Once we have the coordinates, we can ask for the weather:</p>
<pre><code class="language-python">def get_weather(latitude, longitude):
    url = "https://api.open-meteo.com/v1/forecast"

    params = {
        "latitude": latitude,
        "longitude": longitude,
        "current": "temperature_2m,wind_speed_10m"
    }

    response = requests.get(url, params=params, timeout=5)
    response.raise_for_status()

    data = response.json()

    return data["current"]
</code></pre>
<p>The temperature_2m and wind_speed_10m parameters ask for the temperature at 2 meters above ground and wind speed at 10 meters. By specifying current, we tell the API we only want the data for right now, rather than a multi-day forecast. The API actually returns a bunch of other data too, but we'll just extract the current section.</p>
<h2 id="heading-how-to-run-it-from-the-terminal">How to Run it From the Terminal</h2>
<p>I wanted to be able to run it like this:</p>
<p>python <a href="http://weather.py">weather.py</a> Karachi</p>
<p>So, I used the <strong>sys</strong> module:</p>
<pre><code class="language-python">import sys

def main():
    if len(sys.argv) &lt; 2:
        print("Usage: python weather.py &lt;city_name&gt;")
        return

    city = " ".join(sys.argv[1:])

    try:
        coordinates = get_coordinates(city)

        if not coordinates:
            print(f"City not found: {city}")
            return

        latitude, longitude = coordinates
        weather = get_weather(latitude, longitude)

        print(f"\nWeather in {city.title()}")
        print(f"Temperature: {weather['temperature_2m']}°C")
        print(f"Wind speed: {weather['wind_speed_10m']} km/h")

    except requests.exceptions.RequestException:
        print("Couldn't connect to the weather service. Check your internet connection and try again.")

    except (KeyError, ValueError):
        print("Something went wrong while reading the weather data.")

if __name__ == "__main__":
    main()
</code></pre>
<p>The sys module gives us access to the command-line arguments. <code>sys.argv</code> is a list of everything you type in the terminal. <code>sys.argv[0]</code> is the file name (<a href="http://weather.py">weather.py</a>), and <code>sys.argv[1]</code> is the city name. Using <code>" ".join(sys.argv[1:])</code> allows us to handle city names with spaces, like New York.</p>
<h2 id="heading-lets-test-it-out">Let’s Test it Out</h2>
<p>Save the file as <a href="http://weather.py">weather.py</a>, open a terminal in that folder, and try:</p>
<pre><code class="language-python">python weather.py Madrid
python weather.py Paris
python weather.py Washington
</code></pre>
<p>If you forget to type a city, it just tells you how to use it.</p>
<pre><code class="language-plaintext">Weather in Madrid
Temperature: 15.2°C
Wind speed: 8.4 km/h
</code></pre>
<h2 id="heading-what-i-might-add-next">What I Might Add Next</h2>
<p>Once the basic version works, there are a few easy upgrades you can make:</p>
<ul>
<li>Add humidity (relative_humidity_2m)</li>
<li>Show a short forecast instead of just current conditions</li>
<li>Let the user pick from multiple matching cities when the name is ambiguous</li>
<li>Make the output a bit prettier</li>
</ul>
<p>I usually pick one small improvement, get it working, then move on. Trying to do everything at once usually just gets messy.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>This is a solid little project once you’re past the “print hello world” stage and want to build something that actually talks to the internet. You get real practice with functions, dictionaries, error handling, and APIs, which is stuff you’ll use all the time.</p>
<p>But here’s the important bit. Once you get it working, close this page and try building the whole thing again from scratch.</p>
<p>You’ll forget something. You’ll probably hit some weird error and waste an hour staring at it. That’s fine. That’s the part that actually teaches you something. Copy-pasting my code doesn’t really solidify anything in your brain. Figuring out why yours is broken does.</p>
<p>After you’ve got the weather app working, try the same approach with a completely different API (like movies, crypto prices, sports scores, whatever). The pattern is pretty much the same. Just get the basic version running first, then go break it.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
