civic29/formsetu-backend
0
A FastAPI-based backend service for FormSetu - an AI-powered government form assistant application.
Tech Stack
- Framework: FastAPI (Python)
- Database: PostgreSQL
- ORM: SQLAlchemy
- Authentication: JWT (JSON Web Tokens)
- Password Hashing: bcrypt (via passlib)
Project Structure
src/engine/
├── app/
│ ├── api/
│ │ ├── __init__.py
│ │ ├── auth.py # Authentication routes (signup, login, me)
│ │ └── routes.py # Main API router
│ ├── core/
│ │ ├── __init__.py
│ │ ├── config.py # Application settings
│ │ ├── deps.py # Dependency injection (DB session, auth)
│ │ └── security.py # Password hashing & JWT utilities
│ ├── db/
│ │ ├── __init__.py
│ │ ├── base.py # SQLAlchemy Base
│ │ └── session.py # Database session configuration
│ ├── models/
│ │ ├── __init__.py
│ │ └── user.py # User database model
│ ├── schemas/
│ │ ├── __init__.py
│ │ └── user.py # Pydantic schemas for request/response
│ └── main.py # Application entry point
├── .env # Environment variables (create this)
├── requirements.txt # Python dependencies
└── README.md # This filePrerequisites
- Python 3.10+ installed
- PostgreSQL installed and running
- pip package manager
Setup Instructions
1. Create PostgreSQL Database
Open pgAdmin or use command line:
CREATE DATABASE formsetu;Or via command line (Windows):
$env:PGPASSWORD = "your_password"
& "C:\Program Files\PostgreSQL\18\bin\psql.exe" -U postgres -c "CREATE DATABASE formsetu;"2. Create Virtual Environment (Optional but Recommended)
# From project root
python -m venv .venv
# Activate (Windows PowerShell)
.\.venv\Scripts\Activate.ps1
# Activate (Linux/Mac)
source .venv/bin/activate3. Install Dependencies
cd src/engine
pip install -r requirements.txt4. Configure Environment Variables
Create a .env file in src/engine/:
# Database Configuration
DATABASE_URL=postgresql://postgres:admin@localhost:5432/formsetu
# JWT Configuration
SECRET_KEY=your-super-secret-key-change-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=10080
# Environment
ENVIRONMENT=dev
PROJECT_NAME=FormSetu APINote: Changeadminto your PostgreSQL password and generate a secureSECRET_KEYfor production.
5. Run the Server
cd src/engine
uvicorn app.main:app --reload --port 8000The API will be available at: http://localhost:8000
API Documentation
Once the server is running, access the interactive API docs:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
API Endpoints
Health Check
Authentication
Request/Response Examples
Signup
Request:
POST /api/auth/signup
{
"email": "user@example.com",
"password": "securepassword",
"name": "John Doe",
"phone": "9876543210" // optional
}Response (201 Created):
{
"user": {
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"phone": "9876543210",
"is_active": true,
"created_at": "2024-01-15T10:30:00"
},
"token": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
},
"message": "Account created successfully"
}Login
Request:
POST /api/auth/login
{
"email": "user@example.com",
"password": "securepassword"
}Response (200 OK):
{
"user": {
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"phone": "9876543210",
"is_active": true,
"created_at": "2024-01-15T10:30:00"
},
"token": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
},
"message": "Login successful"
}Get Current User
Request:
GET /api/auth/me
Authorization: Bearer <access_token>Response (200 OK):
{
"id": 1,
"email": "user@example.com",
"name": "John Doe",
"phone": "9876543210",
"is_active": true,
"created_at": "2024-01-15T10:30:00"
}Authentication Flow
┌─────────────────────────────────────────────────────────────┐
│ Authentication Flow │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. SIGNUP │
│ ┌──────────┐ POST /signup ┌──────────┐ │
│ │ Client │ ─────────────────> │ Server │ │
│ │ │ <───────────────── │ │ │
│ └──────────┘ JWT + User Data └──────────┘ │
│ │
│ 2. LOGIN │
│ ┌──────────┐ POST /login ┌──────────┐ │
│ │ Client │ ─────────────────> │ Server │ │
│ │ │ <───────────────── │ │ │
│ └──────────┘ JWT + User Data └──────────┘ │
│ │
│ 3. AUTHENTICATED REQUESTS │
│ ┌──────────┐ GET /me + JWT ┌──────────┐ │
│ │ Client │ ─────────────────> │ Server │ │
│ │ │ <───────────────── │ │ │
│ └──────────┘ User Data └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘Database Schema
Users Table
Security Features
- Password Hashing: Passwords are hashed using bcrypt before storage
- JWT Tokens: Stateless authentication with configurable expiration
- CORS Protection: Configured for allowed frontend origins
- Input Validation: Pydantic schemas validate all input data
- Email Validation: Email format is validated on signup
Error Handling
Development
Running in Development Mode
uvicorn app.main:app --reload --port 8000The --reload flag enables auto-reload on code changes.
Testing with cURL/PowerShell
# Test signup
Invoke-RestMethod -Uri "http://localhost:8000/api/auth/signup" `
-Method POST -ContentType "application/json" `
-Body '{"email":"test@example.com","password":"test123","name":"Test User"}'
# Test login
Invoke-RestMethod -Uri "http://localhost:8000/api/auth/login" `
-Method POST -ContentType "application/json" `
-Body '{"email":"test@example.com","password":"test123"}'Troubleshooting
Common Issues
- Database Connection Error
- Ensure PostgreSQL is running
- Check DATABASE_URL in .env file
- Verify database exists:
\lin psql
- CORS Errors
- Frontend origin must be in allowed origins list
- Check
main.pyfor CORS configuration
- Invalid Token
- Token may be expired (default: 7 days)
- Ensure token is sent in Authorization header as
Bearer <token>
- Module Not Found
- Ensure virtual environment is activated
- Run
pip install -r requirements.txt
Production Deployment
For production, ensure:
- Use a strong, unique
SECRET_KEY - Set
ENVIRONMENT=production - Use HTTPS
- Configure proper CORS origins
- Use environment variables (not .env file)
- Set up proper logging
- Use a process manager (gunicorn, supervisor)
# Production run example
gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000