Quickstart
Get a working pyRPC server and client in under 2 minutes.
1. Install
uv add pyrpc-core
uvicornis included as a dependency ofpyrpc-core- no need to install it separately. Thepyrpc devcommand uses it under the hood.
2. Server
Create server.py:
from pyrpc_core import rpc, model
@model
class User:
name: str
age: int
@rpc
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
@rpc
def greet(user: User) -> str:
"""Greet a user."""
return f"Hello, {user.name}!"3. Start the dev server
Run pyrpc dev - on first run it walks you through setup: your backend framework and entry point, then the client project root and frontend framework. The backend framework decides which native dev server runs (uvicorn for FastAPI/ASGI, flask run for Flask, manage.py runserver for Django), so pick the one your project actually uses.
pyrpc devFirst run output:
pyRPC setup (runs once — saved to pyrpc.json)
? Backend framework: FastAPI
? Backend entry point (module[:app] — the file that calls mount_fastapi): server
? Client project root: ../frontend
? Frontend framework: Next.js
✓ types generated (2 procs) → ../frontend
pyRPC dev http://127.0.0.1:8000/rpcThe client root prompt autocompletes directories as you type (Tab accepts a suggestion). This creates a pyrpc.json config file and starts the dev server with auto-type regeneration on file changes. pyrpc dev writes __pyrpc.ts to your client project root and wires @pyrpc/types to it automatically.
To skip the wizard in CI or on repeat setups:
pyrpc dev --yes # sniff the framework, auto-detect module and client
pyrpc dev --yes --framework fastapi --module server --client ../frontend
pyrpc dev --yes --framework flask --module app --client ../frontendWith --yes, pyRPC sniffs your code for mount_fastapi / mount_flask / mount_django and refuses to guess when detection fails — pass --framework explicitly to be sure.
4. Client (TypeScript)
import { createClient, httpBatchLink } from "@pyrpc/client"
import type { Types } from "@pyrpc/types"
const api = createClient<Types>({
links: [
httpBatchLink({
url: "http://localhost:8000",
}),
],
})
const result = await api.add(10, 5)
const message = await api.greet({ name: "pyRPC", age: 1 })
console.log(result, message)5. Client (Python)
You can also call your procedures from other Python services or scripts with zero codegen required.
from pyrpc_core import RPCClient
with RPCClient("http://localhost:8000") as client:
# Everything is dynamic and introspected at runtime
result = client.add(a=10, b=5)
print(result) # 15Done
You now have a working pyRPC server + end-to-end typed contracts. Next:
- Installation - Adapters and CLI tools
- Concepts - Mental model and error handling
- Server Guide - Routers and procedures
- Client Guide - TypeScript and Python usage

pyRPC