Overview
Function calling tool loops let a model request external actions, then send the results back to the model. Use the Fikra API OpenAI-compatible chat completions endpoint at https://api.fikraapi.co.ke/v1 with any model from the model list. A reliable loop always appends tool results and re-sends the full message history until the assistant stops requesting tools.
Prerequisites
- Python 3.x
openaiPython SDK installed- Fikra API key stored in the environment variable
FIKRA_API_KEY - Base URL set to
https://api.fikraapi.co.ke/v1
Step-by-step
- Create the OpenAI client with the Fikra base URL and your API key.
- Define a tool as a JSON function schema.
- Send an initial chat completion request with
messagesandtools. - If the assistant message has no
tool_calls, the loop is done. - Otherwise, execute each tool call locally using the arguments from the assistant.
- Append the assistant message and each tool result to
messageswith role"tool"and the matchingtool_call_id. - Send a new chat completion request with the updated
messages. - Repeat until no
tool_callsare returned. Cap the loop to avoid infinite turns.
import json
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["FIKRA_API_KEY"],
base_url="https://api.fikraapi.co.ke/v1",
)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Return current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}
]
def get_weather(city: str) -> str:
return "sunny, 22C"
messages = [
{"role": "user", "content": "What is the weather in Nairobi?"}
]
for _ in range(5):
response = client.chat.completions.create(
model="deepseek-v4-flash-0731",
messages=messages,
tools=tools,
)
assistant = response.choices[0].message
messages.append(assistant)
if not assistant.tool_calls:
print(assistant.content)
break
for call in assistant.tool_calls:
args = json.loads(call.function.arguments)
result = get_weather(args["city"])
messages.append(
{
"role": "tool",
"tool_call_id": call.id,
"content": result,
}
)
Verify it works
Run the script and confirm the final assistant reply includes the tool result. The output should be generated from the get_weather result, not from a placeholder. Also confirm the request succeeds without a model error.
Costs
Pricing depends on the model. For deepseek-v4-flash-0731, the rate is USD 0.09 per 1M input tokens and USD 0.15 per 1M output tokens. Each loop iteration sends the full message history, so token usage grows with each turn. For current model rates, check the pricing page.
Common errors
401to invalid or inactive API key.400to unsupported model or malformed tool schema.429to rate limit exceeded: 30 requests/min for unverified keys, 100 requests/min for trusted keys.503to upstream service busy; retry with backoff.