pyRPC
Get Started

Quickstart

Get a working pyRPC server and client in under 2 minutes.

Quickstart

Copy, paste, run - a working pyRPC server and client call in under 2 minutes.

1. Install

uv add pyrpc-core[fastapi]

uvicorn is included as a dependency of pyrpc-core - no need to install it separately. The pyrpc dev command uses it under the hood.

2. Server

Create server.py:

from fastapi import FastAPI
from pyrpc_core import rpc
from pyrpc_fastapi import mount_fastapi

app = FastAPI()

@rpc
def add(a: int, b: int) -> int:
    """Add two numbers."""
    return a + b

@rpc
def greet(name: str = "World") -> str:
    """Greet someone."""
    return f"Hello, {name}!"

mount_fastapi(app)

3. Start the dev server

Run pyrpc dev - on first run it will prompt for your framework, Python module, TypeScript client location, and distribution mode, then generate types automatically.

pyrpc dev

Expected output (workspace mode - monorepo):

pyRPC Setup
Let's configure pyRPC for your project.

? Which web framework are you using?  fastapi
? Python module to scan for @rpc procedures:  server
? How are types distributed?  workspace
? Where is your TypeScript client project?:  ../frontend

  ✓ Types regenerated (2 procs)
  pyRPC dev server  http://127.0.0.1:8000/rpc
  Types: ../frontend/node_modules/@pyrpc/types/src/index.ts

This creates a pyrpc.json config file and starts the dev server with auto-type regeneration on file changes. The distribution field determines how types are synced:

  • workspace (default) - for monorepos: types written directly to your client project
  • server - for separate repos: clients fetch types via npx pyrpc sync

For server mode, start with:

pyrpc dev --distribution server

4. Client (TypeScript)

import { createClient } from "@pyrpc/client"
import type { Types } from "@pyrpc/types"

const client = createClient<Types>()

// Fully typed result and parameters!
const result = await client.add(10, 5)
const message = await client.greet("pyRPC")

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)  # 15

Done

You now have a working pyRPC server + end-to-end typed contracts. Next: