mcpField
C
connector-weatherapi

connector-weatherapi

github.com/caffeinelabs开发27.8k 次安装1 周前更新
代码仓库

关于 connector-weatherapi

由 OpenAPI 规范生成的 WeatherAPI.com Motoko 绑定,提供九种只读 GET 操作,适用于需要当前、预报、历史、海洋或相关天气数据的应用。

主要功能

  1. 01九种 WeatherAPI.com GET 操作
  2. 02当前天气与天气预报
  3. 03历史和未来天气接口
  4. 04海洋与天文数据
  5. 05时区、IP 查询和自动补全

适用场景

  1. 01在 canister 中读取当前天气
  2. 02获取天气预报或历史天气
  3. 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.jsonRealtimeWeather200Response
forecastWeather(cfg, q, days, dt, unixdt, hour, lang, alerts, aqi, tp)/forecast.jsonForecastWeather200Response
historyWeather(cfg, q, dt, unixdt, endDt, unixendDt, hour, lang)/history.jsonFutureWeather200Response
futureWeather(cfg, q, dt, lang)/future.jsonFutureWeather200Response
marineWeather(cfg, q, days, dt, unixdt, hour, lang)/marine.jsonMarineWeather200Response
astronomy(cfg, q, dt)/astronomy.jsonAstronomy200Response
timeZone(cfg, q)/timezone.jsonLocation
ipLookup(cfg, q)/ip.jsonIp
searchAutocompleteWeather(cfg, q)/search.json[Search]

days 是枚举值,不是数字:ForecastWeatherDaysParameter 的取值为 #_1_ … #_14_,而 MarineWeatherDaysParameter 的取值为 #_1_ … #_7_(下划线是生成器转义数字枚举值的方式——应写作 #_3_,而不是 #_3 或 3)。

API 密钥设置

  1. 在 weatherapi.com 注册——免费套餐涵盖当前天气、3 天预报、天文、时区、搜索和 IP 查询。历史、未来、海洋和 14 天预报需要付费套餐,使用免费密钥时会返回 403。
  2. 从控制面板复制密钥,并以 auth = ?#apiKey key 传入。
  3. 客户端会将密钥附加为 ?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)。

评论

支持 Markdown