Если вы хоть раз задавались вопросом, какая погода за окном, то вместо того, чтобы смотреть в окно, можно воспользоваться OpenWeatherMap! Это популярный сервис, предоставляющий погодные данные для различных локаций по всему миру. Реальные разработчики часто обращаются к таким внешним API, чтобы обогатить свои приложения данными вроде температуры, влажности или прогноза на неделю.
OpenWeatherMap API позволяет:
- Получать текущую погоду для указанного города.
- Предоставлять прогноз погоды на несколько дней вперед.
- Предоставлять исторические данные о погоде.
- Работать с глобальными геоданными.
Регистрация и получение API-ключа
Для доступа к OpenWeatherMap API потребуется регистрация. После регистрации:
- Зайдите в OpenWeatherMap.
- Создайте бесплатный аккаунт (если вы не готовы платить за разработку — а мы будем работать с бесплатным доступом).
- Получите ваш API-ключ в разделе "API keys". Он понадобится для аутентификации запросов.
Настройка проектной структуры
Перед тем, как приступить к созданию кода, убедимся, что структура проекта готова к нашей интеграции.
weather_app/
├── app/
│ ├── main.py
│ ├── routes/
│ │ ├── weather.py
│ ├── services/
│ │ ├── weather_service.py
│ ├── models/
│ │ ├── weather.py
├── requirements.txt
- routes/ — для маршрутов API.
- services/ — для логики работы с OpenWeatherMap API.
- models/ — для описания Pydantic моделей.
Реализация интеграции: шаг за шагом
Для работы нам понадобятся следующие библиотеки:
fastapi— для создания API.httpx— для отправки асинхронных HTTP-запросов.uvicorn— для запуска приложения.
Установите зависимости из requirements.txt:
fastapi==0.115.8
httpx==0.28.1
uvicorn==0.34.0
Или установите их напрямую с помощью pip:
pip install fastapi httpx uvicorn
Шаг 1: создаём базовое приложение FastAPI
Создайте файл app/main.py и добавьте туда основной запуск нашего приложения:
from fastapi import FastAPI
from app.routes.weather import router as weather_router
app = FastAPI(title="Weather App")
# Подключаем маршруты для работы с погодой
app.include_router(weather_router, prefix="/weather")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)
Шаг 2: создаём маршрут для получения погоды
В файле app/routes/weather.py добавим маршрут для обработки запросов:
from fastapi import APIRouter, HTTPException
from app.services.weather_service import fetch_weather_data
from app.models.weather import WeatherResponse
router = APIRouter()
@router.get("/{city}", response_model=WeatherResponse)
async def get_weather(city: str):
"""
Получает текущую погоду для указанного города.
"""
try:
weather_data = await fetch_weather_data(city)
return weather_data
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
Шаг 3: реализуем логику для обращения к OpenWeatherMap API
Теперь создадим файл app/services/weather_service.py, в котором будет находиться логика работы с OpenWeatherMap:
import httpx
from app.models.weather import WeatherResponse
API_KEY = "ваш_API_ключ_сюда"
BASE_URL = "https://api.openweathermap.org/data/2.5/weather"
async def fetch_weather_data(city: str) -> WeatherResponse:
"""
Отправляет запрос в OpenWeatherMap API для получения данных о погоде.
"""
params = {
"q": city,
"appid": API_KEY,
"units": "metric", # Получаем температуру в Цельсиях
}
async with httpx.AsyncClient() as client:
response = await client.get(BASE_URL, params=params)
if response.status_code == 200:
data = response.json()
return WeatherResponse(
city=data["name"],
temperature=data["main"]["temp"],
description=data["weather"][0]["description"]
)
else:
raise Exception(f"Ошибка при получении данных: {response.text}")
Шаг 4: добавляем Pydantic модель для ответа
Переходим в файл app/models/weather.py и создаём модель WeatherResponse для валидации и форматирования данных:
from pydantic import BaseModel
class WeatherResponse(BaseModel):
city: str
temperature: float
description: str
Запуск и тестирование приложения
Запустите приложение:
uvicorn app.main:app --reload
Проверьте работу маршрута, используя браузер или Postman, отправив GET-запрос:
http://127.0.0.1:8000/weather/London
Если всё настроено правильно, вы получите результат:
{
"city": "London",
"temperature": 15.5,
"description": "clear sky"
}
Для тестирования вы также можете использовать встроенный Swagger-интерфейс FastAPI. Откройте:
http://127.0.0.1:8000/docs
Расширение функциональности
Пример 1: улучшаем функционал маршрута
Добавим длительный прогноз погоды. Для этого можно использовать другой эндпоинт OpenWeatherMap, например, /forecast.
BASE_FORECAST_URL = "https://api.openweathermap.org/data/2.5/forecast"
Реализуйте новый метод fetch_forecast_data для получения прогноза.
Пример 2: добавляем поддержку нескольких единиц измерения
Добавьте параметр units для выбора между "metric", "imperial" и "standard".
Важные моменты и типичные ошибки
Не забывайте:
- Проверять, что ваш API-ключ активен и у вас нет превышения лимита запросов.
- Обрабатывать ошибки на уровне кода (например, при передаче неверного города).
- Логировать ошибки, чтобы обнаруживать проблемы в работе.
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Используйте logger для записи ошибок
Если OpenWeatherMap API вернул вам 401 или 429 код, стоит проверить ваш API-ключ или уменьшить частоту запросов.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ