Flask

Mount pyRPC on a Flask application using mount_flask.

The Flask adapter mounts pyRPC onto a Flask app. Flask is sync-only, so the adapter handles async procedure execution internally, your procedure code stays the same.

1. Install

uv add pyrpc-core[flask]
# or
pip install "pyrpc-core[flask]"

This also installs flask-cors, which you'll need for local frontend development.

2. Write the server

main.py
from flask import Flask
from flask_cors import CORS
from pyrpc_core import rpc
from pyrpc_flask import mount_flask

app = Flask(__name__)
CORS(app, origins=["http://localhost:3000"])  # your frontend origin

@rpc.query
def greet(name: str = "World") -> dict:
    return {"message": f"Hello, {name}!", "framework": "Flask"}

@rpc.query
def read_item(item_id: int, q: str = None) -> dict:
    return {"item_id": item_id, "q": q}

@rpc.mutation
def create_item(name: str, description: str = None) -> dict:
    return {"name": name, "description": description, "created": True}

mount_flask(app)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=5000)

3. Start the dev server

pyrpc dev

First run: a short wizard asks for your backend framework (Flask is preselected when detected) and entry point, then client root and frontend framework, and writes pyrpc.json. Every run after: reads pyrpc.json automatically. To skip the wizard:

# auto-detect
pyrpc dev --yes

# fully explicit
pyrpc dev --yes --framework flask --module main --client ../client

pyrpc dev serves the app with Flask's own dev server (flask run on your module:app - no WSGI-to-ASGI bridge involved; default http://127.0.0.1:8000/rpc), generates __pyrpc.ts at the client project root, and re-generates it on every .py save.

4. Connect the frontend

lib/pyrpc.ts
import { createReactClient, httpBatchLink } from "@pyrpc/react"
import type { Types } from "@pyrpc/types"

export const api = createReactClient<Types>({
  links: [
    httpBatchLink({
      url: "http://localhost:8000",
    }),
  ],
})

Note: the URL must match the port your Flask app is served on. pyrpc dev uses port 8000 by default; if you run the app directly with app.run(port=5000) instead, use 5000.

See React, Next.js, Vue, or Svelte for full frontend setup.

How it works

  • @rpc.query / @rpc.mutation register the function in the global registry with its kind.
  • mount_flask(app) adds two routes to the Flask app:
    • POST /rpc: procedure dispatch (async execution via anyio.run)
    • GET /rpc: schema introspection
  • Flask is sync-only, mount_flask runs async procedure execution with anyio.run internally. You don't need to change anything.

CORS origins by frontend

FrontendDefault dev origin
React (CRA)http://localhost:3000
React (Vite)http://localhost:5173
Next.jshttp://localhost:3000
Vue (Vite)http://localhost:5173
Svelte (Vite)http://localhost:5173

Full working examples

ExampleFrontendSource
Flask + ReactReact + TanStack Queryexamples/flask-react
Flask + Next.jsNext.js App Router + RSCexamples/flask-nextjs
Flask + VueVue 3 + TanStack Vue Queryexamples/flask-vue
Flask + SvelteSvelte + TanStack Svelte Queryexamples/flask-svelte