kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: add weather api service
rodzic
19cb765db1
commit
64afe1d441
|
@ -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,
|
||||
|
|
|
@ -5,3 +5,4 @@ export * from './novu'
|
|||
export * from './serpapi'
|
||||
export * from './slack'
|
||||
export * from './twilio-conversation'
|
||||
export * from './weather'
|
||||
|
|
|
@ -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>()
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
})
|
Ładowanie…
Reference in New Issue