In today’s world of AI-powered applications, large language models (LLMs) like Claude by Anthropic offer a human-like understanding of natural language. But when it comes to precise tasks, like date calculations, calendar parsing, or time-based reasoning, relying on natural language alone can lead to inconsistent results. That’s where function calling comes in.
In this article, we’ll walk through a powerful example of how to integrate Anthropic Claude with Python function calling to build a smart date assistant. The assistant understands natural language queries and uses tools (functions) to return precise, structured answers involving date extraction, date arithmetic, and real-time data computation.
![Anthropic Claude]()
What We'll Build?
A smart assistant that can:
- Answer: “What’s today’s date?”
- Extract: “Let’s meet next week” → 2025-07-14
- Calculate: “How many days until Christmas?”
- Stream responses in real-time
- Call Python functions to get accurate results
Technologies Used
- Anthropic SDK: Send/receive messages to Claude
- Python: Define and execute tools (functions)
- Streaming API: Display Claude’s response in real time
- .env config: Securely load API key
Implementation
1. Setup and Configuration
Install dependencies: pip install anthropic python-dotenv
Create a .env file and add your Claude API key: ANTHROPIC_API_KEY=your-api-key-here
Imports
import anthropic
import os
from dotenv import load_dotenv
from datetime import datetime, timedelta
import time
We load environment variables to securely access the Anthropic API key:
load_dotenv()
ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
2. Define Functions (Tools)
These Python functions will act as external tools that Claude can call when needed.
a. Extract Natural Dates
def extract_date_from_text(text_input):
today = datetime.now()
if "tomorrow" in text_input.lower():
return (today + timedelta(days=1)).strftime("%Y-%m-%d")
elif "next week" in text_input.lower():
return (today + timedelta(days=7)).strftime("%Y-%m-%d")
elif "next month" in text_input.lower():
next_month = today.replace(day=1) + timedelta(days=32)
return next_month.replace(day=1).strftime("%Y-%m-%d")
elif "next friday" in text_input.lower():
days_ahead = 4 - today.weekday() # Friday is 4
if days_ahead <= 0:
days_ahead += 7
return (today + timedelta(days=days_ahead)).strftime("%Y-%m-%d")
else:
return None
b. Get Today’s Date
def get_current_date():
return datetime.now().strftime("%Y-%m-%d")
c. Days Until a Target Date
def calculate_days_until(target_date):
try:
target = datetime.strptime(target_date, "%Y-%m-%d")
today = datetime.now()
return (target - today).days
except:
return None
3. Tool Definitions for Claude
These are JSON schemas that Claude uses to understand what each tool does and what inputs it needs.
function_definitions = [
{
"name": "extract_date_from_text",
"description": "Extract and parse date from natural language text input",
"input_schema": {
"type": "object",
"properties": {
"text_input": {
"type": "string",
"description": "The natural language text containing a date reference"
}
},
"required": ["text_input"]
}
},
...
]
4. Function Dispatcher
We map each tool name to its actual Python function:
available_functions = {
"extract_date_from_text": extract_date_from_text,
"get_current_date": get_current_date,
"calculate_days_until": calculate_days_until
}
5. Claude Interaction with Tool Use + Streaming
Here’s where everything comes together. Full Function:
def process_streaming_with_functions(user_input, max_retries=3):
messages = [{"role": "user", "content": f"Help me with this date-related query: {user_input}"}]
for attempt in range(max_retries):
try:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
temperature=0.2,
system="You are a helpful assistant that can extract dates and perform date calculations. Use the available functions when needed to provide accurate results.",
messages=messages,
tools=function_definitions
)
# Handle function calls
function_calls = []
for content in response.content:
if content.type == "tool_use":
function_calls.append(content)
if function_calls:
messages.append({"role": "assistant", "content": response.content})
# Execute each tool
tool_results = []
for call in function_calls:
function_name = call.name
function_args = call.input
result = available_functions[function_name](**function_args)
tool_results.append({
"type": "tool_result",
"tool_use_id": call.id,
"content": str(result)
})
# Append results and stream final reply
messages.append({"role": "user", "content": tool_results})
final_response = ""
with client.messages.stream(
model="claude-3-5-sonnet-20241022",
max_tokens=1000,
temperature=0.2,
system="You are a helpful assistant.",
messages=messages
) as stream:
for event in stream:
if event.type == "content_block_delta" and event.delta.type == "text_delta":
print(event.delta.text, end="", flush=True)
final_response += event.delta.text
print("\n")
return final_response
else:
return "".join(c.text for c in response.content if c.type == "text")
except anthropic.RateLimitError:
time.sleep(2 ** attempt)
except anthropic.APIError as e:
time.sleep(1)
except Exception as e:
return f"ERROR: {e}"
6. Testing
We run multiple prompts to evaluate how Claude uses tools:
def run_function_call_tests():
test_queries = [
"What's today's date?",
"I need to schedule something for tomorrow",
"How many days until 2025-12-25?",
"Extract the date from: 'Let's meet next week'",
"What date is next Friday?",
"When is next month starting?"
]
for query in test_queries:
result = process_streaming_with_functions(query)
print(f"\nFinal result: {result}")
Sample Output
Test 2/6
Processing: 'I need to schedule something for tomorrow'
Claude's response:
Sure! Let's determine what date "tomorrow" refers to.
Function call: extract_date_from_text
Input: {'text_input': 'I need to schedule something for tomorrow'}
extract_date_from_text returned: 2025-07-09
Final response:
You should schedule it for 2025-07-09.
Conclusion
This smart assistant blends LLM intelligence with programmatic logic, producing highly accurate, user-friendly, and scalable results. If you're building agents, chatbots, or automation tools, this is a powerful pattern you’ll want in your toolbox.
Combining Claude’s intelligence with Python’s precision unlocks real, production-grade assistants. We have now learned how to:
- Call tools/functions from Claude
- Stream final answers
- Handle retries and errors
- Test multi-step conversations
This Smart Date Assistant is a foundation for any LLM-based app that needs structured logic with natural language input.