scormhost
Version 0.1.0 — Turn FastAPI into a SCORM 1.2 / 2004 hosting app with user accounts, JWT auth, and an admin UI — deployable to FastAPI Cloud.
Works with packages built by LXPack (lxpack build --target scorm12 / scorm2004) and other compliant SCORM ZIPs.
Features
- User management — SQLite database, Alembic migrations, bcrypt passwords
- JWT auth — access + refresh tokens (httpOnly cookies for the browser UI,
Authorization: Bearerfor API clients) - Public learning — anyone can browse and launch courses without logging in
- Optional login for learners — progress saved to your account when signed in
- Anonymous progress — guests get a browser cookie so progress persists on that device
- Staff login — upload/delete courses and manage users (instructor/admin)
- Roles —
learner,instructor,admin(first registered user becomesadmin)
Quick start
git clone https://github.com/eddiethedean/scormhost.git
cd scormhost
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# optional: run migrations manually (also runs on startup by default)
alembic upgrade head
fastapi dev
- Open http://127.0.0.1:8000 — launch any course without an account.
- Register at
/register(first user = admin) to upload SCORM ZIPs or save progress to your account.
Or use the factory:
from scormhost import create_scorm_app
app = create_scorm_app(
data_dir="./data",
title="My SCORM Host",
secret_key="change-me-in-production",
)
Set require_auth=True only if you want to force login before taking courses (not the default).
Database & migrations
Default database: sqlite:///<data_dir>/scormhost.db (override with SCORMHOST_DATABASE_URL).
alembic upgrade head # apply migrations
alembic revision -m "describe change" --autogenerate # new revision
On app startup, migrations run automatically when SCORMHOST_AUTO_MIGRATE=true (default).
Roles
| Role | Capabilities |
|---|---|
learner |
Launch courses (no login required); signed-in progress tied to account |
instructor |
Upload packages, delete own uploads (login required) |
admin |
User management, delete any package (login required) |
Without login: launch courses; progress stored under a guest cookie on this browser.
With login: same, but SCORM progress is keyed to your user id (works across browsers/devices).
Auth API
| Method | Path | Description |
|---|---|---|
POST |
/api/auth/register |
Create account (sets cookies) |
POST |
/api/auth/login |
Login (sets cookies) |
POST |
/api/auth/refresh |
Rotate refresh token |
POST |
/api/auth/logout |
Revoke refresh token, clear cookies |
GET |
/api/auth/me |
Current user (Bearer or cookie) |
PATCH |
/api/auth/me/password |
Change password |
GET |
/api/users |
List users (admin) |
PATCH |
/api/users/{id} |
Update role / active flag (admin) |
DELETE |
/api/users/{id} |
Delete user (admin) |
HTML: /login, /register, /admin/users
SCORM API
| Method | Path | Description |
|---|---|---|
GET |
/ |
Package catalog (requires login when auth enabled) |
GET |
/api/packages |
Package list JSON (public; no auth required) |
GET |
/launch/{package_id} |
SCORM player |
GET |
/content/{package_id}/{path} |
Package static files |
POST |
/api/packages |
Upload ZIP (instructor/admin) |
DELETE |
/api/packages/{id} |
Delete package |
GET/PUT |
/api/scorm/{id}/cmi |
CMI for authenticated user |
Environment variables
| Variable | Default | Description |
|---|---|---|
SCORMHOST_DATA_DIR |
./data |
Packages, sessions, SQLite DB |
SCORMHOST_SECRET_KEY |
random per start | Set in production — JWT signing |
SCORMHOST_DATABASE_URL |
sqlite:///<data>/scormhost.db |
SQLAlchemy URL |
SCORMHOST_REQUIRE_AUTH |
false |
If true, login required to take courses (not just manage) |
SCORMHOST_ALLOW_REGISTRATION |
true |
Public sign-up |
SCORMHOST_BOOTSTRAP_ADMIN_EMAIL |
— | Force admin role for matching email on register (only use with trusted registration; no email verification) |
SCORMHOST_API_PREFIX |
`` | URL prefix for all routes (e.g. /scorm behind a reverse proxy) |
SCORMHOST_ACCESS_TOKEN_MINUTES |
30 |
JWT access TTL |
SCORMHOST_REFRESH_TOKEN_DAYS |
7 |
Refresh token TTL |
SCORMHOST_COOKIE_SECURE |
false |
Set true behind HTTPS |
SCORMHOST_AUTO_MIGRATE |
true |
Run alembic upgrade head on startup |
SCORMHOST_ALLOW_UPLOAD |
true |
Global upload toggle |
SCORMHOST_TITLE |
SCORM Host |
Site title |
Deploy to FastAPI Cloud
cd examples/cloud
pip install -r requirements.txt
fastapi login
fastapi deploy
Set SCORMHOST_DATA_DIR, SCORMHOST_SECRET_KEY, and SCORMHOST_COOKIE_SECURE=true in the dashboard. Always set a stable SCORMHOST_SECRET_KEY in production (do not rely on the random per-start default).
Development
pip install -e ".[dev]"
ruff format .
ruff check .
ty check
pytest
Tests use require_auth=False for SCORM flows and a separate DB for auth tests. Migrations live in src/scormhost/alembic/ and ship inside the wheel; alembic upgrade head from the repo root uses alembic.ini.
Releasing
- Ensure
pyproject.tomland CHANGELOG.md match the target version. - Run
pytest,ruff check,ty check, andpython -m build. - Tag
v0.1.0and publish the GitHub release (attachdist/*artifacts if publishing to PyPI manually).
Limits (v0.1)
- SQLite by default (swap
SCORMHOST_DATABASE_URLfor Postgres in production) - Package files remain on disk (not in the DB)
- cmi5 / xAPI launch not supported
- SCORM 2004 sequencing not enforced server-side
License
Apache-2.0 — see LICENSE.
Metadata
Release files for scormhost 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| scormhost-0.1.0.tar.gz | 35.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| scormhost-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 77.7 kB
Release files / scormhost-0.1.0.tar.gz
| Download URL | scormhost-0.1.0.tar.gz |
|---|---|
| Size | 35.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1a3094be2b49482ae036df23335d7ef27a986ae6a17b6813d7fad3f39a6b4fe3
|
|
BLAKE2b-256 checksum How to use checksums |
ec9983c24e7e38c364e0dfc1561059950835a6e39c14d9604fa60b64997b1d60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|
Release files / scormhost-0.1.0-py3-none-any.whl
| Download URL | scormhost-0.1.0-py3-none-any.whl |
|---|---|
| Size | 41.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
69d4c85762a6947f004cdba5addf85bbf7cbb56606c0c962c0706a64e2c34039
|
|
BLAKE2b-256 checksum How to use checksums |
fe1e829a190559569b516507613a2a7790226d79203da77bae546db1444ab16b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|