A CLI scaffolding tool for FastAPI + SQLModel projects. Stop writing boilerplate — generate models, services, and routers in one command.
craft make:crud Userapp/
models/user.py ← SQLModel table + Pydantic schemas
services/user_services.py ← OOP service with business logic
routers/user_router.py ← Clean FastAPI router
# Install globally as a tool
uv tool install git+https://github.com/Mroshan15200/fastapi-craft
# Or add to your project
uv add git+https://github.com/Mroshan15200/fastapi-craftpip install git+https://github.com/Mroshan15200/fastapi-craftOnce installed, the craft command is available anywhere.
Generates a model, service, and router for a resource.
craft make:crud User
craft make:crud Product --force # overwrite existing files
craft make:crud Order --no-router # skip router generationGenerated files:
app/models/user.py
class UserBase(SQLModel): ... # shared fields
class User(UserBase, table=True): ... # DB table
class UserCreate(UserBase): ...
class UserUpdate(SQLModel): ...
class UserResponse(UserBase): ...app/services/user_services.py
class UserService:
def get(self, db, user_id) -> User: ...
def get_all(self, db, skip, limit) -> List[User]: ...
def create(self, db, data) -> User: ...
def update(self, db, user_id, data) -> User: ...
def delete(self, db, user_id) -> None: ...
user_service = UserService()app/routers/user_router.py
GET /users/ → list all
GET /users/{id} → get one
POST /users/ → create
PUT /users/{id} → update
DELETE /users/{id} → deleteThen register in main.py:
from app.routers.user_router import router as users_router
app.include_router(users_router)Generates just the model file when you don't need a full CRUD setup.
craft make:model Tag
craft make:model AuditLog --no-schemas # table only, no Create/Update/ResponseGenerates a service file for non-CRUD logic.
craft make:service Auth --type auth
craft make:service Recommender --type ml
craft make:service Email # generic (default)| Type | What you get |
|---|---|
auth |
hash_password, verify_password, create_access_token, create_refresh_token, decode_token, get_current_user dependency |
ml |
load(model_path), predict(inputs), health() |
generic |
Clean class shell with a run() stub |
After running craft make:service Auth --type auth:
- Uncomment the
Userimport at the top ofauth_service.py - Uncomment
get_current_user() - Use it in any router:
from app.services.auth_service import get_current_user
@router.get("/me")
def get_me(current_user: User = Depends(get_current_user)):
return current_user
@router.delete("/{id}")
def delete_item(id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db)):
...| Flag | Commands | Description |
|---|---|---|
--force |
all | Overwrite existing files |
--no-router |
make:crud |
Skip router generation |
--no-schemas |
make:model |
Skip Create/Update/Response schemas |
--type |
make:service |
auth | ml | generic |
craft assumes your project looks like this:
your-project/
├── app/
│ ├── database.py ← Session / get_db dependency
│ ├── models/
│ ├── services/
│ └── routers/
├── main.py
└── pyproject.toml
app/database.py should expose a get_db dependency:
from sqlmodel import Session, create_engine
engine = create_engine("sqlite:///db.sqlite3")
def get_db():
with Session(engine) as session:
yield sessionPRs welcome! To work on craft locally:
git clone https://github.com/Mroshan15200/fastapi-craft
cd fastapi-craft
uv sync
uv run craft --helpMIT