OpenWeather は様々な気象データの API を提供しており、一部の機能は無料で使用できる。
アプリ開発チュートリアルでもよく見かける定番の API だ。
今回は、データを取得して表示する Python スクリプトと共に紹介してみたい。
以下の流れで進めていく。
- OpenWeather にサインアップして API キーを入手する
- API を呼び出してデータを取得する
a. 事前準備
b. Current weather data
c. 5 day weather forecast
1. OpenWeather にサインアップして API キーを入手する
まずは、OpenWeather にサインアップする。
-
サインアップページ にアクセスする
- フォームを入力し、Create Account をクリックする
- ホーム画面が開かれる(サインアップに使用したメールアドレスに確認メールが届く。メール を開き、Verify your email をクリックする)
- ホーム画面の API keys をクリックする
-
Default という名前の API キーを確認する
今回使用するのは、このデフォルトで用意されている API キーだ。
2. API を呼び出してデータを取得する
事前準備
環境のセットアップ
環境について説明しておく。
Python バージョン 3.13.1
を使用しており、venv
で作成した仮想環境内で作業する。
python -m venv .venv
source .venv/bin/activate
API リクエストに requests
、結果を整形して表示するために pandas
を利用する。
pip install requests pandas
また、先ほど確認した OpenWeather の API キーを環境変数に入れておく
export API_KEY=<your-api-key>
今回用いるスクリプトの流れは次の通りだ。
- ユーザー入力として「地名」を受け取る
- 地名を緯度経度に変換する
- 気象 API を呼び出す
- 結果を確認する
ヘルパーモジュールを作成する
気象データの取得に使用するヘルパーモジュールを作成しておく。
Geocoding API
まずは Geocoding API を呼び出す処理だ。これも OpenWeather API の一つだ。
これを使用して、ユーザーから受け取った地名を緯度経度に変換する。後で出てくる気象データ用の API で、どの地点の天気を取得するかを指定するために使用する。
Built-in geo-coding を使用する方が簡単だが廃止されているため、今回は正規の方法を採用した。
Geocoding API を用いて関数のコードスニペットを以下に示す。
def get_coordinates_by_city_name(city_name):
"""Converting a city name to geographical coordinates."""
url = f"{BASE_URL}/{GEO_URL}?q={city_name}&appid={API_KEY}&limit=1"
response = requests.get(url, timeout=1)
data = response.json()
if response.status_code != 200 or not data:
raise Exception(f"City not found: {data if not data else data["message"]}")
else:
return data[0]["lat"], data[0]["lon"]
日付フォーマット
後で表示用に使うので。以下のような感じ。
def format_datetime(dt_value, format_string):
"""Convert a UNIX timestamp to a formatted date-time string."""
return datetime.fromtimestamp(
dt_value, tz=ZoneInfo("Asia/Tokyo")
).strftime(format_string)
上記をヘルパーにまとめたコード。
"""OpenWeather API helper"""
import os
from datetime import datetime
from zoneinfo import ZoneInfo
import requests
API_KEY = os.environ.get("API_KEY")
BASE_URL = "http://api.openweathermap.org"
GEO_URL = "/geo/1.0/direct"
def get_coordinates_by_city_name(city_name):
"""Converting a city name to geographical coordinates."""
url = f"{BASE_URL}/{GEO_URL}?q={city_name}&appid={API_KEY}&limit=1"
response = requests.get(url, timeout=1)
data = response.json()
if response.status_code != 200 or not data:
raise Exception(f"City not found: {data if not data else data["message"]}")
else:
return data[0]["lat"], data[0]["lon"]
def format_datetime(dt_value, format_string):
"""Convert a UNIX timestamp to a formatted date-time string."""
return datetime.fromtimestamp(
dt_value, tz=ZoneInfo("Asia/Tokyo")
).strftime(format_string)
if __name__ == "__main__":
city_name_input = input("Enter city name: ")
lat, lon = get_coordinates_by_city_name(city_name_input)
print(f"\n(Latitude, Longitude) = ({lat}, {lon})")
実行してみる。
python geo_coding_sample.py
Enter city name: tokyo
(Latitude, Longitude) = (35.6828387, 139.7594549)
準備が終わったところで、OpenWeather API を呼び出してみる。
Current weather data
Current weather data を使用すると、現在の天気や気温を取得できる。
ここでは、以下のコードで
- 天気
- 気温
- 湿度
を表示してみた。
"""Featch current weather by city."""
import requests
from pandas import DataFrame
from open_weather_helper import (
API_KEY,
BASE_URL,
get_coordinates_by_city_name,
format_datetime,
)
WEATHER_URL = "/data/2.5/weather"
if __name__ == "__main__":
city_name = input("Enter city name: ")
lat, lon = get_coordinates_by_city_name(city_name)
url = f"{BASE_URL}/{WEATHER_URL}?lat={lat}&lon={lon}&appid={API_KEY}&units=metric"
response = requests.get(url, timeout=1)
data = response.json()
if response.status_code == 200:
print("\n==============================================")
print(f"Current weather data in {city_name}")
print("==============================================", end="\n\n")
display_data = [
["Date/Time (JST)", format_datetime(data["dt"], "%Y-%m-%d %H:%M")],
["Weather", data['weather'][0]['description']],
["Temperature", f"{data['main']['temp']}°C"],
["Humidity", f"{data['main']['humidity']}%"],
]
print(
DataFrame(display_data).to_string(index=False, header=False)
)
else:
print(f"City not found: {data['message']}")
実行結果
python fetch_current_weather_by_city.py
Enter city name: tokyo
==============================================
Current weather data in tokyo
==============================================
Date/Time (JST) 2024-12-21 23:17
Weather clear sky
Temperature 10.46°C
Humidity 65%
5 day weather forecast
5 day weather forecast を使うと、直近5日間の3時間ごとの天気を取得できる。
データをいくつ取得するかは cnt
パラメータで指定できる。今回は24時間分取得する(cnt=9
)。
"""Featch current weather by city."""
import requests
from pandas import DataFrame
from open_weather_helper import (
API_KEY,
BASE_URL,
get_coordinates_by_city_name,
format_datetime,
)
FORECAST_URL = "/data/2.5/forecast"
if __name__ == "__main__":
city_name = input("Enter city name: ")
lat, lon = get_coordinates_by_city_name(city_name)
endpoint = f"{BASE_URL}/{FORECAST_URL}"
url = f"{endpoint}?lat={lat}&lon={lon}&appid={API_KEY}&units=metric&cnt=9"
response = requests.get(url, timeout=1)
data = response.json()
if response.status_code == 200:
print("\n==============================================")
print(f"24 hours forecast in {city_name}")
print("==============================================", end="\n\n")
display_data = []
for e in data["list"]:
display_data.append([
format_datetime(e["dt"], "%Y-%m-%d %H:%M"),
e['weather'][0]['description'],
f"{e['main']['temp']}°C",
f"{e['main']['humidity']}%",
f"{e['pop'] * 100}%"
])
print(
DataFrame(
display_data,
columns=[
"Date/Time (JST)",
"Weather",
"Temperature",
"Humidity",
"Precipitation"
]
).to_string(index=False)
)
else:
print(f"City not found: {data['message']}")
実行結果
python fetch_forecast_by_city.py
Enter city name: tokyo
==============================================
24 hours forecast in tokyo
==============================================
Date/Time (JST) Weather Temperature Humidity Precipitation
2024-12-22 00:00 clear sky 10.24°C 69% 0%
2024-12-22 03:00 clear sky 10.01°C 59% 0%
2024-12-22 06:00 clear sky 8.8°C 49% 0%
2024-12-22 09:00 clear sky 8.43°C 35% 0%
2024-12-22 12:00 clear sky 9.17°C 29% 0%
2024-12-22 15:00 few clouds 9.11°C 21% 0%
2024-12-22 18:00 clear sky 6.41°C 28% 0%
2024-12-22 21:00 clear sky 5.49°C 31% 0%
2024-12-23 00:00 clear sky 5.03°C 32% 0%
以上だ
今回使用したもの以外にも、次のようなデータが取れる。
- 風向・風速
- 視程
- 日の出時刻
- 日の入り時刻
一度じっくり見てみるのも良いかもしれない。