Metadata-Version: 2.4
Name: shafikul_cli
Version: 2.3.0
Summary: CLI tool for FastAPI scaffolding with router, models, database, and templates.
Author-email: Md Shafikul Islam <buildwithshafikul@gmail.com>
Project-URL: Homepage, https://github.com/build-with-shafikul/shafikul_cli
Project-URL: Issues, https://github.com/build-with-shafikul/shafikul_cli/issues
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer
Requires-Dist: rich
Requires-Dist: questionary
Dynamic: license-file

# 🚀 Shafikul CLI

> **Lightning-fast FastAPI Project Scaffolding** — Generate a production-ready FastAPI project with authentication, database models, migrations, and a complete folder structure in seconds.

<div align="center">

![Version](https://img.shields.io/badge/version-2.3.0-blue?style=flat-square)
![Python](https://img.shields.io/badge/python-3.9+-green?style=flat-square)
![License](https://img.shields.io/badge/license-MIT-purple?style=flat-square)
[![GitHub](https://img.shields.io/badge/GitHub-build--with--shafikul-black?style=flat-square&logo=github)](https://github.com/build-with-shafikul/shafikul_cli)

</div>

---

## 📑 Table of Contents

1. [Overview](#-overview)
2. [Features](#-features)
3. [Installation](#-installation)
4. [Quick Start](#-quick-start)
5. [CLI Commands](#-cli-commands)
6. [Creating a Project (`create app`)](#-creating-a-project-create-app)
7. [Creating a Model (`create model`)](#-creating-a-model-create-model)
8. [Adding Routers](#-adding-routers)
9. [Project Structure](#-project-structure)
10. [Authentication](#-authentication)
11. [Database & Migrations](#-database--migrations)
12. [Environment Variables](#-environment-variables)
13. [Dependencies](#-dependencies)
14. [Troubleshooting](#-troubleshooting)
15. [Development & Contributing](#-development--contributing)
16. [License & Author](#-license--author)

---

## 📋 Overview

Shafikul CLI is a **command-line scaffolding tool** that generates a **complete FastAPI project** with best practices built in. Instead of manually creating routers, models, templates, and configuration files, the CLI does it for you — including installing dependencies, initializing Alembic, creating the `users` table, and optionally starting the server.

Perfect for:

- 🎯 **Rapid prototyping** — start building features, not boilerplate
- 👥 **User authentication** — login, logout, and registration pre-configured
- 🗄️ **Database setup** — SQLAlchemy models + Alembic migrations, SQLite or MySQL
- 🎨 **Templates ready** — organized Jinja2 layouts and pages
- ⚡ **Model generator** — create a new model file with one command

---

## ✨ Features

| Feature | Status |
|---------|--------|
| 🏗️ Auto-generate FastAPI project structure | ✅ |
| 📦 Auto-install dependencies | ✅ |
| 🔐 Built-in user authentication (login, logout, registration) | ✅ |
| 🗄️ SQLAlchemy models & Alembic migrations (auto-initialized) | ✅ |
| 🐬 Database choice: **SQLite** or **MySQL** | ✅ |
| 🧱 `create model` command — generates model file & registers it | ✅ |
| 🛣️ Web (HTML) and API (JSON) router structure | ✅ |
| 📝 HTML templates (layouts, pages, error handling) | ✅ |
| 🎨 CSS, JavaScript, and static assets folders | ✅ |
| 🚀 Optional "start server" prompt after setup | ✅ |
| 🧩 Interactive CLI prompts | ✅ |
| 🌈 Colored console output | ✅ |
| 📦 Pip installable package | ✅ |

---

## 📦 Installation

### From PyPI (Recommended)

```bash
pip install shafikul_cli
```

### From Source (Development)

```bash
git clone https://github.com/build-with-shafikul/shafikul_cli.git
cd shafikul_cli
pip install -e .
```

**Requirements:** Python 3.9 or newer.

---

## 🚀 Quick Start

```bash
# 1. Go to the folder where you want to work
cd my_workspace

# 2. Create a new project (answer the interactive prompts)
shafikul_cli create app

# 3. Start the development server
cd my_project
python main.py
```

Then open **http://127.0.0.1:8000** in your browser.

> If you pick **SQLite**, the CLI creates the database, runs the first migration, and can even start the server for you. If you pick **MySQL**, configure `.env` first (see [MySQL setup](#mysql-setup)).

---

## 📖 CLI Commands

| Command | Description |
|---------|-------------|
| `shafikul_cli --help` | Show help and available commands |
| `shafikul_cli --version` / `-V` / `-v` | Show CLI version |
| `shafikul_cli --about` / `-A` / `-a` | Show information about Shafikul CLI |
| `shafikul_cli create app` | Create a complete FastAPI project |
| `shafikul_cli create model <ModelName>` | Create a new SQLAlchemy model inside an existing project |
| `shafikul_cli --install-completion` | Install shell completion |
| `shafikul_cli --show-completion` | Show shell completion script |

```bash
shafikul_cli --help
```

```
 Usage: shafikul_cli [OPTIONS] COMMAND [ARGS]...

 Shafikul CLI for FastAPI

 Options:
   --version             -V,-v   Show CLI version
   --about               -A,-a   Show information about Shafikul CLI
   --install-completion          Install completion for the current shell.
   --show-completion             Show completion for the current shell.
   --help                        Show this message and exit.

 Commands:
   create  Create FastAPI project or model structure
```

---

## 🏗️ Creating a Project (`create app`)

```bash
shafikul_cli create app
```

The CLI shows its banner and then asks two questions.

### Step 1 — Project location

```
? Where do you want to create the project?
```

| Option | Result |
|--------|--------|
| **Current directory** | Project files are created directly in the folder you are in |
| **Default (demo_folder)** | Creates a folder named `demo_folder` in the current directory |
| **New folder** | Asks for a folder name (`Enter your project folder name:`) and creates it |

After you choose, the CLI prints `Project location: <path>`.

### Step 2 — Folder & file generation

The CLI creates all folders and files (`Creating Folder: ...`, `Creating File: ...`) and ends with:

```
Project structure created successfully!
```

### Step 3 — Install dependencies

The CLI installs all packages from `requirements.txt` automatically (`Install Dependencies → 🌐 Installing...`). Packages that are already installed are skipped.

### Step 4 — Select database

```
? Select Database (mysql/sqlite):
```

The default is **SQLite**.

#### SQLite flow (fully automatic)

1. **Migrations Initialize** — Alembic is initialized (`migrations/`, `alembic.ini`)
2. **Configuration updated** — `alembic.ini` / `migrations/env.py` / `.env` are configured for you
3. **Create default users table** — the first migration (`create users table`) is generated
4. **Migrate in DB** — the migration is applied (`alembic upgrade head`)
5. **User table created successfully**
6. Prompt: `🚀 Do you want to start server? (y/n)`
   - `y` → runs `uvicorn main:app --reload` at `http://127.0.0.1:8000`
   - `n` → exit; start later with `python main.py`

#### MySQL flow

1. Alembic is initialized and configured
2. The CLI shows a warning: **configure your MySQL settings in `.env`** before migrating
3. Next step message: *Configuration Success. Then run `python main.py`.*

See [MySQL setup](#mysql-setup) for the remaining steps.

---

## 🧱 Creating a Model (`create model`)

Run this command **inside your project folder** (where `main.py` lives):

```bash
cd my_project
shafikul_cli create model ShafikulModel
```

Output:

```
Model 'ShafikulModel' created successfully!
```

### What it does

**1. Creates a model file** at `app/models/ShafikulModel.py`:

```python
from sqlalchemy import Column, Integer, String, DateTime
from app.database.database import Base

from datetime import datetime

class Shafikulmodel(Base):
    __tablename__ = 'shafikulmodel'
    id = Column(Integer, primary_key=True, index=True)
    # Add More Column....
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
```

- The **file name** keeps the name you typed (`ShafikulModel.py`)
- The **class name** is capitalized (`Shafikulmodel`)
- The **table name** is lowercase (`shafikulmodel`)
- `id`, `created_at`, and `updated_at` columns are included by default
- Add your own columns where the `# Add More Column....` comment is

**2. Registers the model automatically** in `app/models/__init__.py`:

```python
from app.models.users import User

# Add More Models

from app.models.ShafikulModel import Shafikulmodel
```

> Registering the model in `__init__.py` is what lets Alembic detect it for `--autogenerate`.

### After creating a model — migrate

```bash
alembic revision --autogenerate -m "create shafikulmodel table"
alembic upgrade head
```

### Adding columns — example

```python
from sqlalchemy import Column, Integer, String, Boolean, DateTime
from app.database.database import Base
from datetime import datetime

class Product(Base):
    __tablename__ = 'product'
    id = Column(Integer, primary_key=True, index=True)
    title = Column(String(150), nullable=False)
    price = Column(Integer, nullable=False)
    is_active = Column(Boolean, default=True)
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
```

---

## 🛣️ Adding Routers

The project has two router groups:

| Folder | Purpose | Response type |
|--------|---------|---------------|
| `router/web/` | Web pages | HTML (Jinja2 templates) |
| `router/api/` | API endpoints | JSON |

### Registering a Web router

After adding a new file in `router/web/` (for example `blog.py`), register it in `router/web/__init__.py`:

```python
from . import public, auth, error, blog

__all__ = ["public", "auth", "error", "blog"]
```

### Registering an API router

After adding a new file in `router/api/` (for example `products.py`), register it in `router/api/__init__.py`:

```python
from fastapi import FastAPI
from . import users, products

def register_routers(app: FastAPI):
    app.include_router(users.router)
    app.include_router(products.router)
```

### Example API router (`router/api/products.py`)

```python
from fastapi import APIRouter

router = APIRouter(prefix="/api/products", tags=["Products"])

@router.get("/")
def list_products():
    return {"products": []}
```

---

## 📁 Project Structure

Generated structure (SQLite or MySQL, after `create app` and one `create model ShafikulModel`):

```
your-project/
│
├── .env                         # Environment variables (gitignored)
├── .env.example                 # Environment template
├── .gitignore                   # Git ignore rules
├── alembic.ini                  # Alembic configuration
├── main.py                      # FastAPI application entry point
├── README.md                    # Project documentation
├── requirements.txt             # Python dependencies
│
├── app/                         # Application core
│   ├── database/
│   │   └── database.py          # Engine, session, Base
│   └── models/
│       ├── __init__.py          # Model registry (imports all models)
│       ├── users.py             # User model
│       └── ShafikulModel.py     # Created by `create model`
│
├── asset/                       # Source assets
│   ├── css/
│   ├── images/
│   └── js/
│
├── config/
│   └── app.py                   # App settings & constants
│
├── migrations/                  # Alembic migrations
│   ├── env.py
│   ├── README
│   ├── script.py.mako
│   └── versions/                # Generated migration files
│
├── router/
│   ├── api/                     # JSON API routes
│   │   ├── __init__.py          # register_routers(app)
│   │   └── users.py
│   └── web/                     # HTML web routes
│       ├── __init__.py          # exports public, auth, error
│       ├── auth.py              # Login, logout, register
│       ├── error.py             # Error pages
│       └── public.py            # Public pages
│
├── static/                      # Served static files
│   └── images/
│       ├── favicon.ico
│       └── icon.png
│
├── templates/                   # Jinja2 templates
│   ├── layouts/
│   │   ├── auth.html            # Auth layout
│   │   └── main.html            # Main layout
│   └── pages/
│       ├── auth/
│       │   ├── login.html
│       │   └── registater.html  # Registration page
│       ├── authenticated/
│       │   └── dashboard.html   # Protected page
│       ├── error/
│       │   └── notfound.html    # 404 page
│       └── public/
│           └── index.html       # Homepage
│
└── utility/
    └── helper_function.py       # Shared helper functions
```

> **Note:** With SQLite, `migrations/versions/` already contains the `create users table` migration and the `.db` file is created. With MySQL, `versions/` stays empty until you run your first migration.

---

## 🔐 Authentication

Pre-built authentication is included out of the box.

### ✅ Included

- **User registration** — form validation & password hashing
- **User login** — session management with secure cookies
- **User logout** — session cleanup
- **Password security** — Bcrypt & Argon2 hashing
- **Protected routes** — dashboard page for logged-in users
- **User model** — `users` table with indexes on `id`, `name`, and `email`

### 🎯 Default routes

```
GET  /                    → Homepage
GET  /register            → Registration form
POST /register            → Handle registration
GET  /login               → Login form
POST /login               → Handle login
GET  /dashboard           → Protected dashboard
POST /logout              → Logout user
```

Unknown URLs show the custom **404** page (`templates/pages/error/notfound.html`).

---

## 🗄️ Database & Migrations

The CLI sets up **SQLAlchemy** (ORM) and **Alembic** (migrations) automatically. Your choice of **SQLite** or **MySQL** is written into the config.

### Common Alembic commands

```bash
# Apply all migrations
alembic upgrade head

# Create a new migration after changing/adding models
alembic revision --autogenerate -m "Add new column"

# Roll back the last migration
alembic downgrade -1

# Show current revision
alembic current

# Show migration history
alembic history
```

### Typical workflow

1. Create or edit a model (`shafikul_cli create model Product`)
2. Add your columns
3. `alembic revision --autogenerate -m "create product table"`
4. `alembic upgrade head`

### MySQL setup

1. Create a database in MySQL (for example `my_database`)
2. Open `.env` and fill in your MySQL credentials (see [Environment Variables](#-environment-variables))
3. Create and apply the first migration (this includes the `users` table):

   ```bash
   alembic revision --autogenerate -m "create users table"
   alembic upgrade head
   ```

4. Start the server:

   ```bash
   python main.py
   ```

---

## ⚙️ Environment Variables

Settings live in `.env` (a template is provided in `.env.example`). **Never commit `.env`.**

Typical values:

```env
# SQLite (default)
DATABASE_URL=sqlite:///./test.db

# MySQL example
# DATABASE_URL=mysql+pymysql://user:password@localhost:3306/my_database
```

> Check the generated `.env` / `.env.example` for the exact variable names used by your version.

---

## 📦 Dependencies

Installed automatically during `create app`:

| Package | Purpose |
|---------|---------|
| **FastAPI** | Web framework |
| **Uvicorn** | ASGI server |
| **Jinja2** | Template engine |
| **SQLAlchemy** | ORM |
| **Alembic** | Database migrations |
| **Passlib + Bcrypt** | Password hashing |
| **Argon2-CFFI** | Advanced password hashing |
| **python-dotenv** | Environment variables |
| **python-multipart** | Form data parsing |

See the generated `requirements.txt` for the complete list.

Manual install (if needed):

```bash
pip install -r requirements.txt
```

---

## 🐛 Troubleshooting

### `shafikul_cli: command not found`

```bash
pip install shafikul_cli
```

Make sure your Python `Scripts` folder is in `PATH`.

### Port 8000 already in use

Change the port in `main.py`:

```python
uvicorn.run("main:app", host="127.0.0.1", port=8001, reload=True)
```

### `create model` says the project is not found

Run the command from the **project root** (the folder containing `main.py` and `app/`).

### New model not detected by Alembic

Check that the model is imported in `app/models/__init__.py`, then re-run:

```bash
alembic revision --autogenerate -m "your message"
```

### MySQL connection error

- Confirm the MySQL server is running
- Verify credentials and database name in `.env`
- Make sure the database exists

### Database migration failed (SQLite)

Reset the database and re-apply migrations:

```bash
# Windows (cmd)
del test.db
# Linux / macOS / Git Bash
rm test.db

alembic upgrade head
```

### Dependencies already satisfied but app fails

Use a virtual environment to avoid version conflicts:

```bash
python -m venv venv
venv\Scripts\activate        # Windows
source venv/bin/activate     # Linux / macOS
pip install -r requirements.txt
```

---

## 🛠️ Development & Contributing

1. **Fork** the [repository](https://github.com/build-with-shafikul/shafikul_cli/fork)
2. **Create a feature branch**
   ```bash
   git checkout -b feature/your-feature-name
   ```
3. **Make your changes** and test thoroughly
4. **Commit with a clear message**
   ```bash
   git commit -m "Add: description of your feature"
   ```
5. **Push to your fork**
   ```bash
   git push origin feature/your-feature-name
   ```
6. **Open a Pull Request** with a clear description

### Development setup

```bash
git clone https://github.com/build-with-shafikul/shafikul_cli.git
cd shafikul_cli
pip install -e ".[dev]"
```

---

## 📄 License & Author

**License:** MIT — see [LICENSE](https://github.com/build-with-shafikul/shafikul_cli?tab=MIT-1-ov-file).

**Author:** Md Shafikul Islam

- 🔗 [GitHub](https://github.com/build-with-shafikul)
- 📧 [Email](mailto:buildwithshafikul@gmail.com)

---

## ⭐ Show Your Support

If you find this tool helpful, please give it a star on [GitHub](https://github.com/build-with-shafikul/shafikul_cli) — it means a lot! 🙌

<div align="center">

**Made with ❤️ by Md Shafikul Islam**

*Simplifying FastAPI development, one command at a time.*

</div>
