A FastAPI-based user management system with SQLAlchemy and PostgreSQL.
- User Management: Create, read, update, and delete users
- Authentication: User authentication with user_id and token
- WebSocket Support: Real-time communication with token-based auth
- Message Storage: Store and retrieve WebSocket messages
- Quiz System: Real-time quiz games between two users
- Question Management: Create and manage quiz questions
- Async Operations: Full async support with SQLAlchemy 2.0
- Data Validation: Pydantic v2 models for request/response validation
- Database: PostgreSQL with asyncpg driver
- API Documentation: Automatic OpenAPI/Swagger docs
Users have the following fields:
id: Auto-generated primary keyuser_id: Unique user identifier (string, max 255 chars)token: Authentication token (string, max 500 chars)
- Python 3.9+
- PostgreSQL database
- Virtual environment (recommended)
-
Clone or set up the project:
cd /path/to/your/project -
Create and activate virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
-
Set up environment variables:
Create a
.envfile in the project root:DATABASE_URL=postgresql+asyncpg://username:password@localhost:5432/your_database_name APP_ENV=development DEBUG=True
-
Create database:
Make sure PostgreSQL is running and create a database for the application.
-
Run database migrations (optional, tables are created automatically):
# Tables will be created automatically on startup
python main.pyThe API will be available at:
- API: http://localhost:8000
- API Docs: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
Use a production ASGI server:
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4POST /users/- Create a new userGET /users/- Get all usersGET /users/{user_id}- Get user by user_idPUT /users/{user_id}- Update userDELETE /users/{user_id}- Delete userPOST /users/authenticate- Authenticate user
curl -X POST "http://localhost:8000/users/" \
-H "Content-Type: application/json" \
-d '{"user_id": "user123", "token": "abc123token"}'curl -X GET "http://localhost:8000/users/"curl -X POST "http://localhost:8000/users/authenticate" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "user_id=user123&token=abc123token"WS /ws/connect?token=<user_token>- Main WebSocket connectionWS /ws/echo?token=<user_token>- Echo WebSocket for testing
GET /messages/user/{user_id}- Get messages for a userGET /messages/type/{message_type}- Get messages by typeGET /messages/- Get all messages
Messages should be sent as JSON:
{
"type": "message_type",
"payload": {
"key": "value"
}
}ping- Ping/pong heartbeatuser_data- User data payloadbroadcast- Broadcast message to all users
// JavaScript WebSocket client example
const ws = new WebSocket('ws://localhost:8000/ws/connect?token=your_user_token');
ws.onopen = function(event) {
console.log('Connected to WebSocket');
// Send user data
ws.send(JSON.stringify({
type: 'user_data',
payload: {
location: 'New York',
status: 'online',
customData: 'any data here'
}
}));
};
ws.onmessage = function(event) {
const data = JSON.parse(event.data);
console.log('Received:', data);
};
ws.onclose = function(event) {
console.log('Connection closed');
};ws.send(JSON.stringify({
type: 'ping',
payload: { timestamp: Date.now() }
}));# Get messages for a specific user
curl "http://localhost:8000/messages/user/user123"
# Get messages by type
curl "http://localhost:8000/messages/type/user_data"
# Get all messages
curl "http://localhost:8000/messages/"Question Model:
id: Primary keytext: Question textoption1, option2, option3, option4: Answer optionscorrect_option: Correct answer (1-4)
Quiz Model:
id: Primary keyfirst_user_id: First user IDfirst_user_score: First user scoresecond_user_id: Second user IDsecond_user_score: Second user score
# Create a question
curl -X POST "http://localhost:8000/questions/" \
-H "Content-Type: application/json" \
-d '{
"text": "What is the capital of France?",
"option1": "London",
"option2": "Paris",
"option3": "Berlin",
"option4": "Madrid",
"correct_option": 2
}'# Get all questions
curl "http://localhost:8000/questions/"
# Get random questions
curl "http://localhost:8000/questions/random/5"
# Get specific question
curl "http://localhost:8000/questions/1"# Start quiz session between two users
curl -X POST "http://localhost:8000/quizzes/start-session?first_user_id=user1&second_user_id=user2"Response:
{
"session_id": "uuid-here",
"first_user_id": "user1",
"second_user_id": "user2",
"status": "waiting_for_connections",
"message": "Quiz session created. Both users should connect via WebSocket."
}- Start Session: Create session via REST API
- Connect Users: Both users connect via WebSocket
- Quiz Begins: 10 random questions sent one by one
- Answer Race: First user to answer gets the point
- Score Tracking: Scores updated in real-time
- Completion: Final scores saved and sent to users
// User 1 connects
const ws1 = new WebSocket('ws://localhost:8000/ws/quiz/play?token=user1_token&session_id=session_uuid');
// User 2 connects
const ws2 = new WebSocket('ws://localhost:8000/ws/quiz/play?token=user2_token&session_id=session_uuid');
ws1.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'question') {
// Send answer immediately
ws1.send(JSON.stringify({
user_token: 'user1_token',
question_id: data.question.id,
answer_number: 2 // Your answer
}));
}
if (data.type === 'quiz_complete') {
console.log('Quiz finished!', data.results);
}
};connected: User connected successfullyquiz_starting: Quiz about to beginquestion: New question with optionsanswer_result: Answer processed with scoresquiz_complete: Final results with winner
# Get all quizzes
curl "http://localhost:8000/quizzes/"
# Get user's quizzes
curl "http://localhost:8000/quizzes/user/user1"
# Get quiz result with winner
curl "http://localhost:8000/quizzes/1/result"
# Get active sessions
curl "http://localhost:8000/quizzes/sessions/active"├── api/ # API routes
│ └── users.py # User management endpoints
├── config/ # Configuration files
│ └── database.py # Database configuration
├── models/ # SQLAlchemy models
│ ├── base.py # Base model class
│ └── user.py # User model
├── schemas/ # Pydantic schemas
│ └── user.py # User validation schemas
├── services/ # Business logic
│ └── user_service.py # User service layer
├── tests/ # Test files
├── workers/ # Background workers
├── main.py # FastAPI application
├── requirements.txt # Python dependencies
└── README.md # This file
Run tests with pytest:
pytestRun with coverage:
pytest --cov=.- Type Hints: All functions must have type hints
- Async/Await: Prefer async operations where possible
- PEP 8: Follow Python style guidelines
- F-strings: Use f-strings for string formatting
- Docstrings: Add docstrings to all public functions and classes
- Error Handling: Proper exception handling and meaningful error messages
- Validation: Validate all input data with Pydantic
This project is open source. Feel free to use and modify as needed.