Learn how to create a Python-based Weather Report by City app — first with a one-liner using wttr.in, then with a full-featured solution using OpenStreetMap's Nominatim geocoding and the Open-Meteo API. Step-by-step code breakdown, error handling, and best practices included.

Introduction
Whether you're building a CLI tool for quick forecasts or a full-blown weather dashboard, fetching and displaying weather by city is a classic Python project. In this post, you'll first see a minimal one-liner solution using wttr.in, then dive into a robust implementation leveraging:
- Nominatim (OpenStreetMap's geocoding service)
- Open-Meteo API for current weather data
-
Python's
requestslibrary for HTTP calls
Prerequisites
Make sure you have:
- Python 3.7+ installed
-
The
requestslibrary:pip install requests
- A basic understanding of HTTP requests and JSON parsing
- (Optional) an IDE like VS Code for syntax highlighting
Quick & Simple: the wttr.in One-Liner
For an ultra-lightweight solution, you can use wttr.in — a free weather service for the terminal:
How it works: it prompts for a city, sends a GET request to wttr.in with ?format=3 (returns "City: +temp +condition"), and prints the concise result.
Pros: no API key required; one-liner. Cons: limited formatting, no fine-grained control, depends on an external service's uptime.
The Detailed Approach
For production-grade projects, you'll often need more control, reliability, and clarity. Let's explore a two-step version.
1. Geocoding with Nominatim
Most weather APIs require latitude & longitude, so we geocode first. Nominatim requires a descriptive User-Agent to identify your application, and you should always validate the JSON to avoid crashes on empty results.
2. Fetching Weather Data from Open-Meteo
Open-Meteo is free with no API key for basic usage. We request only temperature_2m and weathercode to minimize the payload, and validate that the current key exists before accessing nested fields.
3. Mapping Weather Codes to Descriptions
Weather APIs use numeric codes for conditions; mapping makes the output human-friendly. You can extend this dictionary to include icons, humidity, wind speed, and more.
4. Error Handling & User Feedback
-
JSON decode errors: wrap
response.json()in atry/except.
-
Network issues: handle
requests.exceptions.RequestExceptionfor timeouts or connection errors.
- Invalid input: prompt the user to re-enter if the city name yields no geocoding result.
Putting It All Together
Conclusion
You now have two approaches to fetch weather by city in Python: a one-line wttr.in solution for quick CLI checks, and a detailed implementation using Nominatim geocoding and the Open-Meteo API for production-grade apps. Experiment by extending the mapping dictionary, adding error logging, or integrating with a GUI/web framework like Flask or Tkinter. Happy coding!
About the Author: gs_admin
A senior technical contributor specializing in architectural designs, software optimization, database structures, and developer education. Passionate about writing clean code and sharing engineering knowledge.