webquiz


Namewebquiz JSON
Version 1.5.4 PyPI version JSON
download
home_pageNone
SummaryA modern web-based quiz and testing system built with Python and aiohttp
upload_time2025-10-14 13:38:04
maintainerNone
docs_urlNone
authorOleksandr Liabakh
requires_python<4.0,>=3.9
licenseMIT
keywords quiz testing aiohttp web assessment education
VCS
bugtrack_url
requirements aiohttp PyYAML aiofiles pytest pytest-asyncio pytest-xdist requests selenium webdriver-manager pytest-html
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # WebQuiz

A modern web-based quiz and testing system built with Python and aiohttp that allows users to take multiple-choice tests with real-time answer validation and performance tracking.

## โœจ Features

- **User Management**: Unique username registration with UUID-based session tracking
- **Multi-Quiz System**: Questions loaded from `quizzes/` directory with multiple YAML files
- **Admin Interface**: Web-based admin panel with master key authentication for quiz management
- **Registration Approval**: Optional admin approval workflow for new registrations with real-time notifications
- **Question Randomization**: Configurable per-student question order randomization for fair testing
- **Dynamic Quiz Switching**: Real-time quiz switching with automatic server state reset
- **Config File Editor**: Web-based configuration editor with real-time validation
- **Live Statistics**: Real-time WebSocket-powered dashboard showing user progress
- **Real-time Validation**: Server-side answer checking with immediate feedback
- **Session Persistence**: Cookie-based user sessions for seamless experience
- **Performance Tracking**: Server-side timing for accurate response measurement
- **Data Export**: Automatic CSV export with quiz-prefixed filenames and unique suffixes
- **Responsive UI**: Clean web interface with dark/light theme support
- **Binary Distribution**: Standalone PyInstaller executable with auto-configuration
- **Comprehensive Testing**: 210+ tests covering all functionality with CI/CD pipeline
- **Flexible File Paths**: Configurable paths for quizzes, logs, CSV, and static files

## ๐Ÿš€ Quick Start

### Prerequisites

- Python 3.9+ (required by aiohttp)
- Poetry (recommended) or pip
- Git

### Installation with Poetry (Recommended)

1. **Clone the repository**
   ```bash
   git clone git@github.com:oduvan/webquiz.git
   cd webquiz
   ```

2. **Install with Poetry**
   ```bash
   poetry install
   ```

3. **Run the server**
   ```bash
   webquiz           # Foreground mode
   webquiz -d        # Daemon mode
   ```

4. **Open your browser**
   ```
   http://localhost:8080
   ```

The server will automatically create necessary directories and files on first run.

### Alternative Installation with pip

1. **Clone and set up virtual environment**
   ```bash
   git clone git@github.com:oduvan/webquiz.git
   cd webquiz
   python3 -m venv venv
   source venv/bin/activate  # On Windows: venv\Scripts\activate
   ```

2. **Install dependencies**
   ```bash
   pip install -r requirements.txt
   ```

3. **Run the server**
   ```bash
   python -m webquiz.cli
   ```

The server will automatically create necessary directories and files on first run.

## ๐Ÿ“ Project Structure

```
webquiz/
โ”œโ”€โ”€ pyproject.toml           # Poetry configuration and dependencies
โ”œโ”€โ”€ requirements.txt         # Legacy pip dependencies
โ”œโ”€โ”€ .gitignore              # Git ignore rules
โ”œโ”€โ”€ CLAUDE.md               # Project documentation
โ”œโ”€โ”€ README.md               # This file
โ”œโ”€โ”€ webquiz/                # Main package
โ”‚   โ”œโ”€โ”€ __init__.py        # Package initialization
โ”‚   โ”œโ”€โ”€ cli.py             # CLI entry point (webquiz command)
โ”‚   โ”œโ”€โ”€ server.py          # Main application server
โ”‚   โ”œโ”€โ”€ build.py           # PyInstaller binary build script
โ”‚   โ”œโ”€โ”€ binary_entry.py    # Binary executable entry point
โ”‚   โ”œโ”€โ”€ version_check.py   # Version update checking
โ”‚   โ”œโ”€โ”€ server_config.yaml.example  # Configuration example
โ”‚   โ””โ”€โ”€ templates/         # HTML templates
โ”‚       โ”œโ”€โ”€ index.html                     # Main quiz interface
โ”‚       โ”œโ”€โ”€ admin.html                     # Admin management panel
โ”‚       โ”œโ”€โ”€ files.html                     # File manager interface
โ”‚       โ”œโ”€โ”€ live_stats.html                # Live statistics dashboard
โ”‚       โ”œโ”€โ”€ quiz_selection_required.html   # Quiz selection prompt
โ”‚       โ””โ”€โ”€ template_error.html            # Error page template
โ”œโ”€โ”€ tests/                  # Test suite (14 test files)
โ”‚   โ”œโ”€โ”€ conftest.py                      # Test fixtures and configuration
โ”‚   โ”œโ”€โ”€ test_cli_directory_creation.py   # CLI and directory tests
โ”‚   โ”œโ”€โ”€ test_admin_api.py                # Admin API tests
โ”‚   โ”œโ”€โ”€ test_admin_quiz_management.py    # Quiz management tests
โ”‚   โ”œโ”€โ”€ test_config_management.py        # Config editor tests
โ”‚   โ”œโ”€โ”€ test_registration_approval.py    # Registration approval tests
โ”‚   โ”œโ”€โ”€ test_registration_fields.py      # Registration fields tests
โ”‚   โ”œโ”€โ”€ test_index_generation.py         # Template generation tests
โ”‚   โ”œโ”€โ”€ test_files_management.py         # File manager tests
โ”‚   โ”œโ”€โ”€ test_integration_multiple_choice.py  # Multiple choice integration tests
โ”‚   โ”œโ”€โ”€ test_multiple_answers.py         # Multiple answer tests
โ”‚   โ”œโ”€โ”€ test_show_right_answer.py        # Show answer tests
โ”‚   โ”œโ”€โ”€ test_selenium_multiple_choice.py # Selenium multiple choice tests
โ”‚   โ”œโ”€โ”€ test_selenium_registration_fields.py # Selenium registration tests
โ”‚   โ””โ”€โ”€ test_user_journey_selenium.py    # Selenium user journey tests
โ””โ”€โ”€ .github/
    โ””โ”€โ”€ workflows/
        โ””โ”€โ”€ test.yml       # CI/CD pipeline

# Generated at runtime (excluded from git):
โ””โ”€โ”€ quizzes/               # Quiz files directory
    โ”œโ”€โ”€ default.yaml      # Default quiz (auto-created)
    โ””โ”€โ”€ *.yaml            # Additional quiz files
```

## ๐Ÿ–ฅ๏ธ CLI Commands

The `webquiz` command provides several options:

```bash
# Start server in foreground (default)
webquiz

# Start server with admin interface (requires master key)
webquiz --master-key secret123

# Start server with custom directories
webquiz --quizzes-dir my_quizzes
webquiz --logs-dir /var/log
webquiz --csv-dir /data
webquiz --static /var/www/quiz

# Combine multiple options
webquiz --master-key secret123 --quizzes-dir quizzes --logs-dir logs

# Set master key via environment variable
export WEBQUIZ_MASTER_KEY=secret123
webquiz

# Start server as daemon (background)
webquiz -d
webquiz --daemon

# Stop daemon server
webquiz --stop

# Check daemon status
webquiz --status

# Show help
webquiz --help

# Show version
webquiz --version
```

### Key Options

- `--master-key`: Enable admin interface with authentication
- `--quizzes-dir`: Directory containing quiz YAML files (default: `./quizzes`)
- `--logs-dir`: Directory for server logs (default: current directory)
- `--csv-dir`: Directory for CSV exports (default: current directory)
- `--static`: Directory for static files (default: `./static`)
- `-d, --daemon`: Run server in background
- `--stop`: Stop daemon server
- `--status`: Check daemon status

### Daemon Mode Features

- **Background execution**: Server runs independently in background
- **PID file management**: Automatic process tracking via `webquiz.pid`
- **Graceful shutdown**: Proper cleanup on stop
- **Status monitoring**: Check if daemon is running
- **Log preservation**: All output still goes to `server.log`

## ๐Ÿš€ Release Management

This project uses GitHub Actions for automated versioning, PyPI deployment, and GitHub Release creation.

### Creating a New Release

1. **Go to GitHub Actions** in the repository
2. **Select "Release and Deploy to PyPI" workflow**
3. **Click "Run workflow"**
4. **Enter the new version** (e.g., `1.0.6`, `2.0.0`)
5. **Click "Run workflow"**

The action will automatically:
- โœ… Update version in `pyproject.toml` and `webquiz/__init__.py`
- โœ… Run tests to ensure everything works
- โœ… Commit the version changes
- โœ… Create a git tag with the version
- โœ… Build the package using Poetry
- โœ… Publish to PyPI
- ๐Ÿ†• **Create a GitHub Release** with built artifacts

### What's included in GitHub Releases

Each release automatically includes:
- ๐Ÿ“ฆ **Python wheel package** (`.whl` file)
- ๐Ÿ“‹ **Source distribution** (`.tar.gz` file)
- ๐Ÿ“ **Formatted release notes** with installation instructions
- ๐Ÿ”— **Links to commit history** for detailed changelog
- ๐Ÿ“‹ **Installation commands** for the specific version

### Prerequisites for Release Deployment

Repository maintainers need to set up:
- `PYPI_API_TOKEN` secret in GitHub repository settings
- PyPI account with publish permissions for the `webquiz` package
- `GITHUB_TOKEN` is automatically provided by GitHub Actions

## ๐Ÿงช Testing

Run the comprehensive test suite:

```bash
# With Poetry
poetry run pytest

# Or directly
pytest tests/

# Run with verbose output
pytest tests/ -v

# Run in parallel with 4 workers
pytest tests/ -v -n 4

# Run specific test file
pytest tests/test_admin_api.py
pytest tests/test_registration_approval.py
```

### Test Coverage

The project has **210+ tests** across **14 test files** covering:

- **CLI and Directory Creation** (7 tests): Directory and file creation
- **Admin API** (14 tests): Admin interface and authentication
- **Admin Quiz Management** (18 tests): Quiz switching and management
- **Config Management** (16 tests): Config editor and validation
- **Registration Approval** (20 tests): Approval workflow and timing
- **Files Management** (32 tests): File manager interface
- **Index Generation** (13 tests): Template generation tests
- **Registration Fields** (12 tests): Custom registration fields
- **Show Right Answer** (5 tests): Answer display functionality
- **Integration Tests** (6 tests): Multiple choice, multiple answers
- **Selenium Tests** (56 tests): End-to-end browser testing

The test suite uses GitHub Actions CI/CD for automated testing on every commit.

## ๐Ÿ“‹ Configuration Format

### Quiz Files

Questions are stored in YAML files in the `quizzes/` directory. The server automatically creates a `default.yaml` file if the directory is empty.

**Example quiz file** (`quizzes/math_quiz.yaml`):

```yaml
title: "Mathematics Quiz"
randomize_questions: true  # Set to true to randomize question order for each student (default: false)
questions:
  - question: "What is 2 + 2?"
    options:
      - "3"
      - "4"
      - "5"
      - "6"
    correct_answer: 1  # 0-indexed (option "4")

  - question: "What is 5 ร— 3?"
    options:
      - "10"
      - "15"
      - "20"
      - "25"
    correct_answer: 1  # 0-indexed (option "15")
```

**Question Randomization:**
- Set `randomize_questions: true` in your quiz YAML to give each student a unique question order
- Each student receives a randomized order that persists across sessions
- Helps prevent cheating and ensures fair testing
- Default is `false` (questions appear in YAML order)

### Server Configuration

Optional server configuration file (`webquiz.yaml`):

```yaml
server:
  host: "0.0.0.0"
  port: 8080

registration:
  approve: false  # Set to true to require admin approval
  fields:
    - name: "full_name"
      label: "Full Name"
      required: true

quiz:
  show_right_answer: false  # Show correct answer after submission
```

All configuration sections are optional and have sensible defaults.

## ๐Ÿ“Š Data Export

User responses are automatically exported to CSV files with quiz-prefixed filenames and unique suffixes to prevent overwrites:

**Example:** `math_quiz_user_responses_0001.csv`

```csv
user_id,question,selected_answer,correct_answer,is_correct,time_taken_seconds
123456,"What is 2 + 2?","4","4",True,3.45
123456,"What is 5 ร— 3?","15","15",True,2.87
```

CSV files are created with proper escaping and include all user response data. Files are flushed periodically (every 30 seconds) to ensure data persistence.

## ๐ŸŽจ Customization

### Adding Your Own Quizzes

1. **Create a YAML file** in the `quizzes/` directory
   ```bash
   # Example: quizzes/science_quiz.yaml
   ```

2. **Add your questions** following the format:
   ```yaml
   title: "Science Quiz"
   questions:
     - question: "What is H2O?"
       options: ["Water", "Hydrogen", "Oxygen", "Salt"]
       correct_answer: 0
   ```

3. **Switch to your quiz** via the admin interface
   - Access `/admin` with your master key
   - Select your quiz from the dropdown
   - Click "Switch Quiz"

### Admin Interface

Enable admin features with a master key:

```bash
webquiz --master-key secret123
```

Access admin panels:
- `/admin` - Quiz management and user approval
- `/files` - View logs, CSV files, and edit configuration
- `/live-stats` - Real-time user progress dashboard

### Styling

- Templates are located in `webquiz/templates/`
- Built-in dark/light theme toggle
- Responsive design works on mobile and desktop
- Generated `static/index.html` can be customized (regenerates on quiz switch)

## ๐Ÿ› ๏ธ Development

### Building Binary Executable

Create a standalone executable with PyInstaller:

```bash
# Build binary
poetry run build_binary

# Or directly
python -m webquiz.build

# The binary will be created at:
./dist/webquiz

# Run the binary
./dist/webquiz
./dist/webquiz --master-key secret123
```

The binary includes all templates and configuration examples, with automatic directory creation on first run.

### Key Technical Decisions

- **Multi-quiz system**: Questions loaded from `quizzes/` directory with YAML files
- **Master key authentication**: Admin endpoints protected with decorator-based authentication
- **Server-side timing**: All timing calculated server-side for accuracy
- **Server-side question randomization**: Random question order generated server-side, stored per-user, ensures unique randomized order for each student with session persistence
- **UUID-based sessions**: Secure user identification without passwords
- **Middleware error handling**: Clean error management with proper HTTP status codes
- **CSV module usage**: Proper escaping for data with commas/quotes
- **Smart file naming**: CSV files prefixed with quiz names, unique suffixes prevent overwrites
- **Dynamic quiz switching**: Complete server state reset when switching quizzes
- **WebSocket support**: Real-time updates for admin and live statistics
- **Binary distribution**: PyInstaller for standalone executable with auto-configuration

### Architecture

- **Backend**: Python 3.9+ with aiohttp async web framework
- **Frontend**: Vanilla HTML/CSS/JavaScript (no frameworks)
- **Storage**: In-memory with periodic CSV backups (30-second intervals)
- **Session Management**: Cookie-based with server-side validation
- **Real-time Features**: WebSocket for live stats and admin notifications

## ๐Ÿ› Troubleshooting

### Common Issues

**Port already in use:**
```bash
# Kill process using port 8080
lsof -ti:8080 | xargs kill -9
```

**Virtual environment issues:**
```bash
# Recreate virtual environment
rm -rf venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

**Quiz not loading:**
- Check that quiz YAML files have valid syntax
- Verify `quizzes/` directory exists and contains `.yaml` files
- Check server logs for errors
- Restart server after adding new quiz files

**Admin interface not accessible:**
- Ensure you started server with `--master-key` option
- Or set `WEBQUIZ_MASTER_KEY` environment variable
- Check that you're using the correct master key

**Tests failing:**
- Always run tests in virtual environment: `source venv/bin/activate`
- Install test dependencies: `poetry install` or `pip install -r requirements.txt`
- Use parallel testing: `pytest tests/ -v -n 4`

**Daemon not stopping:**
```bash
# Check status
webquiz --status

# Force kill if needed
cat webquiz.pid | xargs kill -9
rm webquiz.pid
```

## ๐Ÿ“ License

This project is open source. Feel free to use and modify as needed.

## ๐Ÿค Contributing

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass
5. Submit a pull request

## ๐Ÿ“ž Support

For questions or issues:
- Check the server logs (`server.log`)
- Run the test suite to verify setup
- Review this README and `CLAUDE.md` for detailed documentation


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "webquiz",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.9",
    "maintainer_email": null,
    "keywords": "quiz, testing, aiohttp, web, assessment, education",
    "author": "Oleksandr Liabakh",
    "author_email": "oduvan@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/4d/fd/0b2bd090f3daf3b0fbcfea151cc2ef0ea5cede555049da630c865e7ef8b6/webquiz-1.5.4.tar.gz",
    "platform": null,
    "description": "# WebQuiz\n\nA modern web-based quiz and testing system built with Python and aiohttp that allows users to take multiple-choice tests with real-time answer validation and performance tracking.\n\n## \u2728 Features\n\n- **User Management**: Unique username registration with UUID-based session tracking\n- **Multi-Quiz System**: Questions loaded from `quizzes/` directory with multiple YAML files\n- **Admin Interface**: Web-based admin panel with master key authentication for quiz management\n- **Registration Approval**: Optional admin approval workflow for new registrations with real-time notifications\n- **Question Randomization**: Configurable per-student question order randomization for fair testing\n- **Dynamic Quiz Switching**: Real-time quiz switching with automatic server state reset\n- **Config File Editor**: Web-based configuration editor with real-time validation\n- **Live Statistics**: Real-time WebSocket-powered dashboard showing user progress\n- **Real-time Validation**: Server-side answer checking with immediate feedback\n- **Session Persistence**: Cookie-based user sessions for seamless experience\n- **Performance Tracking**: Server-side timing for accurate response measurement\n- **Data Export**: Automatic CSV export with quiz-prefixed filenames and unique suffixes\n- **Responsive UI**: Clean web interface with dark/light theme support\n- **Binary Distribution**: Standalone PyInstaller executable with auto-configuration\n- **Comprehensive Testing**: 210+ tests covering all functionality with CI/CD pipeline\n- **Flexible File Paths**: Configurable paths for quizzes, logs, CSV, and static files\n\n## \ud83d\ude80 Quick Start\n\n### Prerequisites\n\n- Python 3.9+ (required by aiohttp)\n- Poetry (recommended) or pip\n- Git\n\n### Installation with Poetry (Recommended)\n\n1. **Clone the repository**\n   ```bash\n   git clone git@github.com:oduvan/webquiz.git\n   cd webquiz\n   ```\n\n2. **Install with Poetry**\n   ```bash\n   poetry install\n   ```\n\n3. **Run the server**\n   ```bash\n   webquiz           # Foreground mode\n   webquiz -d        # Daemon mode\n   ```\n\n4. **Open your browser**\n   ```\n   http://localhost:8080\n   ```\n\nThe server will automatically create necessary directories and files on first run.\n\n### Alternative Installation with pip\n\n1. **Clone and set up virtual environment**\n   ```bash\n   git clone git@github.com:oduvan/webquiz.git\n   cd webquiz\n   python3 -m venv venv\n   source venv/bin/activate  # On Windows: venv\\Scripts\\activate\n   ```\n\n2. **Install dependencies**\n   ```bash\n   pip install -r requirements.txt\n   ```\n\n3. **Run the server**\n   ```bash\n   python -m webquiz.cli\n   ```\n\nThe server will automatically create necessary directories and files on first run.\n\n## \ud83d\udcc1 Project Structure\n\n```\nwebquiz/\n\u251c\u2500\u2500 pyproject.toml           # Poetry configuration and dependencies\n\u251c\u2500\u2500 requirements.txt         # Legacy pip dependencies\n\u251c\u2500\u2500 .gitignore              # Git ignore rules\n\u251c\u2500\u2500 CLAUDE.md               # Project documentation\n\u251c\u2500\u2500 README.md               # This file\n\u251c\u2500\u2500 webquiz/                # Main package\n\u2502   \u251c\u2500\u2500 __init__.py        # Package initialization\n\u2502   \u251c\u2500\u2500 cli.py             # CLI entry point (webquiz command)\n\u2502   \u251c\u2500\u2500 server.py          # Main application server\n\u2502   \u251c\u2500\u2500 build.py           # PyInstaller binary build script\n\u2502   \u251c\u2500\u2500 binary_entry.py    # Binary executable entry point\n\u2502   \u251c\u2500\u2500 version_check.py   # Version update checking\n\u2502   \u251c\u2500\u2500 server_config.yaml.example  # Configuration example\n\u2502   \u2514\u2500\u2500 templates/         # HTML templates\n\u2502       \u251c\u2500\u2500 index.html                     # Main quiz interface\n\u2502       \u251c\u2500\u2500 admin.html                     # Admin management panel\n\u2502       \u251c\u2500\u2500 files.html                     # File manager interface\n\u2502       \u251c\u2500\u2500 live_stats.html                # Live statistics dashboard\n\u2502       \u251c\u2500\u2500 quiz_selection_required.html   # Quiz selection prompt\n\u2502       \u2514\u2500\u2500 template_error.html            # Error page template\n\u251c\u2500\u2500 tests/                  # Test suite (14 test files)\n\u2502   \u251c\u2500\u2500 conftest.py                      # Test fixtures and configuration\n\u2502   \u251c\u2500\u2500 test_cli_directory_creation.py   # CLI and directory tests\n\u2502   \u251c\u2500\u2500 test_admin_api.py                # Admin API tests\n\u2502   \u251c\u2500\u2500 test_admin_quiz_management.py    # Quiz management tests\n\u2502   \u251c\u2500\u2500 test_config_management.py        # Config editor tests\n\u2502   \u251c\u2500\u2500 test_registration_approval.py    # Registration approval tests\n\u2502   \u251c\u2500\u2500 test_registration_fields.py      # Registration fields tests\n\u2502   \u251c\u2500\u2500 test_index_generation.py         # Template generation tests\n\u2502   \u251c\u2500\u2500 test_files_management.py         # File manager tests\n\u2502   \u251c\u2500\u2500 test_integration_multiple_choice.py  # Multiple choice integration tests\n\u2502   \u251c\u2500\u2500 test_multiple_answers.py         # Multiple answer tests\n\u2502   \u251c\u2500\u2500 test_show_right_answer.py        # Show answer tests\n\u2502   \u251c\u2500\u2500 test_selenium_multiple_choice.py # Selenium multiple choice tests\n\u2502   \u251c\u2500\u2500 test_selenium_registration_fields.py # Selenium registration tests\n\u2502   \u2514\u2500\u2500 test_user_journey_selenium.py    # Selenium user journey tests\n\u2514\u2500\u2500 .github/\n    \u2514\u2500\u2500 workflows/\n        \u2514\u2500\u2500 test.yml       # CI/CD pipeline\n\n# Generated at runtime (excluded from git):\n\u2514\u2500\u2500 quizzes/               # Quiz files directory\n    \u251c\u2500\u2500 default.yaml      # Default quiz (auto-created)\n    \u2514\u2500\u2500 *.yaml            # Additional quiz files\n```\n\n## \ud83d\udda5\ufe0f CLI Commands\n\nThe `webquiz` command provides several options:\n\n```bash\n# Start server in foreground (default)\nwebquiz\n\n# Start server with admin interface (requires master key)\nwebquiz --master-key secret123\n\n# Start server with custom directories\nwebquiz --quizzes-dir my_quizzes\nwebquiz --logs-dir /var/log\nwebquiz --csv-dir /data\nwebquiz --static /var/www/quiz\n\n# Combine multiple options\nwebquiz --master-key secret123 --quizzes-dir quizzes --logs-dir logs\n\n# Set master key via environment variable\nexport WEBQUIZ_MASTER_KEY=secret123\nwebquiz\n\n# Start server as daemon (background)\nwebquiz -d\nwebquiz --daemon\n\n# Stop daemon server\nwebquiz --stop\n\n# Check daemon status\nwebquiz --status\n\n# Show help\nwebquiz --help\n\n# Show version\nwebquiz --version\n```\n\n### Key Options\n\n- `--master-key`: Enable admin interface with authentication\n- `--quizzes-dir`: Directory containing quiz YAML files (default: `./quizzes`)\n- `--logs-dir`: Directory for server logs (default: current directory)\n- `--csv-dir`: Directory for CSV exports (default: current directory)\n- `--static`: Directory for static files (default: `./static`)\n- `-d, --daemon`: Run server in background\n- `--stop`: Stop daemon server\n- `--status`: Check daemon status\n\n### Daemon Mode Features\n\n- **Background execution**: Server runs independently in background\n- **PID file management**: Automatic process tracking via `webquiz.pid`\n- **Graceful shutdown**: Proper cleanup on stop\n- **Status monitoring**: Check if daemon is running\n- **Log preservation**: All output still goes to `server.log`\n\n## \ud83d\ude80 Release Management\n\nThis project uses GitHub Actions for automated versioning, PyPI deployment, and GitHub Release creation.\n\n### Creating a New Release\n\n1. **Go to GitHub Actions** in the repository\n2. **Select \"Release and Deploy to PyPI\" workflow**\n3. **Click \"Run workflow\"**\n4. **Enter the new version** (e.g., `1.0.6`, `2.0.0`)\n5. **Click \"Run workflow\"**\n\nThe action will automatically:\n- \u2705 Update version in `pyproject.toml` and `webquiz/__init__.py`\n- \u2705 Run tests to ensure everything works\n- \u2705 Commit the version changes\n- \u2705 Create a git tag with the version\n- \u2705 Build the package using Poetry\n- \u2705 Publish to PyPI\n- \ud83c\udd95 **Create a GitHub Release** with built artifacts\n\n### What's included in GitHub Releases\n\nEach release automatically includes:\n- \ud83d\udce6 **Python wheel package** (`.whl` file)\n- \ud83d\udccb **Source distribution** (`.tar.gz` file)\n- \ud83d\udcdd **Formatted release notes** with installation instructions\n- \ud83d\udd17 **Links to commit history** for detailed changelog\n- \ud83d\udccb **Installation commands** for the specific version\n\n### Prerequisites for Release Deployment\n\nRepository maintainers need to set up:\n- `PYPI_API_TOKEN` secret in GitHub repository settings\n- PyPI account with publish permissions for the `webquiz` package\n- `GITHUB_TOKEN` is automatically provided by GitHub Actions\n\n## \ud83e\uddea Testing\n\nRun the comprehensive test suite:\n\n```bash\n# With Poetry\npoetry run pytest\n\n# Or directly\npytest tests/\n\n# Run with verbose output\npytest tests/ -v\n\n# Run in parallel with 4 workers\npytest tests/ -v -n 4\n\n# Run specific test file\npytest tests/test_admin_api.py\npytest tests/test_registration_approval.py\n```\n\n### Test Coverage\n\nThe project has **210+ tests** across **14 test files** covering:\n\n- **CLI and Directory Creation** (7 tests): Directory and file creation\n- **Admin API** (14 tests): Admin interface and authentication\n- **Admin Quiz Management** (18 tests): Quiz switching and management\n- **Config Management** (16 tests): Config editor and validation\n- **Registration Approval** (20 tests): Approval workflow and timing\n- **Files Management** (32 tests): File manager interface\n- **Index Generation** (13 tests): Template generation tests\n- **Registration Fields** (12 tests): Custom registration fields\n- **Show Right Answer** (5 tests): Answer display functionality\n- **Integration Tests** (6 tests): Multiple choice, multiple answers\n- **Selenium Tests** (56 tests): End-to-end browser testing\n\nThe test suite uses GitHub Actions CI/CD for automated testing on every commit.\n\n## \ud83d\udccb Configuration Format\n\n### Quiz Files\n\nQuestions are stored in YAML files in the `quizzes/` directory. The server automatically creates a `default.yaml` file if the directory is empty.\n\n**Example quiz file** (`quizzes/math_quiz.yaml`):\n\n```yaml\ntitle: \"Mathematics Quiz\"\nrandomize_questions: true  # Set to true to randomize question order for each student (default: false)\nquestions:\n  - question: \"What is 2 + 2?\"\n    options:\n      - \"3\"\n      - \"4\"\n      - \"5\"\n      - \"6\"\n    correct_answer: 1  # 0-indexed (option \"4\")\n\n  - question: \"What is 5 \u00d7 3?\"\n    options:\n      - \"10\"\n      - \"15\"\n      - \"20\"\n      - \"25\"\n    correct_answer: 1  # 0-indexed (option \"15\")\n```\n\n**Question Randomization:**\n- Set `randomize_questions: true` in your quiz YAML to give each student a unique question order\n- Each student receives a randomized order that persists across sessions\n- Helps prevent cheating and ensures fair testing\n- Default is `false` (questions appear in YAML order)\n\n### Server Configuration\n\nOptional server configuration file (`webquiz.yaml`):\n\n```yaml\nserver:\n  host: \"0.0.0.0\"\n  port: 8080\n\nregistration:\n  approve: false  # Set to true to require admin approval\n  fields:\n    - name: \"full_name\"\n      label: \"Full Name\"\n      required: true\n\nquiz:\n  show_right_answer: false  # Show correct answer after submission\n```\n\nAll configuration sections are optional and have sensible defaults.\n\n## \ud83d\udcca Data Export\n\nUser responses are automatically exported to CSV files with quiz-prefixed filenames and unique suffixes to prevent overwrites:\n\n**Example:** `math_quiz_user_responses_0001.csv`\n\n```csv\nuser_id,question,selected_answer,correct_answer,is_correct,time_taken_seconds\n123456,\"What is 2 + 2?\",\"4\",\"4\",True,3.45\n123456,\"What is 5 \u00d7 3?\",\"15\",\"15\",True,2.87\n```\n\nCSV files are created with proper escaping and include all user response data. Files are flushed periodically (every 30 seconds) to ensure data persistence.\n\n## \ud83c\udfa8 Customization\n\n### Adding Your Own Quizzes\n\n1. **Create a YAML file** in the `quizzes/` directory\n   ```bash\n   # Example: quizzes/science_quiz.yaml\n   ```\n\n2. **Add your questions** following the format:\n   ```yaml\n   title: \"Science Quiz\"\n   questions:\n     - question: \"What is H2O?\"\n       options: [\"Water\", \"Hydrogen\", \"Oxygen\", \"Salt\"]\n       correct_answer: 0\n   ```\n\n3. **Switch to your quiz** via the admin interface\n   - Access `/admin` with your master key\n   - Select your quiz from the dropdown\n   - Click \"Switch Quiz\"\n\n### Admin Interface\n\nEnable admin features with a master key:\n\n```bash\nwebquiz --master-key secret123\n```\n\nAccess admin panels:\n- `/admin` - Quiz management and user approval\n- `/files` - View logs, CSV files, and edit configuration\n- `/live-stats` - Real-time user progress dashboard\n\n### Styling\n\n- Templates are located in `webquiz/templates/`\n- Built-in dark/light theme toggle\n- Responsive design works on mobile and desktop\n- Generated `static/index.html` can be customized (regenerates on quiz switch)\n\n## \ud83d\udee0\ufe0f Development\n\n### Building Binary Executable\n\nCreate a standalone executable with PyInstaller:\n\n```bash\n# Build binary\npoetry run build_binary\n\n# Or directly\npython -m webquiz.build\n\n# The binary will be created at:\n./dist/webquiz\n\n# Run the binary\n./dist/webquiz\n./dist/webquiz --master-key secret123\n```\n\nThe binary includes all templates and configuration examples, with automatic directory creation on first run.\n\n### Key Technical Decisions\n\n- **Multi-quiz system**: Questions loaded from `quizzes/` directory with YAML files\n- **Master key authentication**: Admin endpoints protected with decorator-based authentication\n- **Server-side timing**: All timing calculated server-side for accuracy\n- **Server-side question randomization**: Random question order generated server-side, stored per-user, ensures unique randomized order for each student with session persistence\n- **UUID-based sessions**: Secure user identification without passwords\n- **Middleware error handling**: Clean error management with proper HTTP status codes\n- **CSV module usage**: Proper escaping for data with commas/quotes\n- **Smart file naming**: CSV files prefixed with quiz names, unique suffixes prevent overwrites\n- **Dynamic quiz switching**: Complete server state reset when switching quizzes\n- **WebSocket support**: Real-time updates for admin and live statistics\n- **Binary distribution**: PyInstaller for standalone executable with auto-configuration\n\n### Architecture\n\n- **Backend**: Python 3.9+ with aiohttp async web framework\n- **Frontend**: Vanilla HTML/CSS/JavaScript (no frameworks)\n- **Storage**: In-memory with periodic CSV backups (30-second intervals)\n- **Session Management**: Cookie-based with server-side validation\n- **Real-time Features**: WebSocket for live stats and admin notifications\n\n## \ud83d\udc1b Troubleshooting\n\n### Common Issues\n\n**Port already in use:**\n```bash\n# Kill process using port 8080\nlsof -ti:8080 | xargs kill -9\n```\n\n**Virtual environment issues:**\n```bash\n# Recreate virtual environment\nrm -rf venv\npython3 -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt\n```\n\n**Quiz not loading:**\n- Check that quiz YAML files have valid syntax\n- Verify `quizzes/` directory exists and contains `.yaml` files\n- Check server logs for errors\n- Restart server after adding new quiz files\n\n**Admin interface not accessible:**\n- Ensure you started server with `--master-key` option\n- Or set `WEBQUIZ_MASTER_KEY` environment variable\n- Check that you're using the correct master key\n\n**Tests failing:**\n- Always run tests in virtual environment: `source venv/bin/activate`\n- Install test dependencies: `poetry install` or `pip install -r requirements.txt`\n- Use parallel testing: `pytest tests/ -v -n 4`\n\n**Daemon not stopping:**\n```bash\n# Check status\nwebquiz --status\n\n# Force kill if needed\ncat webquiz.pid | xargs kill -9\nrm webquiz.pid\n```\n\n## \ud83d\udcdd License\n\nThis project is open source. Feel free to use and modify as needed.\n\n## \ud83e\udd1d Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Add tests for new functionality\n4. Ensure all tests pass\n5. Submit a pull request\n\n## \ud83d\udcde Support\n\nFor questions or issues:\n- Check the server logs (`server.log`)\n- Run the test suite to verify setup\n- Review this README and `CLAUDE.md` for detailed documentation\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A modern web-based quiz and testing system built with Python and aiohttp",
    "version": "1.5.4",
    "project_urls": {
        "Bug Tracker": "https://github.com/oduvan/webquiz/issues",
        "Documentation": "https://github.com/oduvan/webquiz",
        "Homepage": "https://github.com/oduvan/webquiz",
        "Repository": "https://github.com/oduvan/webquiz"
    },
    "split_keywords": [
        "quiz",
        " testing",
        " aiohttp",
        " web",
        " assessment",
        " education"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "dee2e79a7db900910161b4b9c2a31408a4ca9f2a3bdd72b00c278ececdcec1c0",
                "md5": "a7f4abe7ac88312deef30c1a4cacafae",
                "sha256": "df6617c1fb1fb92b6ff35e3b7f7c537579f9bea56ce5cd5319f2fe8d755e0fce"
            },
            "downloads": -1,
            "filename": "webquiz-1.5.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a7f4abe7ac88312deef30c1a4cacafae",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.9",
            "size": 76862,
            "upload_time": "2025-10-14T13:38:02",
            "upload_time_iso_8601": "2025-10-14T13:38:02.003573Z",
            "url": "https://files.pythonhosted.org/packages/de/e2/e79a7db900910161b4b9c2a31408a4ca9f2a3bdd72b00c278ececdcec1c0/webquiz-1.5.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "4dfd0b2bd090f3daf3b0fbcfea151cc2ef0ea5cede555049da630c865e7ef8b6",
                "md5": "c921263c8b2b0f173f160ec28ab2f3c2",
                "sha256": "f2c73095ed75b8fac94e142a951d7249f6e8acd93ad1a33ec6724eeaa92564ee"
            },
            "downloads": -1,
            "filename": "webquiz-1.5.4.tar.gz",
            "has_sig": false,
            "md5_digest": "c921263c8b2b0f173f160ec28ab2f3c2",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.9",
            "size": 74985,
            "upload_time": "2025-10-14T13:38:04",
            "upload_time_iso_8601": "2025-10-14T13:38:04.274628Z",
            "url": "https://files.pythonhosted.org/packages/4d/fd/0b2bd090f3daf3b0fbcfea151cc2ef0ea5cede555049da630c865e7ef8b6/webquiz-1.5.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-14 13:38:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "oduvan",
    "github_project": "webquiz",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "aiohttp",
            "specs": [
                [
                    "==",
                    "3.12.13"
                ]
            ]
        },
        {
            "name": "PyYAML",
            "specs": [
                [
                    "==",
                    "6.0.2"
                ]
            ]
        },
        {
            "name": "aiofiles",
            "specs": [
                [
                    "==",
                    "24.1.0"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    "==",
                    "8.3.3"
                ]
            ]
        },
        {
            "name": "pytest-asyncio",
            "specs": [
                [
                    "==",
                    "0.24.0"
                ]
            ]
        },
        {
            "name": "pytest-xdist",
            "specs": [
                [
                    "==",
                    "3.8.0"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.32.0"
                ]
            ]
        },
        {
            "name": "selenium",
            "specs": [
                [
                    "==",
                    "4.24.0"
                ]
            ]
        },
        {
            "name": "webdriver-manager",
            "specs": [
                [
                    "==",
                    "4.0.0"
                ]
            ]
        },
        {
            "name": "pytest-html",
            "specs": [
                [
                    "==",
                    "4.1.0"
                ]
            ]
        }
    ],
    "lcname": "webquiz"
}
        
Elapsed time: 4.23389s