Python SDK
Purpose
The Python SDK provides an async ApiMapperClient and adapters for LangChain and LangGraph.
Main Capabilities
- Async-first using
httpx - Async context manager (
async with) - Three authentication modes: API key, OAuth2 client credentials, delegated bearer
- Standard library
loggingintegration — no forced dependency - Adapters for LangChain (StructuredTool) and LangGraph (ToolNode)
Packages
| Package | Install extra | Description |
|---|---|---|
api-mapper-client |
— | Core client |
api-mapper-client[langchain] |
langchain-core, pydantic |
LangChain adapter |
api-mapper-client[langgraph] |
langgraph, langchain-core, pydantic |
LangGraph adapter |
api-mapper-client[all] |
all of the above | All adapters |
Installation
pip install api-mapper-client
# or with adapters:
pip install "api-mapper-client[all]"
Construction
import os, uuid
from api_mapper_client import ApiMapperClient, ApiMapperClientOptions, ApiKeyCredentialProvider
opts = ApiMapperClientOptions(
base_url=os.getenv("APIMAPPER_BASE_URL"),
tenant_id=uuid.UUID(os.getenv("APIMAPPER_TENANT_ID")),
client_id="my-app",
system_prompt_resource_uri="apimapper://toolsets/system-prompt",
credentials=ApiKeyCredentialProvider(os.getenv("APIMAPPER_API_KEY")),
)
async with ApiMapperClient(opts) as client:
...
See SDK Authentication for OAuth2 and delegated bearer options.
Raw Tool Loop (01-raw-client)
async with ApiMapperClient(opts) as client:
system_prompt = await client.get_system_prompt()
tools = await client.get_tools()
openai_tools = [
{
"type": "function",
"function": {
"name": t.name,
"description": t.description or "",
"parameters": t.input_schema,
},
}
for t in tools
]
messages = [
{"role": "system", "content": system_prompt or "You are a helpful assistant."},
{"role": "user", "content": user_message},
]
while True:
response = await openai_client.chat.completions.create(
model="gpt-4o", messages=messages, tools=openai_tools
)
choice = response.choices[0]
messages.append(choice.message.model_dump())
if choice.finish_reason != "tool_calls":
print(choice.message.content)
break
for call in choice.message.tool_calls:
args = json.loads(call.function.arguments)
result = await client.invoke_tool(call.function.name, args)
messages.append({"role": "tool", "tool_call_id": call.id,
"content": result.to_text() if result else ""})
LangGraph Agent (02-langgraph-agent)
create_api_mapper_tool_node and bind_api_mapper_tools from api_mapper_langgraph.
from api_mapper_langgraph import create_api_mapper_tool_node, bind_api_mapper_tools
from langgraph.graph import StateGraph, END
from langchain_core.messages import SystemMessage, HumanMessage
async with ApiMapperClient(opts) as client:
system_prompt = await client.get_system_prompt()
tool_node = await create_api_mapper_tool_node(client)
model = await bind_api_mapper_tools(ChatOpenAI(model="gpt-4o"), client)
def agent_node(state):
msgs = [SystemMessage(content=system_prompt or "")] + state["messages"]
return {"messages": [model.invoke(msgs)]}
def should_continue(state):
last = state["messages"][-1]
return "tools" if getattr(last, "tool_calls", None) else END
graph = StateGraph(AgentState)
graph.add_node("agent", agent_node)
graph.add_node("tools", tool_node)
graph.set_entry_point("agent")
graph.add_conditional_edges("agent", should_continue)
graph.add_edge("tools", "agent")
result = await graph.compile().ainvoke(
{"messages": [HumanMessage(content=user_message)]}
)
print(result["messages"][-1].content)
LangChain Agent (03-langchain-agent)
ApiMapperToolkit from api_mapper_langchain.
from api_mapper_langchain import ApiMapperToolkit
from langchain.agents import create_openai_functions_agent, AgentExecutor
async with ApiMapperClient(opts) as client:
system_prompt = await client.get_system_prompt() or "You are a helpful assistant."
toolkit = ApiMapperToolkit(client=client)
tools = await toolkit.get_tools()
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}"),
MessagesPlaceholder("agent_scratchpad"),
])
agent = create_openai_functions_agent(llm=ChatOpenAI(model="gpt-4o"), tools=tools, prompt=prompt)
executor = AgentExecutor(agent=agent, tools=tools)
result = await executor.ainvoke({"input": user_message})
print(result["output"])
Logging
The SDK emits records to the api_mapper_client.client logger using the standard logging module. Configure it like any other Python logger.
import logging
# Enable all SDK logs at DEBUG level
logging.basicConfig(level=logging.DEBUG)
# Or target only the SDK logger
logging.getLogger("api_mapper_client").setLevel(logging.INFO)
Auth header values and tool arguments are never emitted to logs.
