eCBTKit
An early-stage Python framework for CBT & online examination APIs
Build the CBT API, not the CBT engine.
Version: 0.1.0
Author: Emmanuel Emmanuel Etim
License: MIT
Repository: https://github.com/emmanuelemmanueletim/ecbtkit
Author email: emmanuel224etim089@gmail.com
Starlette ASGI — no FastAPI dependency.
Strong auth — Argon2id, lockout, refresh tokens, password policy.
SQL databases — SQLite, PostgreSQL, and MySQL through SQLAlchemy.
Install
pip install -e .
# or
pip install -r requirements.txt
The project is Beta. Run ecbt migrate before starting the application; tables are not created automatically. ecbt dev enables development-only automatic table creation.
Optional drivers:
pip install psycopg2-binary # PostgreSQL
pip install pymysql cryptography # MySQL
Quick start
from ecbtkit import CBT
app = CBT()
app.run(host="127.0.0.1", port=8000)
Open http://127.0.0.1:8000/docs
Auth that stands out
| Feature | Included |
|---|---|
| Argon2id password hashing | ✅ |
| Password strength policy | ✅ |
| Brute-force lockout | ✅ |
| Access + refresh tokens | ✅ |
| Password reset flow | ✅ |
| Auth rate limiting | ✅ |
| Security response headers | ✅ |
| No user enumeration | ✅ |
POST /api/v1/auth/signup
POST /api/v1/auth/login
POST /api/v1/auth/refresh
GET /api/v1/auth/me
POST /api/v1/auth/change-password
POST /api/v1/auth/forgot-password
POST /api/v1/auth/reset-password
Databases
# SQLite (dev)
ECBT_DATABASE_URL=sqlite:///./ecbtkit.db
# PostgreSQL
ECBT_DATABASE_URL=postgresql://user:pass@localhost:5432/ecbt
# MySQL
ECBT_DATABASE_URL=mysql://user:pass@localhost:3306/ecbt
The examination engine currently supports SQL databases only. MongoDB is not a supported application backend. Set ECBT_CORS_ORIGINS to a comma-separated allowlist when browser clients need cross-origin access; credentials are disabled by default.
Maturity: Beta. Run multiple workers only with PostgreSQL/MySQL and a shared rate limiter at the proxy or gateway. Password reset and verification emails are sent when ECBT_MAIL_ENABLED=true and a provider is configured. Async mail uses an in-process thread pool (queued messages can be lost on process restart); applications that need durable delivery should integrate an outbox or external queue.
Examination engine
Question bank · selection rules · deterministic randomization · server-side timer ·
answer submission · automatic marking · negative marking · grading · result visibility ·
structured errors · role-based access
Docs
Architecture
eCBTKit (independent)
├── Domain engine (no HTTP)
├── Auth service (no HTTP)
├── Security (passwords, tokens, rate limit, headers)
├── SQL persistence (SQLAlchemy)
└── HTTP layer (Starlette ASGI)
License
MIT © Emmanuel Emmanuel Etim
Email (simple)
ECBT_MAIL_ENABLED=true
ECBT_MAIL_PROVIDER=sendgrid
ECBT_MAIL_API_KEY=SG.xxx
ECBT_MAIL_FROM=noreply@yourdomain.com
ECBT_MAIL_LINK_BASE_URL=https://app.yourdomain.com
Production
Metadata
Release files for ecbtkit 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ecbtkit-0.1.1.tar.gz | 59.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ecbtkit-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 127.0 kB
Release files / ecbtkit-0.1.1.tar.gz
| Download URL | ecbtkit-0.1.1.tar.gz |
|---|---|
| Size | 59.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7b0be8c550199631dfb73fc98ecf6bade26fe29e926da26f684cd16e98ac4ac7
|
|
BLAKE2b-256 checksum How to use checksums |
cf5f72050a886cf3ad9d9d976f7b98c7667bcc1f9afd85e62e66766306abeee7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / ecbtkit-0.1.1-py3-none-any.whl
| Download URL | ecbtkit-0.1.1-py3-none-any.whl |
|---|---|
| Size | 67.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
445d8631821f18d523a2ac57f30ccde4a342593895d1fa69b367ee40bc372fd5
|
|
BLAKE2b-256 checksum How to use checksums |
b3ca2a0c756d84ed85189f322ae04f1945b8434ba42f197f80b9e1ed9a4dc987
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|