Skip to main content

FastAPI React Toolkit

A set of extensions for FastAPI and a React component library for building modern web applications with Mantine, Zustand, TanStack Query, and JsonForms.

Concept

FastAPI React Toolkit bootstraps a web API with FastAPI and provides a React component library for building a SPA frontend. It supports automatic CRUD API generation, RBAC, OAuth2/JWT authentication, database migrations, and i18n.

Features

  • Automatic CRUD API generation from SQLAlchemy models
  • Role-Based Access Control (RBAC)
  • Database migrations (Alembic)
  • OAuth2/JWT authentication
  • Modular backend and frontend
  • React hooks and components for API, Auth, Language, DataGrid, UserMenu, etc.
  • Built-in i18n for backend and frontend

Getting Started

You can use fastapi-rtk create-app command to quickly set up a new project with the recommended structure and example code.

Recommended Project Structure

project/
├── app/
│   ├── __init__.py          # Configuration loading
│   ├── app.py               # FastAPI app initialization
│   ├── config.py            # Settings
│   ├── models.py            # Database models
│   └── apis.py              # API endpoints
├── webapp/
│   ├── src/
│   │   ├── main.jsx         # React app entry point
│   │   ├── App.jsx          # Main app component
│   │   ├── constants.js     # Constants for the frontend, like BASE_PATH
│   │   └── ...              # Other React components and hooks
│   ├── index.html           # HTML template
└── run.py                   # Entry point for development server

Backend

  1. Install FastAPI React Toolkit:

    pip install fastapi-rtk
    mkdir -p app
    touch run.py app/__init__.py app/app.py app/config.py app/models.py app/apis.py
    
  2. Project files:

    app/__init__.py

    from fastapi_rtk import g
    
    g.config.from_pyfile("./app/config.py")
    

    app/app.py

    from fastapi import FastAPI
    from fastapi.middleware.cors import CORSMiddleware
    from fastapi_rtk import FastAPIReactToolkit
    
    app = FastAPI(docs_url="/openapi/v1")
    
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["http://localhost:5173"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    
    toolkit = FastAPIReactToolkit(
        app,
        create_tables=True,      # Dev: auto-create tables
        upgrade_db=False,        # Prod: run migrations
    )
    
    from .apis import *  # noqa: E402, F403
    

    app/config.py

    See more configuration here.

    import os
    
    basedir = os.path.abspath(os.path.dirname(__file__))
    
    # Required settings
    SECRET_KEY = "your-secure-secret-key"
    SQLALCHEMY_DATABASE_URI = "sqlite+aiosqlite:///" + os.path.join(basedir, "app.db")
    
    # Optional settings
    APP_NAME = "My FastAPI-RTK App"
    

    app/models.py

    from fastapi_rtk import Model, Mapped, mapped_column, relationship
    from sqlalchemy import String, ForeignKey
    
    class Category(Model):
        __tablename__ = "categories"
    
        id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
        name: Mapped[str] # Automatically set the column to String
    
        items: Mapped[list["Item"]] = relationship(back_populates="category")
    
        def __repr__(self):
            return self.name
    
    class Item(Model):
        __tablename__ = "items"
    
        id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
        name: Mapped[str] = mapped_column(String(100)) # Can also be explicitly given
        description: Mapped[str | None]
    
        category_id: Mapped[int | None] = mapped_column(ForeignKey("categories.id"))
        category: Mapped[Category | None] = relationship(back_populates="items")
    
        def __repr__(self):
            return self.name
    

    app/apis.py

    from fastapi_rtk import ModelRestApi, SQLAInterface, g
    from .models import Item, Category
    
    class ItemApi(ModelRestApi):
        resource_name = "items"
        datamodel = SQLAInterface(Item)
    
    class CategoryApi(ModelRestApi):
        resource_name = "categories"
        datamodel = SQLAInterface(Category)
    
    g.current_app.add_api(ItemApi)
    g.current_app.add_api(CategoryApi)
    

    It will create the following CRUD endpoints automatically, all under the resource prefix /api/v1/items:

    • GET /api/v1/items/_image/{filename} - Serve image files (If image column is present)
    • GET /api/v1/items/_file/{filename} - Serve file downloads (If file column is present)
    • GET /api/v1/items/_info - Get metadata about the model, including which columns can be added, edited, filtered, etc.
    • POST /api/v1/items/bulk/{handler} - Bulk operations, if set on the API class
    • GET /api/v1/items/download - Download items as CSV
    • GET /api/v1/items/ - List items
    • POST /api/v1/items/ - Create item
    • GET /api/v1/items/{id} - Get item by ID
    • PUT /api/v1/items/{id} - Update item by ID
    • DELETE /api/v1/items/{id} - Delete item by ID

Frontend

  1. Install React dependencies:

    pnpm install @mantine/core @mantine/dates @mantine/form @mantine/hooks dayjs react react-dom react-router fastapi-rtk
    
  2. Project files:

    webapp/index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <base href="%VITE_BASE_PATH%" />
        <link rel="icon" type="image/svg+xml" href="" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0, maximum-scale=1.0"
        />
        <title>YOUR_APP_NAME_HERE</title>
        <script src="%VITE_BASE_PATH%server-config.js"></script>
        <script nonce="{{nonce}}">
          window.nonce = "{{nonce}}";
        </script>
      </head>
      <body>
        <div id="root"></div>
        <script type="module" src="/src/main.jsx"></script>
      </body>
    </html>
    

    src/main.jsx

    import "@mantine/core/styles.css";
    import "@mantine/dates/styles.css";
    // Other Mantine styles can be imported here if needed
    
    import "fastapi-rtk/styles.css";
    import "./index.css";
    
    import { MantineProvider } from "@mantine/core";
    import { Provider } from "fastapi-rtk";
    import { StrictMode } from "react";
    import { createRoot } from "react-dom/client";
    import { BrowserRouter } from "react-router";
    import App from "./App.jsx";
    import { BASE_PATH } from "./constants.js";
    
    createRoot(document.getElementById("root")).render(
      <StrictMode>
        <MantineProvider>
          <Provider baseUrl={BASE_PATH + "api/v1"}>
            <BrowserRouter basename={BASE_PATH}>
              <App />
            </BrowserRouter>
          </Provider>
        </MantineProvider>
      </StrictMode>,
    );
    

    src/constants.js

    export const BASE_PATH = new URL(document.baseURI).pathname;
    

Platform Adapters (React Native)

The frontend package is split in two: a Mantine/DOM-free package published as the fastapi-rtk/api subpath, and the Mantine-based web package (fastapi-rtk / fastapi-rtk/core). Every place the library touches the platform (storage, HTTP, cookies/tokens, file downloads, OAuth popups, FormData) goes through six small adapter interfaces (plus an optional localization adapter), grouped into an Adapters object. fastapi-rtk ships web defaults built on the DOM (cookie auth, localStorage, fetch, ...), so existing web apps need no changes.

An optional fastapi-rtk/react-native-adapters package provides factory functions (createReactNativeAdapters, plus per-adapter factories) that build the same six adapters on top of React Native / Expo primitives, using bearer JWT auth (auth/jwt/login) instead of the web's cookie auth (auth/login):

import { ApiProvider, Provider, useAuth } from "fastapi-rtk/api";
import { useApi } from "fastapi-rtk/contexts";
import { createReactNativeAdapters } from "fastapi-rtk/react-native-adapters";

const rnAdapters = createReactNativeAdapters({
  asyncStorage,
  fileSystem,
  sharing,
  webBrowser,
});

<Provider baseUrl="https://api.example.com/api/v1" adapters={rnAdapters}>
  <ApiProvider resource_name="items">
    {/* your own RN UI, driven by useApi()/useAuth() */}
  </ApiProvider>
</Provider>;

A single adapter can also be swapped on the web Provider via adapters={{ storage: mine }} (merged per-key over the web defaults; the rest stay web defaults).

See the wiki page React Native and Adapters for the full adapter reference (interfaces, per-adapter web/RN table, auth transports).

License

FastAPI-RTK is licensed under the MIT license.

Contributing

Contributions are welcome! Please open an issue or submit a pull request.


For more details, see the Wiki and the example app.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_rtk-2.11.3.tar.gz (518.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_rtk-2.11.3-py3-none-any.whl (281.4 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_rtk-2.11.3.tar.gz.

File metadata

  • Download URL: fastapi_rtk-2.11.3.tar.gz
  • Upload date:
  • Size: 518.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fastapi_rtk-2.11.3.tar.gz
Algorithm Hash digest
SHA256 9bf0538644c1547ae31438a1875b7ea7c5e997dc0d6841dc5f27d343697e677f
MD5 f33f4009345ac4cbd3f8bfc736f21d4d
BLAKE2b-256 be909c23781a685345ef2d23d9c671824f2b11a1a4789c8eda467a1da8c6efe4

See more details on using hashes here.

File details

Details for the file fastapi_rtk-2.11.3-py3-none-any.whl.

File metadata

  • Download URL: fastapi_rtk-2.11.3-py3-none-any.whl
  • Upload date:
  • Size: 281.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.0 {"installer":{"name":"uv","version":"0.12.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for fastapi_rtk-2.11.3-py3-none-any.whl
Algorithm Hash digest
SHA256 88fac20a964da1918ab45d8ae0c9f24c04942541bfe153aca42433feec6b6a23
MD5 8a9718f1ee3f253287f4d1cde60ab78e
BLAKE2b-256 cb3a374c3000c404073c8fc1e71ab4c3870d1c1c0bbe823accf06ac75948915d

See more details on using hashes here.

Release history Release notifications | RSS feed

2.14.0

2 files

2.13.1

2 files

2.13.0

2 files

2.12.4

2 files

2.12.3

2 files

2.12.2

2 files

2.12.1

2 files

2.12.0

2 files

2.11.5

2 files

2.11.4

2 files

This release

2.11.3 This release

2 files

2.11.2

2 files

2.11.1

2 files

2.11.0

2 files

2.10.2

2 files

2.10.1

2 files

2.10.0

2 files

2.9.4

2 files

2.9.3

2 files

2.9.2

2 files

2.9.1

2 files

2.9.0

2 files

2.8.0

2 files

2.7.1

2 files

2.7.0

2 files

2.6.1

2 files

2.6.0

2 files

2.5.1

2 files

2.5.0

2 files

2.4.2

2 files

2.4.1

2 files

2.4.0

2 files

2.3.5

2 files

2.3.4

2 files

2.3.3

2 files

2.3.2

2 files

2.3.1

2 files

2.3.0

2 files

2.2.1

2 files

2.2.0

2 files

2.1.5

2 files

2.1.4

2 files

2.1.3

2 files

2.1.2

2 files

2.1.1

2 files

2.1.0

2 files

2.0.6

2 files

2.0.5

2 files

2.0.4

2 files

2.0.3

2 files

2.0.2

2 files

2.0.1

2 files

2.0.0

2 files

1.1.5

2 files

1.1.4

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.52

2 files

1.0.51

2 files

1.0.50

2 files

1.0.49

2 files

1.0.48

2 files

1.0.47

2 files

1.0.46

2 files

1.0.45

2 files

1.0.44

2 files

1.0.43

2 files

1.0.42

2 files

1.0.41

2 files

1.0.40

2 files

1.0.39

2 files

1.0.38

2 files

1.0.37

2 files

1.0.36

2 files

1.0.35

2 files

1.0.34

2 files

1.0.33

2 files

1.0.32

2 files

1.0.31

2 files

1.0.30

2 files

1.0.29

2 files

1.0.28

2 files

1.0.27

2 files

1.0.26

2 files

1.0.25

2 files

1.0.24

2 files

1.0.23

2 files

1.0.22

2 files

1.0.21

2 files

1.0.20

2 files

1.0.19

2 files

1.0.18

2 files

1.0.17

2 files

1.0.16

2 files

1.0.15

2 files

1.0.14

2 files

1.0.13

2 files

1.0.12

2 files

1.0.11

2 files

1.0.10

2 files

1.0.9

2 files

1.0.8

2 files

1.0.7

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

0.2.62

2 files

0.2.61

2 files

0.2.60

2 files

0.2.59

2 files

0.2.58

2 files

0.2.57

2 files

0.2.56

2 files

0.2.55

2 files

0.2.54

2 files

0.2.53

2 files

0.2.52

2 files

0.2.51

2 files

0.2.50

2 files

0.2.49

2 files

0.2.48

2 files

0.2.47

2 files

0.2.46

2 files

0.2.45

2 files

0.2.44

2 files

0.2.43

2 files

0.2.42

2 files

0.2.41

2 files

0.2.40

2 files

0.2.39

2 files

0.2.38

2 files

0.2.37

2 files

0.2.36

2 files

0.2.35

2 files

0.2.34

2 files

0.2.33

2 files

0.2.32

2 files

0.2.31

2 files

0.2.30

2 files

0.2.29

2 files

0.2.28

2 files

0.2.27

2 files

0.2.26

2 files

0.2.25

2 files

0.2.24

2 files

0.2.23

2 files

0.2.22

2 files

0.2.21

2 files

0.2.20

2 files

0.2.19

2 files

0.2.18

2 files

0.2.17

2 files

0.2.16

2 files

0.2.15

2 files

0.2.14

2 files

0.2.13

2 files

0.2.12

2 files

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

0.1.36

2 files

0.1.35

2 files

0.1.34

2 files

0.1.33

2 files

0.1.32

2 files

0.1.31

2 files

0.1.30

2 files

0.1.29

2 files

0.1.28

2 files

0.1.27

2 files

0.1.26

2 files

0.1.25

2 files

0.1.24

2 files

0.1.23

2 files

0.1.22

2 files

0.1.21

2 files

0.1.20

2 files

0.1.19

2 files

0.1.18

2 files

0.1.17

2 files

0.1.16

2 files

0.1.15

2 files

0.1.14

2 files

0.1.13

2 files

0.1.12

2 files

0.1.11

2 files

0.1.10

2 files

0.1.9

2 files

0.1.8

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

0.0.118

2 files

0.0.117

2 files

0.0.116

2 files

0.0.115

2 files

0.0.114

2 files

0.0.113

2 files

0.0.112

2 files

0.0.111

2 files

0.0.110

2 files

0.0.109

2 files

0.0.108

2 files

0.0.107

2 files

0.0.106

2 files

0.0.105

2 files

0.0.104

2 files

0.0.103

2 files

0.0.102

2 files

0.0.101

2 files

0.0.100

2 files

0.0.99

2 files

0.0.98

2 files

0.0.97

2 files

0.0.96

2 files

0.0.94

2 files

0.0.93

2 files

0.0.92

2 files

0.0.91

2 files

0.0.90

2 files

0.0.89

2 files

0.0.88

2 files

0.0.87

2 files

0.0.86

2 files

0.0.85

2 files

0.0.84

2 files

0.0.83

2 files

0.0.82

2 files

0.0.81

2 files

0.0.80

2 files

0.0.79

2 files

0.0.78

2 files

0.0.77

2 files

0.0.76

2 files

0.0.75

2 files

0.0.74

2 files

0.0.73

2 files

0.0.72

2 files

0.0.71

2 files

0.0.70

2 files

0.0.69

2 files

0.0.68

2 files

0.0.67

2 files

0.0.66

2 files

0.0.65

2 files

0.0.64

2 files

0.0.63

2 files

0.0.62

2 files

0.0.61

2 files

0.0.60

2 files

0.0.59

2 files

0.0.58

2 files

0.0.57

2 files

0.0.56

2 files

0.0.55

2 files

0.0.54

2 files

0.0.53

2 files

0.0.52

2 files

0.0.51

2 files

0.0.50

2 files

0.0.49

2 files

0.0.48

2 files

0.0.47

2 files

0.0.46

2 files

0.0.45

2 files

0.0.44

2 files

0.0.43

2 files

0.0.42

2 files

0.0.41

2 files

0.0.40

2 files

0.0.39

2 files

0.0.38

2 files

0.0.37

2 files

0.0.36

2 files

0.0.35

2 files

0.0.34

2 files

0.0.33

2 files

0.0.32

2 files

0.0.31

2 files

0.0.30

2 files

0.0.29

2 files

0.0.28

2 files

0.0.27

2 files

0.0.26

2 files

0.0.25

2 files

0.0.24

2 files

0.0.23

2 files

0.0.22

2 files

0.0.21

2 files

0.0.20

2 files

0.0.19

2 files

0.0.18

2 files

0.0.17

2 files

0.0.16

2 files

0.0.15

2 files

0.0.14

2 files

0.0.13

2 files

0.0.12

2 files

0.0.11

2 files

0.0.10

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page