Inertia package dapater for Nestipy
Project description
Description
Nestipy is a Python framework built on top of FastAPI that follows the modular architecture of NestJS
Under the hood, Nestipy makes use of FastAPI, but also provides compatibility with a wide range of other libraries, like Blacksheep, allowing for easy use of the myriad of third-party plugins which are available.
Getting started
Scaffold a full project (backend + a generated React/Vue/Svelte frontend) with the Nestipy CLI:
nestipy new myapp --fullstack --react # or --vue / --svelte
cd myapp && uv sync && nestipy start --dev
cd inertia && npm install && npm run dev
Or add it to an existing project:
pip install nestipy-inertia
Full manual: https://nestipy.github.io/nestipy/technique/inertia.html
Features
Full latest Inertia.js protocol parity:
- Partial reloads —
only(X-Inertia-Partial-Data),except(X-Inertia-Partial-Except, takes precedence) andX-Inertia-Reset. - Prop helpers —
optional(fn),defer(fn, group=..., merge=...),merge(fn),deep_merge(fn, match_on=[...])(pluslazyalias). - Deferred props (
deferredProps) and merge props (mergeProps/deepMergeProps/matchPropsOn). - History encryption —
res.inertia.encrypt_history()/clear_history()(+InertiaConfig(encrypt_history=True)). - Asset versioning with
409(GET only) +X-Inertia-Location, and automatic302 → 303forPUT/PATCH/DELETE. - Shared props, session flash messages, and Pydantic validation-error handling with error bags.
- SSR via an external Inertia SSR server, with template fallback.
Full example
main.py
import os
import uvicorn
from nestipy.core import NestipyFactory
from nestipy.common import session
from app_module import AppModule, inertia_config
from nestipy_inertia import inertia_head, inertia_body, vite_react_refresh
app = NestipyFactory.create(AppModule)
# set view engine mini jinja and
app.set_base_view_dir(os.path.join(os.path.dirname(__file__), "views"))
# enable session
app.use(session())
if __name__ == '__main__':
uvicorn.run('main:app', host="0.0.0.0", port=8000, reload=True)
app_module.py
import os.path
from nestipy.common import Module
from app_controller import AppController
from app_service import AppService
from nestipy_inertia import InertiaModule, InertiaConfig
@Module(
imports=[
InertiaModule.register(
InertiaConfig(
root_dir=os.path.join(os.getcwd(), "inertia")
)
)
],
controllers=[AppController],
providers=[
AppService,
]
)
class AppModule:
...
vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import nestipyVite from "./nestipy.inertia";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
nestipyVite({
entry: './src/main.tsx',
ssr: './src/ssr.tsx'
}),
],
})
nestipy.inertia.ts
import { PluginOption } from "vite";
type Input = {
entry: string,
ssr?: string,
manifest?: string
}
type NestipyPlugin = (options: Input) => PluginOption
const nestipyVite: NestipyPlugin = ({entry, ssr, manifest = "manifest.json"}) => {
return {
name: "nestipy-vite-plugin",
config: (config, env) => {
return {
...config,
build: {
manifest: env.isSsrBuild ? false: manifest,
outDir: env.isSsrBuild ? "dist/ssr" : "dist",
rollupOptions: {
input: env.isSsrBuild && ssr ? ssr : entry,
},
},
ssr: {
noExternal: ['@inertiajs/server']
}
}
}
}
}
export default nestipyVite
views/index.html
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<link rel="icon" type="image/svg+xml" href="/vite.svg"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Nestipy + Vite + React + TS + Inertia + Mini jinja</title>
{{ inertiaHead() }}
</head>
<body>
{{ viteReactRefresh() }}
{{ inertiaBody() }}
</body>
</html>
app_controller.py
from typing import Annotated
from nestipy.common import Controller, Get, Response, Post
from nestipy.ioc import Inject, Res, Body
from pydantic import BaseModel, EmailStr
from app_service import AppService
from nestipy_inertia import InertiaResponse, optional, defer
class UserLogin(BaseModel):
email: EmailStr
password: str
@Controller()
class AppController:
service: Annotated[AppService, Inject()]
@Get()
async def get(self, res: Annotated[InertiaResponse, Res()]) -> Response:
props = {
"message": "hello from index",
"details": optional(lambda: "loaded only on partial reload"),
"stats": defer(lambda: {"users": 42, "online": 7}),
}
return await res.inertia.render("Index", props)
@Get('/about')
async def about(self, res: Annotated[InertiaResponse, Res()]) -> Response:
return await res.inertia.render("About", {"framework": "Nestipy + Inertia.js"})
@Post("/login")
async def some_form(self, user: Annotated[UserLogin, Body()], res: Annotated[InertiaResponse, Res()]) -> Response:
res.inertia.flash("form submitted", category="success")
return await res.inertia.back()
Viw full example code here.
Support
Nestipy is an MIT-licensed open source project. It can grow thanks to the sponsors and support from the amazing backers. If you'd like to join them, please [read more here].
Stay in touch
- Author - Tsiresy Mila
License
Nestipy is MIT licensed.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nestipy_inertia-0.2.0.tar.gz.
File metadata
- Download URL: nestipy_inertia-0.2.0.tar.gz
- Upload date:
- Size: 12.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90629c16f474ba75af59828396af60f98faea272f90e26a0195dbf762082ddbc
|
|
| MD5 |
e122cbe2a4713b53df8a3420c554deb2
|
|
| BLAKE2b-256 |
bea32e1059c6ed429658c92031d798780c9d1a9331629d583239f8ffb3223a29
|
File details
Details for the file nestipy_inertia-0.2.0-py3-none-any.whl.
File metadata
- Download URL: nestipy_inertia-0.2.0-py3-none-any.whl
- Upload date:
- Size: 16.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.21
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30e779dc4f149d20d8e5efabd9c0a661e32f0af309b6ad1e2c884b4cae95be7d
|
|
| MD5 |
fe660d66ca979d6a2220b2a0278e4407
|
|
| BLAKE2b-256 |
fc73085fbc399c9b3bac0224c0549b75a98c9698747371107026be0b6ec98f82
|