A Django-inspired MVT framework built on top of FastAPI
Project description
FastAPI MVT
A batteries-included project framework for FastAPI — structured, fast to start, and built for developers who want Django's ergonomics with FastAPI's performance.
Overview
FastAPI MVT is a project scaffolding framework built on top of FastAPI.
It gives you a full project skeleton the moment you run one command — with authentication, database, WebSocket, signals, middleware, and CLI management all wired together and ready to use.
You write your business logic. The framework handles the plumbing.
Features
| Feature | Description |
|---|---|
| MVT Pattern | Model → View → Template architecture familiar to Django developers |
| JWT Authentication | Built-in /auth router with register, login, logout, refresh, and /me endpoints |
| SQLAlchemy + Alembic | Async-ready ORM with full migration support via makemigrations / migrate |
| Signals | Django-style ORM signals (pre_save, post_save, pre_delete, post_delete) wired automatically via SQLAlchemy events |
| WebSocket Manager | Group-aware connection manager with optional Redis channel backend for multi-process scaling |
| Security Middleware | CORS, security headers, rate limiting, and SQL injection protection out of the box |
| App Registry | Auto-discovery system for routers, models, and signals across multiple apps |
| CLI Management | startproject, startapp, makemigrations, migrate, checkmigrations commands |
Tech Stack
- FastAPI — high-performance async web framework
- SQLAlchemy 2.0 — modern ORM with async support
- Alembic — database schema migration tool
- Pydantic v2 — data validation and settings management
- python-jose — JWT token signing and verification
- Typer — CLI built on Click
- Jinja2 — templating engine
- Celery + Redis — background task queue
- websockets — WebSocket support with Redis pub/sub scaling
Installation
pip install fastapi-mvt
Or install from source:
git clone https://github.com/yourusername/fastapi-mvt
cd fastapi-mvt
pip install -e .
Quick Start
1. Create a new project
fastapi-mvt startproject myproject
cd myproject
2. Create an app
fastapi-mvt startapp blog
3. Run migrations
fastapi-mvt makemigrations
fastapi-mvt migrate
4. Start the server
uvicorn myproject.asgi:app --reload
Project Structure
After running startproject, you get:
myproject/
├── manage.py # CLI entry point
├── .env # Environment variables
├── myproject/
│ ├── settings.py # Project settings (INSTALLED_APPS, DB, etc.)
│ ├── urls.py # Root router
│ └── asgi.py # ASGI application entry point
├── apps/
│ └── blog/ # An example app (via startapp)
│ ├── models.py # SQLAlchemy models
│ ├── views.py # FastAPI route handlers
│ ├── schemas.py # Pydantic schemas
│ ├── signals.py # Signal receivers
│ └── router.py # APIRouter definition
└── migrations/
└── versions/ # Alembic migration files
Core Concepts
Authentication
FastAPI MVT ships a plug-and-play JWT auth system. Configure it once in settings.py:
from fastapi_mvt.auth import configure_auth, AuthConfig
configure_auth(AuthConfig(
secret_key="your-secret-key",
user_model="apps.accounts.models.User", # omit to use built-in DefaultAuthUser
))
Then include the built-in auth router:
from fastapi import FastAPI
from fastapi_mvt.auth import auth_router
app = FastAPI()
app.include_router(auth_router)
Available endpoints:
| Method | Path | Description |
|---|---|---|
POST |
/auth/register |
Create account, returns token pair |
POST |
/auth/login |
Authenticate, returns token pair |
POST |
/auth/logout |
Revoke access token |
POST |
/auth/refresh |
Exchange refresh token for new access token |
GET |
/auth/me |
Return authenticated user identity |
Protect your own routes with the get_current_user dependency:
from fastapi import Depends
from fastapi_mvt.auth import get_current_user
@router.get("/profile")
def profile(user=Depends(get_current_user)):
return {"id": user.id, "email": user.email}
Signals
Signals fire automatically when SQLAlchemy models are saved or deleted — no manual .send() calls needed inside views.
from fastapi_mvt.core.signals import receiver, post_save
from apps.blog.models import Post
@receiver(post_save, sender=Post)
async def on_post_saved(sender, instance, created, **kwargs):
if created:
print(f"New post published: {instance.title}")
Register signals during startup:
from fastapi_mvt.core.signals import register_all_model_signals
from myproject.db import Base
register_all_model_signals(Base)
Available signals: pre_save, post_save, pre_delete, post_delete, post_init
WebSocket
A group-aware WebSocket connection manager is included. For multi-process deployments, swap in the Redis backend:
from fastapi_mvt.utils.websocket import ConnectionManager, RedisChannelBackend
import redis.asyncio as aioredis
redis_client = aioredis.from_url("redis://localhost")
manager = ConnectionManager(channel_backend=RedisChannelBackend(redis_client))
Use in route handlers:
from fastapi import WebSocket
from fastapi_mvt.utils.websocket import manager
@app.websocket("/ws/{room}")
async def websocket_endpoint(websocket: WebSocket, room: str):
conn_id = await manager.connect(websocket, group=room)
try:
while True:
data = await websocket.receive_text()
await manager.send_to_group(room, {"message": data})
finally:
await manager.disconnect(conn_id)
Middleware
Security middleware is applied automatically. You can also configure it manually:
from fastapi_mvt.middleware import setup_security_middleware, setup_cors_middleware
setup_cors_middleware(app, origins=["https://example.com"])
setup_security_middleware(app)
Built-in middleware:
SecurityHeadersMiddleware— addsX-Content-Type-Options,X-Frame-Options,HSTS,CSP, and moreSQLInjectionProtectionMiddleware— blocks common SQL injection patterns in request parametersRateLimitMiddleware— request-rate throttling per IPCustomMiddleware— base class for your own middleware
App Registry
Register apps in settings.py and the framework auto-discovers their routers, models, and signals:
INSTALLED_APPS = [
"apps.blog",
"apps.accounts",
]
CLI Reference
| Command | Description |
|---|---|
fastapi-mvt startproject <name> |
Scaffold a new project |
fastapi-mvt startapp <name> |
Scaffold a new app inside a project |
fastapi-mvt makemigrations [app] |
Generate Alembic migration from model changes |
fastapi-mvt migrate |
Apply pending migrations to the database |
fastapi-mvt checkmigrations |
Report empty or no-op migration files |
Configuration
All settings live in your project's settings.py. Key options:
# Database
DATABASE_URL = "sqlite+aiosqlite:///./db.sqlite3"
# DATABASE_URL = "postgresql+asyncpg://user:pass@localhost/dbname"
# Auth
SECRET_KEY = "change-me-in-production"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
REFRESH_TOKEN_EXPIRE_DAYS = 7
# Apps
INSTALLED_APPS = [
"apps.blog",
"apps.accounts",
]
# CORS
CORS_ORIGINS = ["http://localhost:3000"]
Documentation
Full documentation is available at https://odaithalji.gitbook.io/fastapi
License
MIT License — see LICENSE for details.
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 fastapi_mvt-0.1.2.tar.gz.
File metadata
- Download URL: fastapi_mvt-0.1.2.tar.gz
- Upload date:
- Size: 48.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d1a02351f234a373c79027434510c3535bd922aadebe2f03681add6d9b8912e
|
|
| MD5 |
643975faa57ca62e5c730b002e35834b
|
|
| BLAKE2b-256 |
9b427d9b3162861f878bfad20a6f3ae0a8e6e379d76a80bdb7618e3d2aaeb8e1
|
Provenance
The following attestation bundles were made for fastapi_mvt-0.1.2.tar.gz:
Publisher:
workflow.yml on OdaiAhmed99/fastapi-mvt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_mvt-0.1.2.tar.gz -
Subject digest:
1d1a02351f234a373c79027434510c3535bd922aadebe2f03681add6d9b8912e - Sigstore transparency entry: 1539627019
- Sigstore integration time:
-
Permalink:
OdaiAhmed99/fastapi-mvt@fb645bdc6da22e641e16766150a39d12aa0f6894 -
Branch / Tag:
refs/tags/0.1.002 - Owner: https://github.com/OdaiAhmed99
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@fb645bdc6da22e641e16766150a39d12aa0f6894 -
Trigger Event:
release
-
Statement type:
File details
Details for the file fastapi_mvt-0.1.2-py3-none-any.whl.
File metadata
- Download URL: fastapi_mvt-0.1.2-py3-none-any.whl
- Upload date:
- Size: 53.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
244cdb1a9b4114ac1125e84b8ada8e7eefd4a082cf65d9623fd8658bceccd324
|
|
| MD5 |
c4fad32ec096b335614e3234ac70921e
|
|
| BLAKE2b-256 |
6cabb07da577b02d091a6926b6e20679999c10e7aeed719872b068bc379ed205
|
Provenance
The following attestation bundles were made for fastapi_mvt-0.1.2-py3-none-any.whl:
Publisher:
workflow.yml on OdaiAhmed99/fastapi-mvt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fastapi_mvt-0.1.2-py3-none-any.whl -
Subject digest:
244cdb1a9b4114ac1125e84b8ada8e7eefd4a082cf65d9623fd8658bceccd324 - Sigstore transparency entry: 1539627183
- Sigstore integration time:
-
Permalink:
OdaiAhmed99/fastapi-mvt@fb645bdc6da22e641e16766150a39d12aa0f6894 -
Branch / Tag:
refs/tags/0.1.002 - Owner: https://github.com/OdaiAhmed99
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@fb645bdc6da22e641e16766150a39d12aa0f6894 -
Trigger Event:
release
-
Statement type: