Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
420: Building a Weather CLI Tool Using a Public API
One thing I see a lot of developers stumble over when they first touch an API is the belief that an API call is just a fancy function call. They think that when they request weather data, the server sends back a clean Python object with attributes like weather.temperature or weather.city. It feels intuitive, but it's completely wrong.
In reality, an API doesn't know Python exists. It sends back a long string of text formatted as JSON (JavaScript Object Notation). If you try to treat that response like a Python object immediately, your program will crash with an AttributeError or a TypeError. You aren't receiving a "Weather Object"; you're receiving a serialized string that you have to decode into a dictionary before you can even think about accessing the temperature.
The "Magic Object" Fallacy vs. Parsing JSON Dictionaries
Let's look at how this actually plays out. If you use the requests library to hit a weather endpoint, the raw response is an HTTP object. To get the data, you have to call the .json() method, which transforms that string into a nested Python dictionary. I've spent way too many hours debugging "NoneType" errors simply because I forgot that API data is often nested three or four levels deep.
import requests
# This is a simplified version of what happens
API_KEY = "your_api_key_here"
city = "London"
url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={API_KEY}&units=metric"
response = requests.get(url)
data = response.json()
# WRONG: Thinking it's a flat object
# print(data.temperature)
# RIGHT: Navigating the dictionary hierarchy
temp = data['main']['temp']
description = data['weather'][0]['description']
print(f"The weather in {city} is {temp}°C with {description}.")
Notice that data['weather'] is actually a list containing a dictionary. That's a classic API quirk. You can't just ask for the description; you have to ask for the first item in the weather list, and then ask for the description key within that item.
Hardcoding Keys is "Fine for Now" vs. Environment Variables
When you're building a CLI tool, it's tempting to just paste your API key directly into the script. I did this early in my career, pushed it to GitHub, and had my account suspended within ten minutes because bots scrape public repos for keys. Never do this. Even for a small project, get in the habit of using environment variables.
By using the os module, you keep your secrets out of your code. It makes your tool portable and secure. If you share your code with a teammate, they can use their own key without you having to edit the source file for them.
import os
from dotenv import load_dotenv # You'll need to pip install python-dotenv
load_dotenv()
API_KEY = os.getenv("OPENWEATHER_API_KEY")
if not API_KEY:
raise ValueError("Missing API Key! Please set OPENWEATHER_API_KEY in your .env file.")
Assuming the Internet Always Works vs. Defensive Request Handling
Your code might work perfectly on your machine today, but the moment a user has a spotty connection or the API server goes down for maintenance, your CLI tool will throw a massive, ugly traceback. A professional tool handles failure gracefully. You don't want your user seeing a ConnectionError; you want them to see "Sorry, I couldn't reach the weather service right now."
I always recommend wrapping your request in a try-except block and checking the status code. A 200 OK is great, but a 404 Not Found (usually meaning the user typed the city name wrong) needs a specific message.
try:
response = requests.get(url, timeout=5)
response.raise_for_status() # This raises an exception for 4xx or 5xx errors
data = response.json()
except requests.exceptions.HTTPError:
print("City not found. Please check your spelling.")
exit(1)
except requests.exceptions.ConnectionError:
print("Network error. Check your internet connection.")
exit(1)
except requests.exceptions.Timeout:
print("The server took too long to respond.")
exit(1)📋 Practical Task
Build a "City-to-City" Weather Comparison Tool
Your task is to create a CLI tool that accepts two city names as command-line arguments (using sys.argv) and prints a comparison of their current temperatures.
Requirements:
- The script should be executed as
python weather_compare.py London Tokyo. - Use an environment variable for your API key (do not hardcode it).
- Implement a
try-exceptblock to handle cases where one or both cities are not found by the API. - The output should clearly state which city is warmer and by how many degrees (e.g., "Tokyo is 5.2°C warmer than London").
- Ensure you are parsing the nested JSON response correctly to extract the temperature from the
'main'key.
There are no comments for now.