feat: add weather api service

old-agentic-v1^2
Travis Fischer 2023-06-13 22:31:48 -07:00
rodzic 19cb765db1
commit 64afe1d441
4 zmienionych plików z 161 dodań i 0 usunięć

Wyświetl plik

@ -8,6 +8,7 @@ import { isValidTaskIdentifier } from '@/utils'
// TODO: this needs work + testing
// TODO: move to isolated module
// TODO compare with https://gist.github.com/rileytomasek/4811b5fdd9c82c4730c191317ea76411
export async function getNumTokensForChatMessages({
messages,
model,

Wyświetl plik

@ -5,3 +5,4 @@ export * from './novu'
export * from './serpapi'
export * from './slack'
export * from './twilio-conversation'
export * from './weather'

Wyświetl plik

@ -0,0 +1,125 @@
import defaultKy from 'ky'
export const WEATHER_API_BASE_URL = 'http://api.weatherapi.com/v1'
interface CurrentWeatherResponse {
current: CurrentWeather
location: WeatherLocation
}
interface CurrentWeather {
cloud: number
condition: WeatherCondition
feelslike_c: number
feelslike_f: number
gust_kph: number
gust_mph: number
humidity: number
is_day: number
last_updated: string
last_updated_epoch: number
precip_in: number
precip_mm: number
pressure_in: number
pressure_mb: number
temp_c: number
temp_f: number
uv: number
vis_km: number
vis_miles: number
wind_degree: number
wind_dir: string
wind_kph: number
wind_mph: number
}
interface WeatherCondition {
code: number
icon: string
text: string
}
interface WeatherLocation {
country: string
lat: number
localtime: string
localtime_epoch: number
lon: number
name: string
region: string
tz_id: string
}
interface WeatherIPInfoResponse {
ip: string
type: string
continent_code: string
continent_name: string
country_code: string
country_name: string
is_eu: string
geoname_id: number
city: string
region: string
lat: number
lon: number
tz_id: string
localtime_epoch: number
localtime: string
}
export class WeatherClient {
api: typeof defaultKy
apiKey: string
apiBaseUrl: string
constructor({
apiKey = process.env.WEATHER_API_KEY,
apiBaseUrl = WEATHER_API_BASE_URL,
ky = defaultKy
}: {
apiKey?: string
apiBaseUrl?: string
ky?: typeof defaultKy
} = {}) {
if (!apiKey) {
throw new Error(`Error WeatherClient missing required "apiKey"`)
}
this.apiKey = apiKey
this.apiBaseUrl = apiBaseUrl
this.api = ky.extend({ prefixUrl: apiBaseUrl })
}
async getCurrentWeather(queryOrOptions: string | { q: string }) {
const options =
typeof queryOrOptions === 'string'
? { q: queryOrOptions }
: queryOrOptions
return this.api
.get('current.json', {
searchParams: {
key: this.apiKey,
...options
}
})
.json<CurrentWeatherResponse>()
}
async ipInfo(ipOrOptions: string | { q: string }) {
const options =
typeof ipOrOptions === 'string' ? { q: ipOrOptions } : ipOrOptions
return this.api
.get('ip.json', {
searchParams: {
key: this.apiKey,
...options
}
})
.json<WeatherIPInfoResponse>()
}
}

Wyświetl plik

@ -0,0 +1,34 @@
import test from 'ava'
import { WeatherClient } from '@/services'
import { ky } from '../_utils'
test('WeatherClient.getCurrentWeather', async (t) => {
if (!process.env.WEATHER_API_KEY) {
return t.pass()
}
t.timeout(2 * 60 * 1000)
const client = new WeatherClient({ ky })
const result = await client.getCurrentWeather('Seattle')
// console.log(result)
t.truthy(result.current)
t.truthy(result.location)
})
test('WeatherClient.ipInfo', async (t) => {
if (!process.env.WEATHER_API_KEY) {
return t.pass()
}
t.timeout(2 * 60 * 1000)
const client = new WeatherClient({ ky })
const res = await client.ipInfo('52.119.125.215')
t.truthy(res.ip)
t.truthy(res.city)
t.truthy(res.lat)
t.truthy(res.lon)
})