Python Tool Calling Examples

Clean, production-ready examples for using tool calling with Captain API in Python.

Basic Calculator Tool

1from openai import OpenAI
2import json
3
4client = OpenAI(
5 base_url="https://api.runcaptain.com/v1",
6 api_key="your_api_key",
7 default_headers={"X-Organization-ID": "your_org_id"}
8)
9
10def calculate(operation, a, b):
11 operations = {
12 "add": lambda x, y: x + y,
13 "subtract": lambda x, y: x - y,
14 "multiply": lambda x, y: x * y,
15 "divide": lambda x, y: x / y if y != 0 else None
16 }
17 return operations[operation](a, b)
18
19tools = [{
20 "type": "function",
21 "function": {
22 "name": "calculate",
23 "description": "Perform arithmetic calculations",
24 "parameters": {
25 "type": "object",
26 "properties": {
27 "operation": {
28 "type": "string",
29 "enum": ["add", "subtract", "multiply", "divide"]
30 },
31 "a": {"type": "number"},
32 "b": {"type": "number"}
33 },
34 "required": ["operation", "a", "b"]
35 },
36 "strict": True
37 }
38}]
39
40response = client.chat.completions.create(
41 model="captain-voyager-latest",
42 messages=[
43 {"role": "user", "content": "What is 156 times 243?"}
44 ],
45 tools=tools
46)
47
48if response.choices[0].finish_reason == "tool_calls":
49 tool_call = response.choices[0].message.tool_calls[0]
50 args = json.loads(tool_call.function.arguments)
51 result = calculate(args["operation"], args["a"], args["b"])
52 print(f"Result: {result}")

Weather API Tool

1from openai import OpenAI
2import json
3import requests
4
5client = OpenAI(
6 base_url="https://api.runcaptain.com/v1",
7 api_key="your_api_key",
8 default_headers={"X-Organization-ID": "your_org_id"}
9)
10
11def get_weather(location, unit="celsius"):
12 api_key = "your_weather_api_key"
13 url = f"https://api.weatherapi.com/v1/current.json"
14 params = {"key": api_key, "q": location}
15
16 response = requests.get(url, params=params)
17 data = response.json()
18
19 temp = data["current"]["temp_c"] if unit == "celsius" else data["current"]["temp_f"]
20
21 return {
22 "location": location,
23 "temperature": temp,
24 "unit": unit,
25 "condition": data["current"]["condition"]["text"]
26 }
27
28tools = [{
29 "type": "function",
30 "function": {
31 "name": "get_weather",
32 "description": "Get current weather for a location",
33 "parameters": {
34 "type": "object",
35 "properties": {
36 "location": {
37 "type": "string",
38 "description": "City name"
39 },
40 "unit": {
41 "type": "string",
42 "enum": ["celsius", "fahrenheit"],
43 "description": "Temperature unit"
44 }
45 },
46 "required": ["location"]
47 },
48 "strict": True
49 }
50}]
51
52response = client.chat.completions.create(
53 model="captain-voyager-latest",
54 messages=[
55 {"role": "user", "content": "What's the weather in Tokyo?"}
56 ],
57 tools=tools
58)
59
60if response.choices[0].finish_reason == "tool_calls":
61 tool_call = response.choices[0].message.tool_calls[0]
62 args = json.loads(tool_call.function.arguments)
63 weather = get_weather(args["location"], args.get("unit", "celsius"))
64 print(f"Weather in {weather['location']}: {weather['temperature']}°{weather['unit'][0].upper()}, {weather['condition']}")

Database Query Tool

1from openai import OpenAI
2import json
3import sqlite3
4
5client = OpenAI(
6 base_url="https://api.runcaptain.com/v1",
7 api_key="your_api_key",
8 default_headers={"X-Organization-ID": "your_org_id"}
9)
10
11def query_database(customer_id):
12 conn = sqlite3.connect('customers.db')
13 cursor = conn.cursor()
14
15 cursor.execute(
16 "SELECT name, email, phone FROM customers WHERE id = ?",
17 (customer_id,)
18 )
19
20 result = cursor.fetchone()
21 conn.close()
22
23 if result:
24 return {
25 "name": result[0],
26 "email": result[1],
27 "phone": result[2]
28 }
29 return {"error": "Customer not found"}
30
31tools = [{
32 "type": "function",
33 "function": {
34 "name": "query_database",
35 "description": "Look up customer information by ID",
36 "parameters": {
37 "type": "object",
38 "properties": {
39 "customer_id": {
40 "type": "string",
41 "description": "Customer ID to look up"
42 }
43 },
44 "required": ["customer_id"]
45 },
46 "strict": True
47 }
48}]
49
50response = client.chat.completions.create(
51 model="captain-voyager-latest",
52 messages=[
53 {"role": "user", "content": "Get contact info for customer CUST-12345"}
54 ],
55 tools=tools
56)
57
58if response.choices[0].finish_reason == "tool_calls":
59 tool_call = response.choices[0].message.tool_calls[0]
60 args = json.loads(tool_call.function.arguments)
61 customer_info = query_database(args["customer_id"])
62
63 if "error" not in customer_info:
64 print(f"Customer: {customer_info['name']}")
65 print(f"Email: {customer_info['email']}")
66 print(f"Phone: {customer_info['phone']}")

Tool Calling with Large Context

1from openai import OpenAI
2import json
3
4client = OpenAI(
5 base_url="https://api.runcaptain.com/v1",
6 api_key="your_api_key",
7 default_headers={"X-Organization-ID": "your_org_id"}
8)
9
10# Read large financial report
11with open('financial_report.txt', 'r') as f:
12 report_content = f.read()
13
14def calculate_total(numbers):
15 return {"total": sum(numbers)}
16
17def calculate_average(numbers):
18 return {"average": sum(numbers) / len(numbers) if numbers else 0}
19
20tools = [
21 {
22 "type": "function",
23 "function": {
24 "name": "calculate_total",
25 "description": "Calculate the sum of a list of numbers",
26 "parameters": {
27 "type": "object",
28 "properties": {
29 "numbers": {
30 "type": "array",
31 "items": {"type": "number"},
32 "description": "List of numbers to sum"
33 }
34 },
35 "required": ["numbers"]
36 },
37 "strict": True
38 }
39 },
40 {
41 "type": "function",
42 "function": {
43 "name": "calculate_average",
44 "description": "Calculate the average of a list of numbers",
45 "parameters": {
46 "type": "object",
47 "properties": {
48 "numbers": {
49 "type": "array",
50 "items": {"type": "number"},
51 "description": "List of numbers"
52 }
53 },
54 "required": ["numbers"]
55 },
56 "strict": True
57 }
58 }
59]
60
61response = client.chat.completions.create(
62 model="captain-voyager-latest",
63 messages=[
64 {"role": "user", "content": "What is the total revenue across all quarters?"}
65 ],
66 tools=tools,
67 extra_body={
68 "captain": {
69 "context": report_content
70 }
71 }
72)
73
74if response.choices[0].finish_reason == "tool_calls":
75 tool_call = response.choices[0].message.tool_calls[0]
76 args = json.loads(tool_call.function.arguments)
77
78 if tool_call.function.name == "calculate_total":
79 result = calculate_total(args["numbers"])
80 print(f"Total Revenue: ${result['total']:,.2f}")
81 elif tool_call.function.name == "calculate_average":
82 result = calculate_average(args["numbers"])
83 print(f"Average Revenue: ${result['average']:,.2f}")

Error Handling

1from openai import OpenAI
2import json
3
4client = OpenAI(
5 base_url="https://api.runcaptain.com/v1",
6 api_key="your_api_key",
7 default_headers={"X-Organization-ID": "your_org_id"}
8)
9
10def safe_execute_tool(tool_name, args):
11 try:
12 if tool_name == "calculate":
13 return calculate(args["operation"], args["a"], args["b"])
14 elif tool_name == "query_database":
15 return query_database(args["customer_id"])
16 elif tool_name == "get_weather":
17 return get_weather(args["location"], args.get("unit", "celsius"))
18 else:
19 return {"error": f"Unknown tool: {tool_name}"}
20 except KeyError as e:
21 return {"error": f"Missing parameter: {e}"}
22 except Exception as e:
23 return {"error": f"Tool execution failed: {str(e)}"}
24
25tools = [...] # Your tool definitions
26
27response = client.chat.completions.create(
28 model="captain-voyager-latest",
29 messages=[{"role": "user", "content": "Your query"}],
30 tools=tools
31)
32
33if response.choices[0].finish_reason == "tool_calls":
34 for tool_call in response.choices[0].message.tool_calls:
35 try:
36 args = json.loads(tool_call.function.arguments)
37 except json.JSONDecodeError:
38 print(f"Invalid JSON in tool arguments: {tool_call.function.arguments}")
39 continue
40
41 result = safe_execute_tool(tool_call.function.name, args)
42
43 if "error" in result:
44 print(f"Tool error: {result['error']}")
45 else:
46 print(f"Tool result: {result}")

Multiple Tools

1from openai import OpenAI
2import json
3
4client = OpenAI(
5 base_url="https://api.runcaptain.com/v1",
6 api_key="your_api_key",
7 default_headers={"X-Organization-ID": "your_org_id"}
8)
9
10# Define multiple tools
11tools = [
12 {
13 "type": "function",
14 "function": {
15 "name": "get_stock_price",
16 "description": "Get current stock price",
17 "parameters": {
18 "type": "object",
19 "properties": {
20 "symbol": {"type": "string", "description": "Stock ticker symbol"}
21 },
22 "required": ["symbol"]
23 },
24 "strict": True
25 }
26 },
27 {
28 "type": "function",
29 "function": {
30 "name": "calculate_roi",
31 "description": "Calculate return on investment",
32 "parameters": {
33 "type": "object",
34 "properties": {
35 "initial": {"type": "number", "description": "Initial investment"},
36 "current": {"type": "number", "description": "Current value"}
37 },
38 "required": ["initial", "current"]
39 },
40 "strict": True
41 }
42 },
43 {
44 "type": "function",
45 "function": {
46 "name": "get_company_info",
47 "description": "Get company information",
48 "parameters": {
49 "type": "object",
50 "properties": {
51 "symbol": {"type": "string", "description": "Stock ticker symbol"}
52 },
53 "required": ["symbol"]
54 },
55 "strict": True
56 }
57 }
58]
59
60response = client.chat.completions.create(
61 model="captain-voyager-latest",
62 messages=[
63 {"role": "user", "content": "What's the current price of AAPL and its ROI if I bought at $150?"}
64 ],
65 tools=tools
66)
67
68if response.choices[0].finish_reason == "tool_calls":
69 for tool_call in response.choices[0].message.tool_calls:
70 args = json.loads(tool_call.function.arguments)
71
72 if tool_call.function.name == "get_stock_price":
73 price = get_stock_price(args["symbol"])
74 print(f"Current price of {args['symbol']}: ${price}")
75
76 elif tool_call.function.name == "calculate_roi":
77 roi = calculate_roi(args["initial"], args["current"])
78 print(f"ROI: {roi}%")
79
80 elif tool_call.function.name == "get_company_info":
81 info = get_company_info(args["symbol"])
82 print(f"Company: {info['name']}, Sector: {info['sector']}")

Async Tool Execution

1from openai import AsyncOpenAI
2import json
3import asyncio
4import aiohttp
5
6client = AsyncOpenAI(
7 base_url="https://api.runcaptain.com/v1",
8 api_key="your_api_key",
9 default_headers={"X-Organization-ID": "your_org_id"}
10)
11
12async def fetch_data_async(endpoint):
13 async with aiohttp.ClientSession() as session:
14 async with session.get(f"https://api.example.com/{endpoint}") as response:
15 return await response.json()
16
17tools = [{
18 "type": "function",
19 "function": {
20 "name": "fetch_data",
21 "description": "Fetch data from API endpoint",
22 "parameters": {
23 "type": "object",
24 "properties": {
25 "endpoint": {"type": "string", "description": "API endpoint to call"}
26 },
27 "required": ["endpoint"]
28 },
29 "strict": True
30 }
31}]
32
33async def main():
34 response = await client.chat.completions.create(
35 model="captain-voyager-latest",
36 messages=[
37 {"role": "user", "content": "Fetch user data from /users/123"}
38 ],
39 tools=tools
40 )
41
42 if response.choices[0].finish_reason == "tool_calls":
43 tool_call = response.choices[0].message.tool_calls[0]
44 args = json.loads(tool_call.function.arguments)
45
46 data = await fetch_data_async(args["endpoint"])
47 print(f"Fetched data: {data}")
48
49asyncio.run(main())