关于 connector-weatherapi
由 OpenAPI 规范生成的 WeatherAPI.com Motoko 绑定,提供九种只读 GET 操作,适用于需要当前、预报、历史、海洋或相关天气数据的应用。
主要功能
- 01九种 WeatherAPI.com GET 操作
- 02当前天气与天气预报
- 03历史和未来天气接口
- 04海洋与天文数据
- 05时区、IP 查询和自动补全
适用场景
- 01在 canister 中读取当前天气
- 02获取天气预报或历史天气
- 03查询时区或 IP 位置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ caffeinelabs/ skills --skill connector-weatherapi安装后在 Claude Code 中输入/connector-weatherapi确认已加载。
详细介绍
使用 weatherapi-client 获取天气数据
基于 WeatherAPI.com 的 OpenAPI 规范生成的 Motoko 绑定。全部九个操作都位于同一个模块 Apis/APIsApi 中,且全部为只读 GET 请求。
后端
一个 canister,用于读取当前气温和未来三天的最高气温序列。默认使用非复制模式,因此只需提供密钥:
import { realtimeWeather; forecastWeather } "mo:weatherapi-client/Apis/APIsApi";
import { type Config; defaultConfig } "mo:weatherapi-client/Config";
import Array "mo:core/Array"; // in scope so `days.map(…)` dot notation resolves
actor {
// The key is a query-string credential. Hold it in a stable variable set by
// an admin call; never hard-code it in source.
func config(apiKey : Text) : Config = { defaultConfig with auth = ?#apiKey apiKey };
// `q` is any WeatherAPI location query: "Zurich", "47.37,8.55", a postcode,
// an IATA code, or "auto:ip".
public func currentTempC(apiKey : Text, q : Text) : async ?Float {
let res = await* realtimeWeather(config apiKey, q, "");
do ? { res.current!.temp_c! };
};
// Daily maxima for the next three days.
public func maxTempsC(apiKey : Text, q : Text) : async [?Float] {
let res = await* forecastWeather(config apiKey, q, #_3_, "", 0, 0, "", "no", "no", 0);
let ?forecast = res.forecast else return [];
let ?days = forecast.forecastday else return [];
days.map(func(d) = do ? { d.day!.maxtemp_c! });
};
}
九个操作
| 函数 | 端点 | 返回值 |
|---|---|---|
realtimeWeather(cfg, q, lang) | /current.json | RealtimeWeather200Response |
forecastWeather(cfg, q, days, dt, unixdt, hour, lang, alerts, aqi, tp) | /forecast.json | ForecastWeather200Response |
historyWeather(cfg, q, dt, unixdt, endDt, unixendDt, hour, lang) | /history.json | FutureWeather200Response |
futureWeather(cfg, q, dt, lang) | /future.json | FutureWeather200Response |
marineWeather(cfg, q, days, dt, unixdt, hour, lang) | /marine.json | MarineWeather200Response |
astronomy(cfg, q, dt) | /astronomy.json | Astronomy200Response |
timeZone(cfg, q) | /timezone.json | Location |
ipLookup(cfg, q) | /ip.json | Ip |
searchAutocompleteWeather(cfg, q) | /search.json | [Search] |
days 是枚举值,不是数字:ForecastWeatherDaysParameter 的取值为 #_1_ … #_14_,而 MarineWeatherDaysParameter 的取值为 #_1_ … #_7_(下划线是生成器转义数字枚举值的方式——应写作 #_3_,而不是 #_3 或 3)。
API 密钥设置
- 在 weatherapi.com 注册——免费套餐涵盖当前天气、3 天预报、天文、时区、搜索和 IP 查询。历史、未来、海洋和 14 天预报需要付费套餐,使用免费密钥时会返回 403。
- 从控制面板复制密钥,并以
auth = ?#apiKey key传入。 - 客户端会将密钥附加为
?key=…(WeatherAPI 不使用Authorization标头),因此密钥会出现在请求 URL 中。请将密钥保存在仅限管理员调用写入的稳定变量中,且不要记录构造出的 URL。
调用默认使用非复制模式
此软件包在 defaultConfig 中设置了 is_replicated = ?false,这在此处是正确性要求,而不只是节省成本。每个响应都带有单次请求的时钟信息——Location.localtime / localtime_epoch、Current.last_updated / last_updated_epoch——这些值每秒都会变化。复制出站调用会让每个子网节点各自发出请求,并要求响应正文逐位相同,因此这些字段会导致大多数调用无法达成共识,还会消耗约 13 倍的 cycles。你无需自行设置;默认值就是正确配置。
只有在同时使用会剥除易变字段的 transform 时,才应覆盖为 is_replicated = ?true。
所有字段都是可选的
WeatherAPI 没有将任何响应字段标记为必填,因此生成的模型字段全部可选:RealtimeWeather200Response.current : ?Current、Current.temp_c : ?Float 等。可使用 do ? 块访问嵌套字段(do ? { res.current!.temp_c! }),而不必嵌套使用 switch;并根据调用方的需求处理字段缺失的情况——对于套餐不包含的字段,API 会将其省略(例如未设置 aqi=yes 参数时的 air_quality)。
空字符串和零表示“省略”
可选查询参数的值若为 "" 或 0,就会被省略,因为 WeatherAPI 会拒绝空的 lang= 和数值为零的参数。因此,为 lang、dt、alerts、aqi 传入 "",为 unixdt、tp 传入 0,就表示“未提供”——没有 ?Text 参数可留空。
有一点需要注意:hour = 0 不会选择午夜,而是完全省略 hour 筛选条件,因此你会获得当天完整的逐小时数组。如果需要筛选出 00:00,请自行筛选返回的 hour : ?[ForecastForecastdayInnerHourInner]。
错误
对于非 2xx 响应和解码失败,会 throw Error.reject(…)。客户端生成时启用了 diagnostics,因此错误消息格式为
HTTP <status> body[<n>B]=<前 100 个字符>: <原因>——无需额外日志,就足以区分 401(密钥无效)、403(端点不在你的套餐范围内)和 400(无法解析 q)。使用 try/catch 捕获,并显示
Error.message(err)。