NexusLLM Python SDK
Official asynchronous Python SDK for the Centralized LLM Platform (NexusLLM).
Installation
Install using uv (recommended) or pip:
uv add nexus-llm
# or
pip install nexus-llm
Building a LangChain/LangGraph agent on top of NexusLLM? Install the
langchain extra to get ChatCentralizedLLM/NexusEmbeddings (see
LangChain / LangGraph Integration below):
pip install "nexus-llm[langchain]"
Quick Start
Simple Chat Completion
import asyncio
from nexus_llm import AIClient
async def main():
# Automatically reads NEXUS_API_KEY and NEXUS_BASE_URL env variables
client = AIClient(api_key="your-nexus-api-key")
response = await client.chat.create(
agent_id="my-custom-agent",
messages=[
{"role": "user", "content": "Hello! Introduce yourself."}
]
)
print(response.choices[0].content)
await client.close()
asyncio.run(main())
Streaming Chat
Passing stream=True targets the gateway's dedicated Server-Sent-Events
endpoint (/chat/stream) under the hood, rather than the plain JSON /chat
endpoint — you don't need to do anything differently, the example below just
works.
import asyncio
from nexus_llm import AIClient
async def main():
client = AIClient(api_key="your-nexus-api-key")
stream = await client.chat.create(
agent_id="my-custom-agent",
messages=[
{"role": "user", "content": "Write a 3-paragraph story."}
],
stream=True
)
async for chunk in stream:
print(chunk.content, end="", flush=True)
await client.close()
asyncio.run(main())
Tool Calling
tools accepts raw OpenAI function-calling JSON schema — the format every
major agent framework already produces, so it needs no translation on your
end. The response's tool_calls mirrors LangChain's own ToolCall shape.
When streaming, tool-call arguments arrive incrementally as
chunk.tool_call_chunks (partial JSON fragments, keyed by index) rather
than as one complete call.
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
response = await client.chat.create(
agent_id="my-custom-agent",
messages=[{"role": "user", "content": "What's the weather in Delhi?"}],
tools=tools,
tool_choice="auto",
)
for call in response.choices[0].tool_calls or []:
print(call["name"], call["args"]) # e.g. get_weather {'city': 'Delhi'}
# Feed the executed tool's result back in a follow-up call:
messages = [
{"role": "user", "content": "What's the weather in Delhi?"},
{"role": "assistant", "content": None, "tool_calls": response.choices[0].tool_calls},
{"role": "tool", "content": "72F and sunny", "tool_call_id": response.choices[0].tool_calls[0]["id"]},
]
Not every model/provider combination supports tool calling yet — the gateway
returns 424 for one that isn't verified rather than silently ignoring
tools. Check supports_tools on an entry from client.models/the admin
model garden before wiring up a new agent.
Reasoning Content
Models that expose their reasoning/thinking (Claude's extended thinking,
OpenAI's o-series, DeepSeek) surface it as a separate reasoning field on
the choice/chunk — never mixed into content — so you can log or display it
distinctly from the final answer:
response = await client.chat.create(agent_id="my-custom-agent", messages=[...])
print(response.choices[0].reasoning) # None if the model doesn't support it
print(response.choices[0].content)
LangChain / LangGraph Integration
Install the langchain extra (pip install "nexus-llm[langchain]"), then
swap ChatOpenAI(...) for ChatCentralizedLLM(...) in any LangGraph node —
graph topology, tools, memory, and checkpointers are unaffected, since they
only depend on the BaseChatModel interface:
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
from nexus_llm import AIClient
from nexus_llm.integrations.langchain import ChatCentralizedLLM, NexusEmbeddings
client = AIClient(api_key="your-nexus-api-key")
llm = ChatCentralizedLLM(agent_id="my-custom-agent", client=client)
@tool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"72F and sunny in {city}"
agent = create_react_agent(llm, tools=[get_weather])
result = await agent.ainvoke({"messages": [{"role": "user", "content": "Weather in Delhi?"}]})
Every call — including the tool-calling round trips LangGraph drives
internally — still goes through the agent's configured provider/model,
budget enforcement, and trace logging on the gateway; the framework has no
awareness a gateway sits underneath. NexusEmbeddings wraps
client.embeddings behind LangChain's Embeddings interface for RAG-style
retrievers/vectorstores.
File Management
Upload files, list them, fetch a presigned download URL, or delete them:
import asyncio
from nexus_llm import AIClient
async def main():
client = AIClient(api_key="your-nexus-api-key")
with open("dataset.csv", "rb") as f:
uploaded = await client.files.upload(f, filename="dataset.csv", purpose="fine-tune")
files = await client.files.list()
for f in files:
print(f.file_id, f.filename, f.size_bytes)
downloadable = await client.files.get(uploaded.file_id)
print(downloadable.download_url)
await client.files.delete(uploaded.file_id)
await client.close()
asyncio.run(main())
Agent Configuration
Configure the provider/model routing for an agent, and read back its current configuration:
import asyncio
from nexus_llm import AIClient
async def main():
client = AIClient(api_key="your-nexus-api-key")
config = await client.agents.configure(
agent_id="my-custom-agent",
provider="anthropic",
model="claude-sonnet-4-5",
fallback_provider="openai",
fallback_model="gpt-4o",
system_prompt="You are a helpful assistant.",
cache_enabled=True,
)
print(config.provider, config.model)
current = await client.agents.get_config("my-custom-agent")
print(current.cache_enabled)
await client.close()
asyncio.run(main())
Error Handling
Errors from the API are mapped to specific custom exception classes:
from nexus_llm import AIClient
from nexus_llm.exceptions import AuthenticationError, RateLimitError, ValidationError
async def run():
client = AIClient(api_key="invalid-key")
try:
await client.chat.create(
agent_id="agent-1",
messages=[{"role": "user", "content": "hi"}]
)
except AuthenticationError:
print("API Key invalid or revoked.")
except RateLimitError:
print("Rate limits exceeded. Exponential backoff has completed retries.")
except ValidationError as e:
print(f"Validation failed: {e.message}")
Configuration Options
When initializing the client, the following parameters are accepted:
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str |
NEXUS_API_KEY |
Nexus authorization key |
base_url |
str |
NEXUS_BASE_URL |
Endpoint of the centralized gateway |
timeout |
float |
30.0 |
Connection timeout in seconds |
retries |
int |
3 |
Number of retries on 429/5xx errors |
debug |
bool |
False |
Turn on logging diagnostics |
Metadata
Release files for nexus-llm 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| nexus_llm-1.1.0.tar.gz | 18.3 kB | With provenance | Details for nexus_llm-1.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nexus_llm-1.1.0-py3-none-any.whl | Python 3 | none | any | Details for nexus_llm-1.1.0-py3-none-any.whl |
Total release size: 37.2 kB
Release files / nexus_llm-1.1.0.tar.gz
| Download URL | nexus_llm-1.1.0.tar.gz |
|---|---|
| Size | 18.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3ec2835a577f2b2df77f50a332010a75aa91f329f935efbc803a85d87e5b5289
|
|
BLAKE2b-256 checksum How to use checksums |
a8b27bce85358e5f6283bbb27af4e8f08ea779e02819d9413573ef5bb2053466
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logRelease files / nexus_llm-1.1.0-py3-none-any.whl
| Download URL | nexus_llm-1.1.0-py3-none-any.whl |
|---|---|
| Size | 18.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9e5d12b111e2a99fc4626d50bb8ad5b989481a2a667e1e6b708b062c6f372b0a
|
|
BLAKE2b-256 checksum How to use checksums |
8cab6648beee25bd83e97bbcf5bdc6ff5501ac92bd18ebb0dce18afcbd735a7a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logSecurity for nexus-llm 1.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for nexus_llm-1.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.