FlashExam
English | 中文
FlashExam - Intelligent Online Examination System with AI Grading
A Flask-based intelligent online examination system with AI grading support, compatible with macOS, Linux, and Windows.
Features
- Multiple Question Types: Multiple choice, true/false, short answer, fill-in-the-blank, programming, code execution
- AI Intelligent Grading: Subjective question grading based on Qwen model
- Code Execution: Online execution support for Python, C, Java, Shell, JavaScript
- Reading Comprehension: TOEFL-style reading comprehension exams
- Real-time Monitoring: Tab switch detection and anti-cheating features
- Batch Import: Import questions and students via Excel/CSV
- Admin Panel: Teacher account management and system configuration
- Cross-platform: Supports macOS, Linux, Windows
- Dark/Light Theme: Elegant theme system with automatic system preference detection
- Port Conflict Handling: Automatic detection and resolution of port conflicts
Quick Start
Installation
# Install from PyPI
pip install flashexam
# Or install from source
git clone https://github.com/cycleuser/flashexam.git
cd flashexam
pip install -e .
Initialize Database
flashexam --init-db
Start Server
# Development mode (default)
flashexam
# Production mode
flashexam --mode prod
# High-performance mode
flashexam --mode high-perf --workers 8
# Custom port
flashexam --port 8080
# Force start (kill process using the port)
flashexam --force
Access the System
- Homepage: http://localhost:5000
- Teacher Portal: http://localhost:5000/teacher
- Student Portal: http://localhost:5000/student
- Admin Panel: http://localhost:5000/admin
First startup requires setting up an administrator account.
Command Line Arguments
flashexam [options]
flashexam export <path> # Export data (zip/json)
flashexam import <path> # Import data (zip/json)
Options:
--mode {dev,prod,high-perf} Run mode (default: dev)
--host HOST Bind address (default: 0.0.0.0)
--port PORT Port number (default: 5000)
--workers N Worker threads (default: 4)
--data, -d DIR Custom data directory (default: flashexam/storage/)
--db-path PATH Custom database file path
--init-db Initialize database
--force Force start (kill process using port)
--backup Backup database
--restore FILE Restore database from backup
--export FILE Export data to JSON (legacy flag)
--import FILE Import data from JSON (legacy flag)
--version Show version information
Custom Data Directory
# Use a custom directory for database, sessions, and uploads
flashexam --data ./exam_data
# Short form
flashexam -d ./exam_data
Data directory structure:
exam_data/
├── exam_database.db # SQLite database
├── sessions/ # Flask session files
├── uploads/ # Uploaded files
└── backups/ # Database backups
Data Export & Import
# Export all data as ZIP (database + sessions)
flashexam export ./backup.zip
# Export all tables as JSON
flashexam export ./backup.json
# Import from ZIP
flashexam import ./backup.zip
# Import from JSON
flashexam import ./backup.json
Database Backup & Restore
# Create a backup
flashexam --backup --data ./exam_data
# Restore from backup
flashexam --restore ./exam_data/backups/exam_database_20260629_120000.db --data ./exam_data
Question Import
Supports importing questions from Excel (.xlsx) and CSV files.
CSV Format
Number,question_type,question_text,option_A,option_B,option_C,option_D,correct_answer,score,difficulty,subject
1,choice,What is Python?,A programming language,A snake,Both A and B,None of the above,A,5,2,Computer Science
2,judge,Python is a compiled language,true,false,,false,3,1,Computer Science
Excel Format
| Number | Material | question_type | question_text | option_A | option_B | correct_answer | score | subject |
|---|---|---|---|---|---|---|---|---|
| 1 | Reading passage text... | choice | Question text | Option A | Option B | A | 5 | English |
Project Structure
flashexam/
├── __init__.py # Application factory
├── cli.py # CLI entry point
├── database.py # Database operations
├── teacher.py # Teacher endpoints
├── student.py # Student endpoints
├── auth.py # Authentication module
├── admin.py # Admin module
├── api.py # API endpoints
├── code_executor.py # Code executor
├── smart_import_manager.py # Question import
├── models.py # Data models
├── utils.py # Utility functions
├── templates/ # HTML templates
├── static/ # Static resources
│ ├── css/
│ │ ├── themes.css # Dark/light theme
│ │ └── app.css # Custom styles
│ └── js/
├── config.py # Centralized path config (--data support)
└── storage/ # Data storage (not in repo)
Development
Install Development Dependencies
pip install -e ".[dev]"
Run Tests
# Run all tests
pytest
# Run with coverage
pytest --cov=flashexam
# Run import tests
python test_import.py
Code Style
ruff check .
ruff format .
Publish to PyPI
# Linux/macOS
./upload_pypi.sh
# Windows
upload_pypi.bat
Tech Stack
- Backend: Flask, SQLite, Flask-Login, Flask-Session
- Frontend: Bootstrap 5, jQuery, Bootstrap Icons
- AI: PyTorch, Transformers, Qwen (optional)
- Server: Waitress (production)
Security Notes
- Database files are excluded from version control
- Session files are excluded from version control
- No sensitive data is uploaded to GitHub or PyPI
- Secret keys should be set via environment variables in production
Performance & Resource Usage (Measured)
Data based on macOS arm64, Python 3.12, SQLite WAL mode, with 74 students, 4 exams (44 questions each).
| Metric | Measured |
|---|---|
| Save latency P50 | 3.7 ms |
| Save latency P99 | 11.7 ms |
| Base memory (idle) | ~68 MB |
| Memory +20 concurrent | +4.3 MB |
| Memory per user | ~0.8 MB |
| Estimated 74 concurrent users | ~127 MB |
| Throughput at 20 concurrent | 242 ops/s |
| Database (after 3h stress test) | ~110 MB |
| 3-hour sustained write rate | 115,539 ops/h |
| Errors in 346,616 operations | 0 |
Recommended Hardware
| Students | CPU | RAM | Disk |
|---|---|---|---|
| < 50 | 1 core | 256 MB | 1 GB |
| 50-100 | 2 cores | 512 MB | 2 GB |
| 100-200 | 4 cores | 1 GB | 5 GB |
Every save/submit uses four-tier disaster recovery (file → memory → main table → backup table). The frontend also has 7 browser-side protections: localStorage offline queue, sendBeacon, auto-retry on reconnect, etc.
License
This project is licensed under the GNU General Public License v3.0.
Contributing
Issues and Pull Requests are welcome!
- Fork this repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Create a Pull Request
Author
FlashExam Contributors
Links
Metadata
Release files for flashexam 2.0.23
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| flashexam-2.0.23-py3-none-any.whl | Python 3 | none | any | Details |
Release files / flashexam-2.0.23-py3-none-any.whl
| Download URL | flashexam-2.0.23-py3-none-any.whl |
|---|---|
| Size | 1.9 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
76e0a73ab4e9e0f335a575fa27fba4c473f7700862d97087966e0ffd57c76a17
|
|
BLAKE2b-256 checksum How to use checksums |
f9280a7d4f9cb729a7d100f43a952644513bd48c8aed360069a8c31037ddcbd3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Security for flashexam 2.0.23
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.