# Weather Report Workflow div strong 🔨 In Development — This section is still being developed and may change. This comprehensive example demonstrates how to build an intelligent weather reporting assistant using Freddy's function calling capabilities. ## Overview We'll create a workflow that: 1. Accepts natural language weather queries 2. Extracts location and date information 3. Calls external weather APIs 4. Formats and presents the weather data 5. Handles errors and edge cases ## Prerequisites - Freddy API account with function calling enabled - Weather API key (we'll use OpenWeatherMap in this example) - Basic understanding of Python/Node.js ## Step 1: Define the Weather Function First, let's create a function that fetches weather data: ```python import requests import json from datetime import datetime def get_weather_data(location: str, date: str = None) -> dict: """ Get weather data for a specific location and date. Args: location: City name or coordinates (e.g., "New York" or "40.7128,-74.0060") date: Date in YYYY-MM-DD format (optional, defaults to current date) Returns: Dictionary containing weather information """ api_key = "YOUR_OPENWEATHERMAP_API_KEY" # Store in environment variables try: # Geocoding API to get coordinates geo_url = f"http://api.openweathermap.org/geo/1.0/direct?q={location}&limit=1&appid={api_key}" geo_response = requests.get(geo_url) geo_data = geo_response.json() if not geo_data: return {"error": f"Location '{location}' not found"} lat = geo_data[0]['lat'] lon = geo_data[0]['lon'] # Current weather API weather_url = f"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={api_key}&units=metric" weather_response = requests.get(weather_url) weather_data = weather_response.json() # Format the response return { "location": geo_data[0]['name'], "country": geo_data[0]['country'], "temperature": weather_data['main']['temp'], "feels_like": weather_data['main']['feels_like'], "humidity": weather_data['main']['humidity'], "description": weather_data['weather'][0]['description'], "wind_speed": weather_data['wind']['speed'], "timestamp": datetime.now().isoformat() } except Exception as e: return {"error": f"Failed to fetch weather data: {str(e)}"} ``` ```javascript const axios = require('axios'); async function getWeatherData(location, date = null) { const apiKey = process.env.OPENWEATHERMAP_API_KEY; try { // Geocoding API to get coordinates const geoUrl = `http://api.openweathermap.org/geo/1.0/direct?q=${encodeURIComponent(location)}&limit=1&appid=${apiKey}`; const geoResponse = await axios.get(geoUrl); const geoData = geoResponse.data; if (!geoData || geoData.length === 0) { return { error: `Location '${location}' not found` }; } const { lat, lon } = geoData[0]; // Current weather API const weatherUrl = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}&units=metric`; const weatherResponse = await axios.get(weatherUrl); const weatherData = weatherResponse.data; // Format the response return { location: geoData[0].name, country: geoData[0].country, temperature: weatherData.main.temp, feels_like: weatherData.main.feels_like, humidity: weatherData.main.humidity, description: weatherData.weather[0].description, wind_speed: weatherData.wind.speed, timestamp: new Date().toISOString() }; } catch (error) { return { error: `Failed to fetch weather data: ${error.message}` }; } } ``` ## Step 2: Create the Weather Assistant Now let's create a Freddy assistant that uses this weather function: ```python import os from freddy import Freddy # Initialize Freddy client freddy = Freddy(api_key=os.getenv("FREDDY_API_KEY")) # Create the assistant assistant = freddy.assistants.create( name="Weather Assistant", instructions="""You are a helpful weather assistant. When users ask about weather: 1. Extract the location from their message 2. Determine if they want current weather or a forecast 3. Use the get_weather_data function to fetch information 4. Provide a clear, formatted response with temperature, conditions, and other relevant details 5. If the location is unclear, ask for clarification 6. Handle errors gracefully and provide helpful error messages Always be friendly and provide context-appropriate responses.""", model="gpt-4", tools=[ { "type": "function", "function": { "name": "get_weather_data", "description": "Get current weather information for a specified location", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city name or coordinates to get weather for (e.g., 'New York' or '40.7128,-74.0060')" }, "date": { "type": "string", "description": "Date in YYYY-MM-DD format (optional, defaults to current date)" } }, "required": ["location"] } } } ] ) ``` ## Step 3: Create a Weather Thread ```python # Create a thread for the weather conversation thread = freddy.threads.create() # Send a message asking for weather message = freddy.threads.messages.create( thread_id=thread.id, role="user", content="What's the weather like in Tokyo today?" ) # Run the assistant run = freddy.threads.runs.create( thread_id=thread.id, assistant_id=assistant.id ) # Wait for completion and get the response while run.status not in ["completed", "failed", "cancelled"]: run = freddy.threads.runs.retrieve(thread_id=thread.id, run_id=run.id) if run.status == "completed": # Get the latest message messages = freddy.threads.messages.list(thread_id=thread.id) latest_message = messages.data[-1] print("Weather Assistant:", latest_message.content[0].text.value) else: print(f"Run failed with status: {run.status}") ``` ## Step 4: Handle the Response The assistant will automatically call your weather function and provide a natural language response: ``` Weather Assistant: The current weather in Tokyo shows it's 22°C with scattered clouds. It feels like 25°C, and there's 65% humidity with a light wind of 3.2 m/s from the southeast. Overall, it's a pleasant day for outdoor activities! ``` ## Advanced Features ### Adding Weather Forecasting Extend the function to support forecasts: ```python def get_weather_forecast(location: str, days: int = 3) -> dict: """Get weather forecast for the next few days.""" # Implementation for multi-day forecast pass ``` ### Location Detection Enhance the assistant to detect locations from context: ```python # In your assistant instructions """ If no location is specified, ask the user for clarification. If the user mentions 'current location' or 'here', ask them to provide their location. Remember the user's location for follow-up questions. """ ``` ### Error Handling ```python # In your weather function def get_weather_data(location: str, date: str = None) -> dict: try: # ... implementation ... except requests.exceptions.RequestException: return {"error": "Unable to connect to weather service. Please try again later."} except KeyError: return {"error": "Invalid response from weather service."} except Exception as e: return {"error": "An unexpected error occurred while fetching weather data."} ``` ## Testing the Workflow 1. Create the assistant with your weather function 2. Start a conversation: "How's the weather in London?" 3. Try different queries: "What's the temperature in NYC?", "Will it rain tomorrow in Paris?" 4. Test error cases: "Weather in Atlantis", "Current conditions in" ## Best Practices 1. **Environment Variables**: Never hardcode API keys 2. **Error Handling**: Provide meaningful error messages 3. **Rate Limiting**: Respect API rate limits 4. **Caching**: Cache weather data to avoid unnecessary API calls 5. **Units**: Allow users to specify preferred units (°C/°F) 6. **Localization**: Support multiple languages and regions ## Next Steps - Add more weather APIs for redundancy - Implement weather alerts and notifications - Add historical weather data - Create weather-based recommendations - Integrate with calendar for event planning ## Troubleshooting **Function not being called**: Check that the function name and parameters match exactly in your assistant configuration. **API errors**: Verify your weather API key is valid and has sufficient quota. **Location not found**: The geocoding service might not recognize the location format. Try major city names first. For more help, check the [Function Calling Guide](/docs/documentation/core-concepts/function-calling) or [API Reference](/docs/api-reference/introduction).