Django-native AI SDK with agent-centric design, multi-provider support, and DRF integration
Project description
djangosdk
A Django-native AI SDK. One Agent class, 12+ providers, no boilerplate.
djangosdk gives Django developers a consistent API for building AI agents — tool calling, streaming, structured output, conversation persistence, reasoning models — without wiring up provider SDKs or rewriting the same patterns in every project.
from djangosdk import Agent, tool
@tool
def get_order(order_id: str) -> str:
"""Fetch the current status of an order.
Args:
order_id: The order identifier.
"""
return Order.objects.get(pk=order_id).status
class SupportAgent(Agent):
provider = "anthropic"
model = "claude-3-5-haiku-20241022"
system_prompt = "You are a helpful customer support agent."
tools = [get_order]
response = SupportAgent().handle("Where is my order #1234?")
print(response.text)
Switching providers is a one-line change. The tool dispatch loop, prompt caching, conversation history, and streaming responses are handled for you regardless of which model you use.
Getting started
uv add djangosdk
# settings.py
INSTALLED_APPS = ["djangosdk", ...]
AI_SDK = {
"DEFAULT_PROVIDER": "openai",
"DEFAULT_MODEL": "gpt-4o-mini",
"PROVIDERS": {
"openai": {"api_key": env("OPENAI_API_KEY")},
"anthropic": {"api_key": env("ANTHROPIC_API_KEY")},
},
}
Structured output
from pydantic import BaseModel
from djangosdk import Agent
class Sentiment(BaseModel):
label: str
score: float
class SentimentAgent(Agent):
model = "gpt-4o-mini"
output_schema = Sentiment
response = SentimentAgent().handle("I love this product but the shipping was slow.")
print(response.structured) # Sentiment(label='mixed', score=0.6)
Streaming
from djangosdk.streaming.async_sse import AsyncSSEResponse
async def chat_view(request):
return AsyncSSEResponse(SupportAgent().astream(request.POST["message"]))
Reasoning models
from djangosdk import Agent
from djangosdk.providers.schemas import ReasoningConfig
class AnalysisAgent(Agent):
provider = "openai"
model = "o3"
reasoning = ReasoningConfig(effort="high")
ReasoningConfig maps to the right parameter for each provider — reasoning_effort for o3/o4-mini, extended_thinking for Claude 3.7, budget_tokens for DeepSeek R1.
Testing
from djangosdk.testing.fakes import FakeProvider
from djangosdk.testing.assertions import assert_tool_called
def test_support_agent(settings):
settings.AI_SDK = {"DEFAULT_PROVIDER": "fake", "PROVIDERS": {"fake": {}}}
FakeProvider.set_response("Your order is shipped.")
response = SupportAgent().handle("Where is order #1234?")
assert_tool_called(SupportAgent, "get_order", order_id="1234")
assert "shipped" in response.text
FakeProvider never calls a real API. assert_tool_called and assert_prompt_sent let you make assertions on what the agent actually did.
Philosophy
Django projects tend to share the same AI patterns: a provider client, a prompt template, a tool dispatch loop, a table for conversation history, a streaming endpoint. Every team writes their own version. djangosdk is the version that doesn't need to be written again.
The design follows Django's own conventions. Agents are classes. Capabilities are mixins — add HasTools, HasStructuredOutput, or Conversational to the base Agent class and get exactly what you need, nothing more. Configuration lives in AI_SDK in settings.py. The ORM, signals, management commands, and DRF integration all work the way Django developers expect them to.
The provider layer is built on litellm. We don't call provider SDKs directly and neither should you. The abstraction is thin on purpose — if litellm supports a model, djangosdk supports it.
Why djangosdk
- Provider independence. Swap
provider = "openai"forprovider = "anthropic"and nothing else changes. The same tools, the same structured output schema, the same streaming response. - Reasoning models work out of the box. o3, Claude 3.7 extended thinking, and DeepSeek R1 each require different API parameters.
djangosdkhandles the translation. - The tool loop is not your problem. Define
@toolfunctions, attach them to an agent, and the SDK handles calling them, feeding results back, and repeating until the model is done — up to a configurable limit. - Django-native persistence. Conversation history is stored in
ConversationandMessageORM models. Episodic and semantic memory layers are available for more complex agents. - Test helpers that are actually useful.
FakeProvidergives you deterministic responses. The assertion helpers let you verify prompts and tool calls without mocking internals. - MCP support. Run Django applications as MCP servers or connect to external MCP servers from your agents.
How it compares
| djangosdk | django-ai-assistant | LangChain | |
|---|---|---|---|
| Provider support | 12+ via litellm | OpenAI only | Many |
| Django-native | Yes | Partial | No |
| Reasoning model support | Yes | No | Partial |
| Prompt caching | Yes (Anthropic + OpenAI) | No | No |
| DRF views + serializers | Yes | No | No |
| Test utilities | Yes | No | No |
| MCP | Yes | No | No |
Documentation
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file djangosdk-0.1.4.tar.gz.
File metadata
- Download URL: djangosdk-0.1.4.tar.gz
- Upload date:
- Size: 296.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9eeea3e7d0a500ded36238acf35d5534e3238995696b83a3925cc7ac39c150cb
|
|
| MD5 |
9b260201bd16cbe50ffd512e2ade2e99
|
|
| BLAKE2b-256 |
a5574a5930f599f8cdce3c5bf9c6577eadd63af7321f5fb0acf971d47ed89868
|
Provenance
The following attestation bundles were made for djangosdk-0.1.4.tar.gz:
Publisher:
publish.yml on ziyacivan/djangosdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
djangosdk-0.1.4.tar.gz -
Subject digest:
9eeea3e7d0a500ded36238acf35d5534e3238995696b83a3925cc7ac39c150cb - Sigstore transparency entry: 1203601567
- Sigstore integration time:
-
Permalink:
ziyacivan/djangosdk@c7ff732a94514fa086942a363425d0d55e6a07db -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/ziyacivan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c7ff732a94514fa086942a363425d0d55e6a07db -
Trigger Event:
push
-
Statement type:
File details
Details for the file djangosdk-0.1.4-py3-none-any.whl.
File metadata
- Download URL: djangosdk-0.1.4-py3-none-any.whl
- Upload date:
- Size: 77.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
045e98caf5cdaac91a42431ab36b223a8ac2854e7a46e89a29f4f45a72f94f29
|
|
| MD5 |
28abec297ec7fb906278e91311c041c7
|
|
| BLAKE2b-256 |
b4b335746a03f9d4be21faea12cce335c4acf6df894c878d786b1e0c7d4979bd
|
Provenance
The following attestation bundles were made for djangosdk-0.1.4-py3-none-any.whl:
Publisher:
publish.yml on ziyacivan/djangosdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
djangosdk-0.1.4-py3-none-any.whl -
Subject digest:
045e98caf5cdaac91a42431ab36b223a8ac2854e7a46e89a29f4f45a72f94f29 - Sigstore transparency entry: 1203601570
- Sigstore integration time:
-
Permalink:
ziyacivan/djangosdk@c7ff732a94514fa086942a363425d0d55e6a07db -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/ziyacivan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c7ff732a94514fa086942a363425d0d55e6a07db -
Trigger Event:
push
-
Statement type: