# How to Build a Weather API with FastAPI and Vercel

**Author:** Ricardo Gonzalez  , Ismael Rumzan

---

To provide real-time weather data, you need to handle API integration, error handling and automatic scaling. With Vercel functions and FastAPI, you can build a production-ready weather API in minutes.

In this tutorial, you will build and deploy a weather API route using the Open-Meteo API that:

1. Accepts a city name and geocodes it to coordinates
   
2. Fetches current weather data from the Open-Meteo API
   
3. Returns temperature, humidity, wind speed, and other weather metrics with optional metric/imperial unit conversion
   

## Prerequisites

- Python 3.10+ installed locally
  
- A Vercel account
  
- Basic understanding of FastAPI and async/await concepts
  

## Build the Weather API

### 1\. Create your FastAPI project

Start with the template [Deploy FastAPI Boilerplate](https://vercel.com/templates/python/fastapi-python-boilerplate). Once your the project is deployed on Vercel, clone the repository locally.

You can also create the project locally using the Vercel CLI with the following command

`vc init fastapi`

### 2\. Add the httpx dependency

Update your `requirements.txt` to include the `httpx` library for making async HTTP requests:

`fastapi uvicorn httpx`

### 3\. Add the Weather endpoint

Open `main.py` and add the necessary imports at the top of the file:

`from fastapi import FastAPI, HTTPException, Query from fastapi.responses import HTMLResponse import httpx`

Then add the weather endpoint after your existing routes:

`@app.get("/api/weather/{city}") async def get_weather(city: str, units: str | None = Query(default="metric")): """ Get current weather for a city. Args: city: City name (e.g., "London", "New York") units: Temperature units - "metric" (Celsius) or "imperial" (Fahrenheit) Returns: Weather data including temperature, humidity, wind speed, and location info """ # Normalize units parameter normalized_units = "imperial" if units == "imperial" else "metric" async with httpx.AsyncClient() as client: # Step 1: Geocode city to get coordinates try: geo_response = await client.get( "https://geocoding-api.open-meteo.com/v1/search", params={ "name": city, "count": 1, "language": "en", "format": "json" } ) geo_response.raise_for_status() geo_data = geo_response.json() if not geo_data.get("results"): raise HTTPException(status_code=404, detail=f"City '{city}' not found") location = geo_data["results"][0] name = location["name"] country = location["country"] latitude = location["latitude"] longitude = location["longitude"] except httpx.HTTPError as e: raise HTTPException(status_code=500, detail=f"Geocoding API error: {str(e)}") # Step 2: Fetch current weather data try: weather_params = { "latitude": latitude, "longitude": longitude, "current": "temperature_2m,relative_humidity_2m,apparent_temperature,wind_speed_10m", "timezone": "auto" } # Add unit parameters for imperial if needed if units == "imperial": weather_params["temperature_unit"] = "fahrenheit" weather_params["wind_speed_unit"] = "mph" weather_response = await client.get( "https://api.open-meteo.com/v1/forecast", params=weather_params ) weather_response.raise_for_status() weather_data = weather_response.json() # Return structured weather data return { "city": name, "country": country, "latitude": latitude, "longitude": longitude, "units": normalized_units, "current": weather_data["current"] } except httpx.HTTPError as e: raise HTTPException(status_code=500, detail=f"Weather API error: {str(e)}")` ### 4\. Test the route locally Install the dependencies and launch the application in dev mode: `pip install -r requirements.txt vercel dev` Use `curl` to test the API route: `# Test with default metric units curl http://localhost:3000/api/weather/london # Test with imperial units curl "http://localhost:3000/api/weather/san%20francisco?units=imperial"` You can also test the endpoint in your browser using the interactive API documentation at `http://localhost:3000/docs`. ### 5\. Deploy to Vercel - Push the changes to your remote repository or run the `vercel` cli command    - Vercel will create a new preview deployment for your to test    - Merge to main branch to deploy to Production    > When you deploy a FastAPI app to Vercel, the application becomes a single [Vercel Function](https://vercel.com/docs/functions) and uses [Fluid compute](https://vercel.com/docs/fluid-compute) by default.

## Summary

In this tutorial, you’ve built a real-time weather API using FastAPI on Vercel.

You learned to:

- Structure a dynamic API route and integrate external APIs
  
- Deploy the app to Vercel as a function for automatic scaling
  

For a production application, make sure that you use a weather API that will not be rate limited based on the amount of traffic that you are expecting.

## Next steps

### Explore references

- [Explore the FastAPI on Vercel docs](https://vercel.com/docs/frameworks/backend/fastapi)
  
- [FastAPI documentation](https://fastapi.tiangolo.com/)
  
- [Vercel Functions](https://vercel.com/docs/functions)

---

[View full KB sitemap](/kb/sitemap.md)
