56 lines
2.3 KiB
Python
56 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
和风天气(QWeather)客户端 —— 实时天气 + 今日温区。
|
||
|
||
和风要求使用「用户专属 API Host」(控制台-设置查看 https://console.qweather.com/setting),
|
||
用 API Key 鉴权(请求头 X-QW-Api-Key);响应体 Gzip 压缩需手动解压,且返回 code 为字符串。
|
||
免费订阅额度足够墨水屏每日推送。HOST/KEY 通过环境变量配置,未配置时调用方回退占位。
|
||
|
||
接口(参考 https://dev.qweather.com/docs/api/):
|
||
- GET /v7/weather/now?location=经度,纬度 实时天气(now.text 中文天气 / now.temp 温度)
|
||
- GET /v7/weather/3d?location=经度,纬度 逐日预报,取 daily[0] 的今日 tempMin/tempMax
|
||
"""
|
||
import gzip
|
||
import json
|
||
import urllib.request
|
||
import urllib.error
|
||
|
||
import config
|
||
|
||
|
||
def _get(path):
|
||
if not config.QWEATHER_HOST or not config.QWEATHER_KEY:
|
||
raise RuntimeError("未配置 QWEATHER_HOST / QWEATHER_KEY")
|
||
host = config.QWEATHER_HOST.rstrip("/")
|
||
if not host.startswith("http"):
|
||
host = "https://" + host
|
||
headers = {"X-QW-Api-Key": config.QWEATHER_KEY, "Accept-Encoding": "gzip"}
|
||
req = urllib.request.Request(host + path, headers=headers, method="GET")
|
||
try:
|
||
with urllib.request.urlopen(req, timeout=30) as resp:
|
||
raw = resp.read()
|
||
except urllib.error.HTTPError as e:
|
||
raise RuntimeError(f"HTTP {e.code}: {e.read().decode('utf-8', 'ignore')[:200]}") from e
|
||
if raw[:2] == b"\x1f\x8b": # gzip magic number,和风默认压缩
|
||
raw = gzip.decompress(raw)
|
||
data = json.loads(raw.decode("utf-8"))
|
||
if str(data.get("code")) != "200": # 和风 code 为字符串
|
||
raise RuntimeError(f"{path} 返回 code={data.get('code')}")
|
||
return data
|
||
|
||
|
||
def get_now() -> dict:
|
||
"""实时天气:now.text(中文天气)/ now.temp(摄氏温度)。"""
|
||
return _get(f"/v7/weather/now?location={config.WEATHER_LOCATION}")["now"]
|
||
|
||
|
||
def get_today() -> dict:
|
||
"""今日逐日预报:daily[0] 含 tempMin / tempMax。"""
|
||
return _get(f"/v7/weather/3d?location={config.WEATHER_LOCATION}")["daily"][0]
|
||
|
||
|
||
if __name__ == "__main__":
|
||
print("now: ", json.dumps(get_now(), ensure_ascii=False)[:300])
|
||
print("today:", json.dumps(get_today(), ensure_ascii=False)[:300])
|