π³ Cookbook: Integrating External APIs¶
The real power of agents comes from their ability to interact with the world. This guide shows you how to wrap any external REST API (Stripe, GitHub, Weather, etc.) into a type-safe tool your agent can use.
π― Goal¶
Build a "Weather Tool" that allows an agent to fetch real-time data from an external API.
ποΈ Phase 1: Define the Tool¶
We use the @tool decorator. Important: Type hints matter! The agent uses them to understand what arguments to send.
1. Requirements¶
We typically use httpx for async requests.
2. Implementation¶
In app/tools/weather.py:
import httpx
from app.tools.base import tool
API_KEY = "your_api_key" # Load this from os.getenv() in production!
@tool(name="get_current_weather", category="info")
async def get_weather(city: str, country_code: str = "US") -> dict:
"""
Fetches the current weather for a specific location.
Args:
city: The name of the city (e.g., 'London', 'New York')
country_code: The 2-letter ISO country code (default: US)
"""
url = f"https://api.weatherapi.com/v1/current.json"
params = {
"key": API_KEY,
"q": f"{city},{country_code}"
}
async with httpx.AsyncClient() as client:
resp = await client.get(url, params=params)
resp.raise_for_status()
data = resp.json()
# Tip: Return only what the LLM needs to save context window space
return {
"condition": data['current']['condition']['text'],
"temp_c": data['current']['temp_c'],
"humidity": data['current']['humidity']
}
π Phase 2: Registering the Tool¶
The Traylinx template has a specialized registry system. You usually just need to import your tool logic in app/tools/__init__.py to ensure the decorator runs.
π§ͺ Phase 3: Testing Without an Agent¶
Before confusing an LLM with it, test your tool directly in Python to ensure the API connection works.
import asyncio
from app.tools.weather import get_weather
result = asyncio.run(get_weather("Paris", "FR"))
print(result)
# {'condition': 'Sunny', 'temp_c': 24.0, 'humidity': 45}
π€ Phase 4: Using It¶
Now, when you run your agent, it "sees" this tool in its system prompt definition automatically.
Reasoning Trace:
1. Thought: User is asking about weather-dependent clothing. I need current weather for Paris.
2. Action: get_weather(city="Paris", country_code="FR")
3. Observation: {'condition': 'Light rain', ...}
4. Answer: "Yes, it is currently raining lightly in Paris, so a raincoat would be a good idea."
π‘ Pro Tip: Error Handling¶
External APIs fail. Your tool should be robust so the agent doesn't crash.
try:
resp.raise_for_status()
except httpx.HTTPStatusError as e:
# Return the error as a string so the agent knows what happened
return f"Error fetching weather: target API returned {e.response.status_code}"
If the agent sees this error string, it might say: "I'm sorry, I couldn't check the weather right now due to a connection issue."βsmart!