Modern FastAPI Project & Module Generator
FCube CLI is a powerful code generation tool that creates production-ready FastAPI projects and modules following clean architecture principles, dependency injection patterns, and role-based access control.
- Features
- Installation
- Quick Start
- Commands
- Generated Architecture
- Plugin System
- Contributing
- CLI Architecture
- Complete Project Scaffolding - Generate full FastAPI projects with core infrastructure
- Modular User System - Add user module with configurable authentication (email, phone, or both)
- Plugin Architecture - Pre-built feature modules with automatic validation
- Modern Module Structure - Organized directories for models, schemas, crud, services, routes
- Docker Support - docker-compose with PostgreSQL, Redis, Celery, and Flower
- Alembic Migrations - Pre-configured async migrations
- Dependency Injection -
@lru_cachesingleton services with factory functions - Role-Based Routes - Separate public and admin route directories
- Permission System - RBAC with configurable permissions
- Transaction Management - "No Commit in CRUD" pattern
- Rich CLI - Beautiful terminal output with progress indicators
# Using pip
pip install git+https://github.com/amal-babu-git/fcube.git
# Using uv (faster)
uv tool install git+https://github.com/amal-babu-git/fcube.gitgit clone https://github.com/amal-babu-git/fcube.git
cd fcube
# Install globally
pip install .
# Or install in editable mode for development
pip install -e .
# Using uv (recommended for development)
uv sync
source .venv/bin/activategit clone https://github.com/amal-babu-git/fcube.git
cd fcube
# Run using uv
uv run fcube --help
# Or using python module syntax
python -m fcube --helpfcube --version
fcube --help# 1. Create a new project
fcube startproject MyApp
# 2. Navigate to project
cd MyApp
# 3. Add user module with email authentication
fcube adduser --auth-type email
# 4. Add referral plugin
fcube addplugin referral
# 5. Create a custom module
fcube startmodule product
# 6. Start the server
docker compose up -d| Command | Description |
|---|---|
startproject |
Create new FastAPI project with core infrastructure |
adduser |
Add user module with configurable authentication |
addplugin |
Add pre-built plugin modules |
startmodule |
Create a new custom module |
addentity |
Add entity to existing module |
listmodules |
List all existing modules |
version |
Show CLI version |
Creates a new FastAPI project with core infrastructure. User module is not included by default.
# Basic usage
fcube startproject MyProject
# Specify directory
fcube startproject MyApi --dir projects
# Without Celery
fcube startproject SimpleApi --no-celery
# Without Docker
fcube startproject LightApi --no-docker
# Force overwrite
fcube startproject MyProject --forceOptions:
| Option | Description | Default |
|---|---|---|
--dir, -d |
Directory for project | . |
--celery/--no-celery |
Include Celery | yes |
--docker/--no-docker |
Include Docker | yes |
--force, -f |
Overwrite existing files | no |
Generated Structure:
my_project/
βββ app/
β βββ apis/
β β βββ v1.py
β βββ core/
β βββ __init__.py
β βββ database.py
β βββ models.py
β βββ settings.py
β βββ crud.py
β βββ exceptions.py
β βββ logging.py
β βββ main.py
β βββ dependencies.py
β βββ alembic_models_import.py
β βββ celery_app.py
βββ migrations/
βββ docker/
β βββ Dockerfile
β βββ docker-entrypoint.sh
βββ docker-compose.yml
βββ alembic.ini
βββ pyproject.toml
βββ .env.example
βββ .gitignore
βββ README.md
Adds user module with configurable authentication methods.
# Email/password authentication (default)
fcube adduser
# Phone OTP authentication
fcube adduser --auth-type phone
# Both email and phone authentication
fcube adduser --auth-type both
# Force overwrite
fcube adduser --forceOptions:
| Option | Description | Default |
|---|---|---|
--auth-type, -a |
email, phone, or both |
email |
--dir, -d |
App directory | app |
--force, -f |
Overwrite existing | no |
Authentication Types:
| Type | Description | User Fields |
|---|---|---|
email |
Email + password with JWT | email, hashed_password |
phone |
Phone OTP with SMS | phone_number, otp_code |
both |
Combined authentication | All fields + primary_auth_method |
Generated Structure:
app/user/
βββ __init__.py
βββ models.py
βββ schemas.py
βββ crud.py
βββ exceptions.py
βββ auth_management/
β βββ __init__.py
β βββ routes.py
β βββ service.py
β βββ utils.py
βββ permission_management/
β βββ __init__.py
β βββ utils.py
β βββ scoped_access.py
βββ services/
βββ __init__.py
βββ user_referral_integration.py
Adds pre-built feature modules to your project.
# List available plugins
fcube addplugin --list
# Preview plugin (dry run)
fcube addplugin referral --dry-run
# Install plugin
fcube addplugin referral
# Force overwrite
fcube addplugin referral --forceOptions:
| Option | Description | Default |
|---|---|---|
--list, -l |
Show available plugins | - |
--dry-run |
Preview without creating files | no |
--dir, -d |
App directory | app |
--force, -f |
Overwrite existing | no |
Available Plugins:
| Plugin | Description | Dependencies |
|---|---|---|
referral |
User referral system with strategies | user |
Referral Plugin Structure:
app/referral/
βββ __init__.py
βββ models.py
βββ config.py
βββ strategies.py
βββ exceptions.py
βββ dependencies.py
βββ tasks.py
βββ schemas/
β βββ __init__.py
β βββ referral_schemas.py
βββ crud/
β βββ __init__.py
β βββ referral_crud.py
βββ services/
β βββ __init__.py
β βββ referral_service.py
βββ routes/
βββ __init__.py
βββ referral_routes.py
βββ referral_admin_routes.py
Post-Installation Steps:
- Add
referral_codefield to User model - Update
app/apis/v1.pyto include referral routes - Update
app/core/alembic_models_import.py - Run migrations:
alembic revision --autogenerate && alembic upgrade head
Creates a new module with complete folder structure.
# Basic usage
fcube startmodule product
# Without admin routes
fcube startmodule review --no-admin
# Without public routes
fcube startmodule internal_report --no-public
# Force overwrite
fcube startmodule product --forceOptions:
| Option | Description | Default |
|---|---|---|
--dir, -d |
App directory | app |
--admin/--no-admin |
Include admin routes | yes |
--public/--no-public |
Include public routes | yes |
--force, -f |
Overwrite existing | no |
Generated Structure:
app/product/
βββ __init__.py
βββ dependencies.py
βββ exceptions.py
βββ permissions.py
βββ tasks.py
βββ README.md
βββ models/
β βββ __init__.py
β βββ product.py
βββ schemas/
β βββ __init__.py
β βββ product_schemas.py
βββ crud/
β βββ __init__.py
β βββ product_crud.py
βββ services/
β βββ __init__.py
β βββ product_service.py
βββ routes/
β βββ __init__.py
β βββ public/
β β βββ __init__.py
β β βββ product.py
β βββ admin/
β βββ __init__.py
β βββ product_management.py
βββ utils/
β βββ __init__.py
βββ integrations/
βββ __init__.py
Adds a new entity to an existing module.
fcube addentity service_provider availability
fcube addentity booking payment --forceCreates model, schema, and CRUD files for a new entity within an existing module.
fcube listmodules
fcube listmodules --dir appShows all existing modules with their structure.
FCube follows the Layered Architecture pattern:
βββββββββββββββββββββββββββββββββββββββ
β Routes (HTTP Layer) β
β - Request validation β
β - Authentication/Authorization β
β - Response serialization β
βββββββββββββββββ¬ββββββββββββββββββββββ
β
βββββββββββββββββΌββββββββββββββββββββββ
β Services (Business Logic) β
β - Business rules β
β - Transaction boundaries β
β - Orchestration β
βββββββββββββββββ¬ββββββββββββββββββββββ
β
βββββββββββββββββΌββββββββββββββββββββββ
β CRUD (Data Access) β
β - Pure database operations β
β - NO session.commit() β
β - flush() and refresh() only β
βββββββββββββββββ¬ββββββββββββββββββββββ
β
βββββββββββββββββΌββββββββββββββββββββββ
β Models (Database Schema) β
β - SQLAlchemy ORM models β
β - Relationships β
βββββββββββββββββββββββββββββββββββββββ
# dependencies.py
@lru_cache()
def get_product_service() -> ProductService:
return ProductService()
# In routes
@router.get("/")
async def list_products(
service: ProductService = Depends(get_product_service)
):
...# CRUD: No commit
async def create(self, session, obj_in):
db_obj = self.model(**obj_in.model_dump())
session.add(db_obj)
await session.flush()
await session.refresh(db_obj)
# NO commit here
return db_obj
# Service: Owns commit
async def create_product(self, session, data):
product = await product_crud.create(session, obj_in=data)
await session.commit()
await session.refresh(product)
return product# permissions.py
PRODUCTS_READ = "products:read"
PRODUCTS_WRITE = "products:write"
def require_product_write_permission():
return require_permission(PRODUCTS_WRITE)
# In routes
@router.post("/", dependencies=[Depends(require_product_write_permission)])
async def create_product(...):
...The plugin system allows adding pre-built feature modules to any FCube-generated project. Plugins are self-contained with their own models, services, routes, and installation logic.
plugins/
βββ __init__.py # Registry + validation
βββ referral/ # Example plugin
βββ __init__.py # PLUGIN_METADATA + installer
βββ model_templates.py
βββ schema_templates.py
βββ crud_templates.py
βββ service_templates.py
βββ route_templates.py
Each plugin defines its metadata:
PLUGIN_METADATA = PluginMetadata(
name="referral",
description="User referral system",
version="1.0.0",
dependencies=["user"],
files_generated=["app/referral/models.py", ...],
config_required=True,
post_install_notes="...",
installer=install_referral_plugin
)Plugins are automatically validated on registration:
- β Name must be valid Python identifier
- β Version must follow semantic versioning (X.Y.Z)
- β Description must be provided
- β Installer function must be callable
- β Post-install notes must be provided
- β Files list must not be empty
Preview plugin installation before committing:
fcube addplugin referral --dry-runShows:
- All files that would be created
- File sizes
- Whether files would overwrite existing ones
- Post-install steps preview
- Create command file:
fcube/commands/mycommand.py
from rich.console import Console
console = Console()
def mycommand_command(arg: str):
console.print(f"Running with: {arg}")- Register in
fcube/cli.py:
from .commands.mycommand import mycommand_command
@app.command("mycommand")
def mycommand(arg: str):
"""My custom command."""
mycommand_command(arg)-
Create folder:
fcube/templates/plugins/my_plugin/ -
Add template files:
# model_templates.py
def generate_my_plugin_model() -> str:
return '''"""MyPlugin model."""
from app.core.models import Base
class MyPlugin(Base):
__tablename__ = "my_plugins"
'''- Create
__init__.pywith metadata and installer:
from pathlib import Path
from typing import List, Tuple
from .. import PluginMetadata
from .model_templates import generate_my_plugin_model
def install_my_plugin(app_dir: Path) -> List[Tuple[Path, str]]:
"""Self-contained installer."""
plugin_dir = app_dir / "my_plugin"
return [
(plugin_dir / "__init__.py", '"""MyPlugin module."""'),
(plugin_dir / "models.py", generate_my_plugin_model()),
]
PLUGIN_METADATA = PluginMetadata(
name="my_plugin",
description="My awesome plugin",
version="1.0.0",
dependencies=[],
files_generated=[
"app/my_plugin/__init__.py",
"app/my_plugin/models.py",
],
config_required=False,
post_install_notes="Run migrations and start using!",
installer=install_my_plugin,
)- Register in
fcube/templates/plugins/__init__.py:
def _discover_plugins() -> None:
from .referral import PLUGIN_METADATA as referral_metadata
from .my_plugin import PLUGIN_METADATA as my_plugin_metadata
register_plugin(referral_metadata)
register_plugin(my_plugin_metadata)- Done! Run
fcube addplugin my_plugin
FCube uses Python functions returning f-strings for code generation:
- Simple - No complex templating engines like Jinja2
- Fast - Pure Python, no external template parsing
- Type-safe - Full IDE support with type hints
- Easy to debug - Just print the function output
fcube/
βββ __init__.py # Package metadata, version
βββ __main__.py # Entry point for python -m
βββ cli.py # Typer CLI app, command registration
βββ commands/ # Command implementations
β βββ startproject.py # Project scaffolding
β βββ adduser.py # User module generation
β βββ addplugin.py # Plugin installation
β βββ startmodule.py # Module generation
β βββ addentity.py # Entity addition
β βββ listmodules.py # Module listing
βββ templates/ # Code generation templates
β βββ model_templates.py
β βββ schema_templates.py
β βββ crud_templates.py
β βββ service_templates.py
β βββ route_templates.py
β βββ module_templates.py
β βββ project/ # Project-specific templates
β β βββ core/ # Core module templates
β β βββ user/ # User module templates
β β βββ infra/ # Docker, Alembic templates
β βββ plugins/ # Plugin templates
β βββ __init__.py # Plugin registry
β βββ referral/ # Referral plugin
βββ utils/ # Helper utilities
βββ helpers.py # File ops, case conversion
Each template is a Python function that returns a string:
# fcube/templates/model_templates.py
def generate_model(module_snake: str, class_name: str) -> str:
"""Generate a SQLAlchemy model file."""
return f'''"""
{class_name} database model.
"""
from sqlalchemy import String, DateTime
from sqlalchemy.orm import Mapped, mapped_column
from app.core.models import Base
class {class_name}(Base):
__tablename__ = "{module_snake}s"
name: Mapped[str] = mapped_column(String(255), nullable=False)
'''Commands import and use these functions:
# fcube/commands/startmodule.py
from ..templates import generate_model
def startmodule_command(module_name: str):
model_content = generate_model(module_snake, class_name)
write_file(module_dir / "models.py", model_content)1. Registration (_discover_plugins)
β
2. Validation (validate_plugin_metadata)
β
3. Storage (PLUGIN_REGISTRY)
β
4. Installation (install_plugin β plugin.installer)
β
5. File Creation (write_file)
MIT License - see LICENSE for details.
Amal Babu
- GitHub: @amal-babu-git
- Email: amalbabu1200@gmail.com