Django's async view support (4.2+) makes it a natural fit for pyRPC. Procedures are just async def functions decorated with @rpc.query / @rpc.mutation, and Django handles them natively, no anyio.run bridge.
There's one Django-specific thing to know: procedures are registered by executing their decorator, which happens when the module is imported. You must import views in urls.py to trigger registration.
Server, views.py
# myproject/views.py
from django.http import HttpResponse
from pyrpc_core import rpc
def index(request):
return HttpResponse("<h1>Django + pyRPC</h1>")
@rpc.query
async def greet(name: str = "World") -> dict:
return {"message": f"Hello, {name}!", "framework": "Django"}
@rpc.query
async def read_item(item_id: int, q: str = None) -> dict:
return {"item_id": item_id, "q": q, "framework": "Django"}
@rpc.mutation
async def create_item(name: str, description: str = None) -> dict:
return {"name": name, "description": description, "created": True}Server, urls.py
# myproject/urls.py
from django.contrib import admin
from django.urls import path
from pyrpc_django import mount_django
from . import views # ← this import registers the @rpc decorators
urlpatterns = [
path("admin/", admin.site.urls),
path("", views.index, name="index"),
]
mount_django(urlpatterns)The import is required. Without from . import views, the procedures never run their decorators and /rpc returns an empty schema.
CORS, settings.py
INSTALLED_APPS = ["corsheaders", ...] MIDDLEWARE = ["corsheaders.middleware.CorsMiddleware", ...] CORS_ALLOWED_ORIGINS = ["http://localhost:3000"]
Start the dev server
cd server uv add pyrpc-core[django] pyrpc dev --yes --module myproject.views --client ../client
Client, identical to fastapi-react
// src/pyrpc.ts
import { createReactClient } from "@pyrpc/react"
import type { Types } from "@pyrpc/types"
export const api = createReactClient<Types>({
baseUrl: process.env.REACT_APP_API_URL ?? "http://localhost:8000",
})// src/App.tsx
import { useState } from "react"
import { api } from "./pyrpc"
function App() {
const [name, setName] = useState("")
const { data: greeting, isLoading } = api.greet.useQuery({ name: "Django User" })
const { data: item } = api.read_item.useQuery({ item_id: 42, q: "test" })
const createItem = api.create_item.useMutation()
return (
<api.Provider>
{isLoading ? <p>Loading…</p> : <pre>{JSON.stringify(greeting)}</pre>}
<pre>{JSON.stringify(item)}</pre>
<input value={name} onChange={e => setName(e.target.value)} />
<button onClick={() => createItem.mutate({ name })} disabled={createItem.isPending}>
{createItem.isPending ? "Creating…" : "Create"}
</button>
{createItem.isSuccess && <pre>{JSON.stringify(createItem.data)}</pre>}
</api.Provider>
)
}Run it
cd server && pyrpc dev cd client && npm install && npm start
Open http://localhost:3000. Full source at examples/django-react.

pyRPC