> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensorlake.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Weather Agent

> Build a conversational weather agent using Tensorlake and OpenWeatherMap.

<Card title="View Source Code" icon="github" href="https://github.com/tensorlakeai/cookbooks/tree/main/weather-app">
  Check out the full source code for this example on GitHub.
</Card>

This tutorial demonstrates how to build a **Weather Agent** using Tensorlake and the OpenWeatherMap API. This agent can fetch real-time weather data for any location and answer natural language questions about it.

## Overview

The Weather Agent consists of:

1. **Weather Tool**: A Python function that calls the OpenWeatherMap API.
2. **Weather Agent**: An LLM-powered agent that understands user queries (e.g., "Will I need an umbrella in London today?") and decides when to call the weather tool.

## Prerequisites

* **Python 3.11+**
* **Tensorlake Account** and CLI installed.
* **OpenWeatherMap API Key**
* **Anthropic API Key**

## Project Structure

```text theme={null}
weather-app/
├── agent.py            # Weather Agent logic and API calls
├── tensorlake_app.py   # Main application entry point
├── config.py           # Configuration and prompts
└── requirements.txt
```

## Implementation (`agent.py`)

Here is the core logic for the Weather Agent.

```python theme={null}
import os
import requests
from typing import List

from anthropic import Anthropic
from pydantic import BaseModel, Field
from tensorlake import Agent, Assistant, Function, FunctionTool, User, configure_logging, get_logger, Image, function

# Define the runtime environment
image = Image(name="weather-agent").run("pip install anthropic requests tensorlake pydantic")

class GetCurrentWeatherInput(BaseModel):
    location: str = Field(..., description="The city and country, e.g., 'London, UK' or 'New York, USA'.")

@function(image=image, secrets=["OPENWEATHER_API_KEY"])
def get_current_weather(location: str) -> str:
    """
    Fetches current weather data for a specified location using the OpenWeatherMap API.
    """
    api_key = os.getenv("OPENWEATHER_API_KEY")
    base_url = "http://api.openweathermap.org/data/2.5/weather"
    params = {
        "q": location,
        "appid": api_key,
        "units": "metric",
    }
    
    response = requests.get(base_url, params=params)
    if response.status_code == 200:
        data = response.json()
        desc = data['weather'][0]['description']
        temp = data['main']['temp']
        return f"Weather in {location}: {desc}, {temp}°C"
    else:
        return f"Could not fetch weather for {location}."

class WeatherAgent(Agent):
    def __init__(self, name: str, system_prompt: str, tools: List[FunctionTool]):
        super().__init__(name, system_prompt, tools)
        self.anthropic_client = Anthropic()

    def call(self, user_message: User, files: List) -> Assistant:
        messages = [{"role": "user", "content": user_message.content}]
        
        response = self.anthropic_client.messages.create(
            model="claude-3-opus-20240229",
            max_tokens=1024,
            system=self.system_prompt,
            messages=messages,
            tools=self.tools,
        )

        if response.stop_reason == "tool_use":
            tool_use = next(block for block in response.content if block.type == "tool_use")
            if tool_use.name == "get_current_weather":
                location = tool_use.input["location"]
                weather_info = get_current_weather(location)
                
                messages.append({"role": "assistant", "content": response.content})
                messages.append({
                    "role": "user",
                    "content": [
                        {
                            "type": "tool_result",
                            "tool_use_id": tool_use.id,
                            "content": weather_info
                        }
                    ]
                })
                
                final_response = self.anthropic_client.messages.create(
                    model="claude-3-opus-20240229",
                    max_tokens=1024,
                    system=self.system_prompt,
                    messages=messages,
                    tools=self.tools,
                )
                return Assistant(content=final_response.content)

        return Assistant(content=response.content)

# Initialize the agent
weather_agent = WeatherAgent(
    name="weather_agent",
    system_prompt="You are a helpful weather assistant.",
    tools=[
        FunctionTool(
            name="get_current_weather",
            description="Get current weather for a location.",
            function=Function(
                name="get_current_weather",
                description="Get current weather for a location.",
                input_schema=GetCurrentWeatherInput.model_json_schema(),
            ),
        )
    ]
)
```

## Running Locally

1. Set up environment variables:
   ```bash theme={null}
   export OPENWEATHER_API_KEY=your_openweather_key
   export ANTHROPIC_API_KEY=your_anthropic_key
   ```

2. Run the agent:
   ```bash theme={null}
   python agent.py
   ```

## Deploying to Tensorlake

Deploy your weather agent to the cloud.

```bash theme={null}
tl secrets set OPENWEATHER_API_KEY=your_openweather_key
tl secrets set ANTHROPIC_API_KEY=your_anthropic_key
tl app deploy agent.py
```

Your weather agent is now live and ready to answer queries!
