Skip to main content
This lesson shows two practical approaches to integrating external APIs from Python:
  1. Use a Claude-generated Python script to call public services:
    • Geocode a city name to latitude/longitude using Nominatim (OpenStreetMap).
    • Fetch current weather for those coordinates from OpenWeather.
  2. Convert that script into a FastAPI application so anyone can request /weather/{city} and receive JSON with:
    • city name
    • coordinates (latitude, longitude)
    • temperature (in Fahrenheit)
    • short weather description
A presentation slide titled "Working with APIs and External Services." A dark curved panel on the right shows the word "Demo" in blue, with a small "© Copyright KodeKloud" at the bottom left.
Overview
  • Use Nominatim (OpenStreetMap) to geocode a city name to latitude/longitude.
  • Use OpenWeather to fetch current weather for those coordinates.
  • Provide an optional CLI entrypoint and a FastAPI HTTP endpoint /weather/{city}.
  • Return temperature in Fahrenheit (converted from metric API response), coordinates, and a short description.
Quick reference weather.py (single file: CLI + FastAPI) Below is the cleaned, production-friendly single-file example. It keeps logic in small functions for testability and exposes both CLI and HTTP access.
Running locally (example)
  1. Create and activate a virtual environment and install dependencies:
  1. Set your OpenWeather API key (replace with your actual key):
3a. Run the CLI example:
Example CLI output (when successful):
3b. Run the FastAPI app with uvicorn:
Then open: http://localhost:8000/weather/New%20York Example JSON response:
Troubleshooting and tips
Tips:
  • Use python3 on macOS (some systems don’t have python mapped to Python 3).
  • If you get a 401 Unauthorized from OpenWeather, verify the OPENWEATHER_API_KEY environment variable is set correctly and that the key is active (new keys can take a few minutes to become active).
  • For debugging, set debug=True when calling get_weather to print the request/response status and the first 8 characters of your API key (the code is already prepared to show these debug lines). Avoid enabling debug logging in production, as even truncated key output can be sensitive.
  • Respect Nominatim’s usage policy: include a descriptive User-Agent (as shown), avoid excessive requests, and follow rate limits. For heavy usage or production systems consider a dedicated geocoding service or local instance. See Nominatim’s usage policy for details: https://operations.osmfoundation.org/policies/nominatim/
  • The FastAPI endpoint in this example calls synchronous requests functions from an async endpoint. This will block the event loop for the duration of those requests. For production use, either:
    • use an async HTTP client such as httpx.AsyncClient, or
    • run blocking calls in a thread pool (e.g., via asyncio.to_thread or FastAPI dependency/background task) to avoid blocking other requests.
What we demonstrated
  • Combining Nominatim and OpenWeather APIs from Python to build a small, useful service.
  • Handling common errors (missing API key, city not found, API failures, unexpected response formats).
  • Converting a CLI script into a simple HTTP API with FastAPI so other people or services can request weather by city name.
References and further reading

Watch Video

Practice Lab