init: init proj
This commit is contained in:
55
weather_api.py
Normal file
55
weather_api.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/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])
|
||||
Reference in New Issue
Block a user