This is a complete conversion of the original Express.js API to Python using FastAPI and SQLAlchemy.
- Express.js → FastAPI (modern async web framework)
- Sequelize ORM → SQLAlchemy (Python ORM)
- express-validator → Pydantic (validation and serialization)
- Morgan → Built-in logging module
- Node.js async/callback pattern → Python
async/awaitwith clean error handling
dbab-api/
├── main.py # Entry point (replaces server.js)
├── app.py # FastAPI app setup (replaces app.js)
├── requirements.txt # Dependencies (replaces package.json)
├── config/
│ └── config.py # Config loader
├── database/
│ └── db.py # SQLAlchemy setup + session management
├── models/
│ ├── appeal_model.py
│ ├── bans_model.py
│ ├── acl_model.py
│ ├── ban_count_model.py
│ └── user_cache_model.py
├── middleware/
│ ├── auth.py # Authentication validation
│ └── logging.py # Request/response logging
├── controllers/ # Business logic
│ ├── appeal_controller.py
│ ├── bans_controller.py
│ ├── acl_controller.py
│ ├── ban_count_controller.py
│ └── user_cache_controller.py
└── routes/ # FastAPI routers
├── appeals_routes.py
├── bans_routes.py
├── cache_routes.py
├── acl_routes.py
└── ban_count_routes.py
pip install -r requirements.txtThe app expects the config at ~/.dbab-config/dbab.json:
{
"mysql": {
"database": "your_database",
"user": "your_user",
"password": "your_password",
"host": "localhost",
"port": 3306
}
}python main.pyThe server will start on http://localhost:3000
FastAPI provides built-in Swagger UI:
- Swagger UI:
http://localhost:3000/docs - ReDoc:
http://localhost:3000/redoc
All endpoints remain compatible with the Node.js version:
GET /appeals- Get all appeals (with pagination)GET /appeals/{appeal_id}- Get single appealPOST /appeals- Create appealDELETE /appeals/{appeal_id}- Delete appeal
GET /bans/{server_id}- Get all bans for serverGET /bans/{server_id}/{user_id}- Get user bansPOST /bans/{server_id}- Add ban
GET /cache- Get all cached usersGET /cache/{user_id}- Get user from cachePOST /cache- Add user to cache
GET /acl- Get all ACL recordsGET /acl/{user_id}/{server_id}- Get ACL by user/serverPUT /acl/{acl_id}- Update permissions
GET /bc- Get all ban countsGET /bc/{server_id}/{user_id}- Get user ban count
All requests (except / and /health) require an Authorization header with a valid API token. The token is validated against the ACL table.
curl -H "Authorization: your_api_token" http://localhost:3000/appealsError responses maintain the same format as the Node.js version:
{
"code": 1,
"message": "SQL_ERROR"
}Common error codes:
1: SQL_ERROR2: NOT_FOUND403: INVALID_TOKEN
Controllers use Python's async/await for all database operations:
async def get_appeal(db: Session, appeal_id: int):
try:
appeal = db.query(Appeal).filter(Appeal.id == appeal_id).first()
return appeal
except Exception as e:
logger.error(f"Error: {e}")
raiseFastAPI's dependency injection manages database sessions via get_db():
@router.get("/{appeal_id}")
async def get_appeal(appeal_id: int, db: Session = Depends(get_db)):
return await appeal_controller.get_appeal(db, appeal_id)Request/response validation is handled by Pydantic models:
class AppealCreate(BaseModel):
userID: str
serverID: str
reason: str
disclaimer: int| Feature | Node.js | Python |
|---|---|---|
| Framework | Express | FastAPI |
| ORM | Sequelize | SQLAlchemy |
| Validation | express-validator | Pydantic |
| Async | Promises/Callbacks | async/await |
| Logging | Morgan | logging module |
| Docs | Manual REST API | Auto-generated (Swagger) |
| Dev Server | nodemon | uvicorn --reload |
# Get all appeals
curl -H "Authorization: your_token" http://localhost:3000/appeals
# Create an appeal
curl -X POST http://localhost:3000/appeals \
-H "Authorization: your_token" \
-H "Content-Type: application/json" \
-d '{"userID": "123", "serverID": "456", "reason": "appeal text", "disclaimer": 1}'
# Get health status
curl http://localhost:3000/health- Add unit tests with pytest
- Add request/response schemas with examples
- Add rate limiting
- Add database migrations (Alembic)
- Add caching layer (Redis)
- Docker containerization