A production-ready FastAPI backend for an AI-powered Blog Generator CMS with multi-step content creation workflow.
- JWT-based authentication with secure token management
- Role-based access control (Admin vs User)
- Argon2 password hashing for maximum security
- 5-step blog creation workflow with exactly 5 options at each step:
- Topic Ideas β Titles β Intros β Outlines β Image Prompts
- Gemini AI integration for intelligent content generation
- AI-generated cover images with custom prompts
- Markdown to HTML conversion with live preview
- Multi-stage publishing workflow:
saved β pending β published/rejected - Admin moderation panel for content approval
- Image upload support (generated or device upload)
- Dashboard statistics for content tracking
- Clean REST API with automatic documentation (Swagger/ReDoc)
- Async MongoDB operations using Motor
- Modular architecture with services and routers
- Type-safe with Pydantic schemas
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β FastAPI App β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββ β
β β Auth β β AI β β Blogs β β Admin β β
β β Router β β Router β β Router β β Router β β
β ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ ββββββ¬ββββββ β
βββββββββΌββββββββββββββΌββββββββββββββΌββββββββββββββΌβββββββββββ€
β ββββββΌββββββββββββββΌββββββββββββββΌββββββββββββββΌβββββββ β
β β Services Layer β β
β β β’ Gemini Service β’ Image Service β’ Markdown β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β MongoDB (Motor) β β
β β β’ users_col β’ blogs_col β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Component | Technology |
|---|---|
| Framework | FastAPI |
| Database | MongoDB (Motor async driver) |
| Authentication | JWT (python-jose) |
| Password Security | Argon2 (argon2-cffi) |
| AI Engine | Google Gemini AI |
| Markdown Parser | markdown |
| Server | Uvicorn (ASGI) |
- Python 3.10+ (Python 3.11 recommended)
- MongoDB (local installation or MongoDB Atlas)
- Google Gemini API Key (Get one here)
git clone <repository-url>
cd backendWindows (PowerShell):
python -m venv venv
.\venv\Scripts\Activate.ps1Linux/macOS:
python -m venv venv
source venv/bin/activatepython -m pip install -U pip
pip install -r requirements.txtCreate a .env file in the backend/ directory:
# Application
APP_NAME=CMS Blog API
ENV=dev
# Database
MONGODB_URI=mongodb://localhost:27017
MONGODB_DB=cms_blog
# Security
JWT_SECRET=your-super-secret-key-change-this
JWT_EXPIRES_MINUTES=10080
# Admin Account
ADMIN_EMAIL=admin@company.com
# CORS & Public URL
CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
PUBLIC_BASE_URL=http://127.0.0.1:8000
# Gemini AI
GEMINI_API_KEY=your_gemini_api_key_here
GEMINI_TEXT_MODEL=gemini-2.0-flash-exp
GEMINI_IMAGE_MODEL=imagen-3.0-generate-001π‘ Tip: Make sure to get your Gemini API key from Google AI Studio.
uvicorn main:app --reload --port 8000The API will be available at:
- API: http://localhost:8000
- Swagger Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
backend/
βββ π main.py # Application entrypoint
βββ π requirements.txt # Python dependencies
βββ π .env # Environment config (DO NOT COMMIT)
βββ π .gitignore # Git ignore rules
βββ π uploads/ # Generated/uploaded images
βββ π venv/ # Virtual environment
β
βββ π core/
β βββ π __init__.py
β βββ π config.py # Settings & environment config
β βββ π deps.py # Auth dependencies
β βββ π verify.py # Token verification utilities
β
βββ π app/
β βββ π __init__.py
β β
β βββ π models/
β β βββ π __init__.py
β β βββ π db.py # MongoDB connection & collections
β β βββ π schemas.py # Pydantic models
β β
β βββ π routers/
β β βββ π __init__.py
β β βββ π auth.py # Signup/Login endpoints
β β βββ π ai.py # AI generation endpoints
β β βββ π blogs.py # Blog CRUD & workflow
β β βββ π admin.py # Admin moderation panel
β β
β βββ π services/
β βββ π __init__.py
β βββ π gemini_service.py # Gemini AI integration
β βββ π image_service.py # Image generation
β βββ π markdown_service.py # Markdown β HTML
| Method | Endpoint | Description |
|---|---|---|
POST |
/auth/auth/signup |
Register new user |
POST |
/auth/auth/login |
Login and get JWT token |
| Method | Endpoint | Description |
|---|---|---|
POST |
/ai/ideas |
Generate topic ideas (default 5, accepts count) |
POST |
/ai/titles |
Generate 5 titles for selected topic |
POST |
/ai/intros |
Generate 5 intro paragraphs |
POST |
/ai/outlines |
Generate 5 blog outlines |
POST |
/ai/image-prompts |
Generate 5 image prompts |
POST |
/ai/image-generate |
Generate single cover image |
POST |
/ai/blog-generate |
Generate final blog (Markdown + HTML) |
| Method | Endpoint | Description |
|---|---|---|
POST |
/blog |
save final blog |
GET |
/blog |
List current user's blogs |
GET |
/blogs/stats |
Get blog statistics for dashboard |
POST |
/blogs/uploads/images |
Upload custom cover image |
GET |
/blogs/{blog_id} |
Get single blog by ID |
POST |
/blogs/{blog_id}/publish-request |
Request admin approval for publishing |
| Method | Endpoint | Description |
|---|---|---|
GET |
/admin/blogs |
List all blogs with optional status filter |
POST |
/admin/blogs/{blog_id}/approve |
Approve blog for publishing |
POST |
/admin/blogs/{blog_id}/reject |
Reject blog with feedback message |
graph LR
A[Topic Ideas] --> B[Titles]
B --> C[Intros]
C --> D[Outlines]
D --> E[Image Prompts]
E --> F[Generate Image]
F --> G[Generate Blog]
G --> H[Save Draft]
H --> I[Request Publish]
I --> J{Admin Review}
J -->|Approve| K[Published]
J -->|Reject| L[Rejected]
Each step provides exactly 5 options to choose from, ensuring a guided and structured content creation process.
- JWT Authentication with configurable expiration
- Argon2 Password Hashing (industry standard)
- Role-Based Access Control (RBAC)
- CORS Protection with whitelist
- Environment-based Configuration (no hardcoded secrets)
{
"_id": "ObjectId",
"email": "user@example.com",
"password_hash": "argon2$...",
"role": "user|admin",
"created_at": "ISO-8601"
}{
"_id": "ObjectId",
"owner": "user_id",
"status": "saved|pending|published|rejected",
"title": "Blog Title",
"intro": "Introduction text",
"outline": ["Section 1", "Section 2"],
"image_url": "/uploads/image.png",
"markdown": "# Blog content...",
"html": "<h1>Blog content...</h1>",
"created_at": "ISO-8601",
"admin_feedback": "Optional rejection reason"
}uvicorn main:app --reload --port 8000- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Automatically created on startup:
- Users: Unique index on
email - Blogs: Indexes on
status,owner,created_at
Ensure all required environment variables are set in production:
- Set
ENV=production - Use strong
JWT_SECRET - Configure
MONGODB_URIfor MongoDB Atlas - Set
PUBLIC_BASE_URLto your domain
- Backend: FastAPI on Docker/Railway/Render
- Database: MongoDB Atlas
- Static Files: CDN for uploaded images
- Reverse Proxy: Nginx or Caddy