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}¤t_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.