Metadata-Version: 2.4
Name: djangorestframework-pydantic-ai
Version: 0.2.2
Summary: Expose djangorestframework-services services and selectors as a Pydantic-AI toolset.
Project-URL: Homepage, https://github.com/Artui/djangorestframework-pydantic-ai
Project-URL: Repository, https://github.com/Artui/djangorestframework-pydantic-ai
Project-URL: Issues, https://github.com/Artui/djangorestframework-pydantic-ai/issues
Author-email: Artur Veres <artur8118@gmail.com>
License: MIT
License-File: LICENSE
Keywords: agent,ai,django,drf,llm,pydantic-ai,rest-framework,tools
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.0
Classifier: Framework :: Django :: 5.1
Classifier: Framework :: Django :: 5.2
Classifier: Framework :: Django :: 6.0
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: django>=4.2
Requires-Dist: djangorestframework-services<0.23,>=0.21.1
Requires-Dist: djangorestframework>=3.14
Requires-Dist: pydantic-ai-slim<2,>=1.0
Provides-Extra: filter
Requires-Dist: django-filter>=23; extra == 'filter'
Description-Content-Type: text/markdown

# djangorestframework-pydantic-ai

[![CI](https://github.com/Artui/djangorestframework-pydantic-ai/workflows/tests/badge.svg)](https://github.com/Artui/djangorestframework-pydantic-ai/actions/workflows/tests.yml)
[![PyPI](https://img.shields.io/pypi/v/djangorestframework-pydantic-ai.svg)](https://pypi.org/project/djangorestframework-pydantic-ai/)
[![Python versions](https://img.shields.io/pypi/pyversions/djangorestframework-pydantic-ai.svg)](https://pypi.org/project/djangorestframework-pydantic-ai/)
[![Django versions](https://img.shields.io/pypi/djversions/djangorestframework-pydantic-ai.svg)](https://pypi.org/project/djangorestframework-pydantic-ai/)
[![Docs](https://img.shields.io/badge/docs-artui.github.io-blue.svg)](https://artui.github.io/djangorestframework-pydantic-ai/)
[![Coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/Artui/djangorestframework-pydantic-ai/gh-pages/coverage.json)](https://github.com/Artui/djangorestframework-pydantic-ai/actions/workflows/tests.yml)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![License](https://img.shields.io/pypi/l/djangorestframework-pydantic-ai.svg)](LICENSE)

Expose [`djangorestframework-services`](https://github.com/Artui/djangorestframework-services)
services and selectors as a [Pydantic-AI](https://ai.pydantic.dev) toolset, so a
plain `pydantic_ai.Agent` can call them as tools — **no MCP server and no AG-UI
bridge** in the path.

Every tool call routes through drf-services' transport-neutral surface
(`dispatch_spec` plus its off-HTTP helpers), so a tool call runs the same input
validation, the same `permission_classes` — both class-level `has_permission`
and object-level `has_object_permission` on the resolved row — and the same
serializer rendering your DRF views apply, just without the HTTP hop.

## Install

```bash
pip install djangorestframework-pydantic-ai
```

It depends only on `djangorestframework-services` and `pydantic-ai-slim`. A model
provider is pulled in separately, the usual Pydantic-AI way (e.g.
`pip install "pydantic-ai-slim[anthropic]"`).

## Quickstart

```python
from pydantic_ai import Agent
from rest_framework_pydantic_ai import AgentDeps, SpecToolset

toolset = SpecToolset({
    "list_orders":  orders_selector_spec,   # SelectorSpec -> read-only tool
    "create_order": create_order_spec,      # ServiceSpec  -> mutation tool
})

agent = Agent("anthropic:claude-opus-4-8", deps_type=AgentDeps, toolsets=[toolset])

result = await agent.run(
    "create an order of 3 widgets",
    deps=AgentDeps(user=request.user),
)
```

The agent acts as `deps.user`: each call builds an off-HTTP request/view context,
**enforces the spec's `permission_classes`** (class- and object-level),
dispatches the spec, and renders the result through the spec's serializer. List
selectors gain `page` / `limit` / `order` tool args.

Failures map onto the model loop so the agent self-corrects: invalid input, a bad
`page` / `limit` / `order` value, and unexpected (hallucinated) arguments come
back as `ModelRetry`; a business error or missing row becomes a readable
`{"error": ...}`; a denied permission raises `PermissionDenied` and aborts the
run. Unexpected arguments are **rejected by default** — pass `unknown_arguments=`
to `SpecToolset` (`IGNORE` / `PASSTHROUGH`) to change that.

See the [documentation](https://artui.github.io/djangorestframework-pydantic-ai/)
for the full reference.

## License

MIT
