Skip to main content
Version: 2.6

Temperature by City

The weather-by-city reaktor (see operaide-apps/apps/op-demo-weather/src/WeatherByCity.reaktor.ts) turns a city name into latitude/longitude coordinates, calls Open-Meteo, and returns the current weather snapshot.

Reaktor implementation

import { z } from 'zod';
import { aktorFunction, registerReaktorDefinition } from '@operaide/aktor';
import { aktorLocation } from './aktorLocation';
import { aktorGetWeather } from './aktorGetWeather';

registerReaktorDefinition({
reaktorDefinitionId: 'weather-by-city',
label: 'Temperature by City',
description:
'Returns the Temperature of a given location: Gets the weather of a location via open-meteo.com. Takes a city as input',
createReaktor({ city }) {
const location = aktorLocation({ city });
const aktorWeatherLocation = aktorFunction('aktorWeatherLocation', { location }, ({ location }) => {
if (location.length === 0) {
throw new Error('Location not found');
}
return {
latitude: Number(location[0]?.lat ?? 0),
longitude: Number(location[0]?.lon ?? 0),
};
});
return aktorGetWeather({ location: aktorWeatherLocation });
},
inputSchema: z.object({
city: z.string().openapi({ example: 'Weinheim' }),
}),
outputSchema: z
.object({
current_weather: z
.object({
temperature: z.number(),
})
.partial(),
})
.partial(),
});

Supporting aktors

aktorLocation wraps the OpenStreetMap geocoder and normalises the response:

export const aktorLocation = createAktorFunctionAsync('aktorLocation', async ({ city, limit }) => {
const url = `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(city)}&format=json${limit ? `&limit=${limit}` : ''}`;
const response = await axios.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });
return PlacesZ.parse(response.data);
});

Once coordinates are known, aktorGetWeather queries Open-Meteo for current conditions:

export const aktorGetWeather = createAktorFunctionAsync('aktorGetWeather', async ({ location }) => {
const result = await axios.get(
`https://api.open-meteo.com/v1/forecast?latitude=${location.latitude}&longitude=${location.longitude}&current_weather=true`
);
return weatherZ.partial().parse(result.data);
});

Sample request

Use the bundled WeatherByCity.http file or issue the request manually:

POST http://localhost:8811/api/v1/aktor/weather-by-city/run
Content-Type: application/json

{
"city": "Weinheim"
}

The response includes the current_weather object returned by Open-Meteo, including the current temperature.