H5P content types
H5P content types (libraries such as H5P.MultiChoice or H5P.InteractiveVideo) are not
code you add to ulams. You install them into the H5P service at runtime. The service is
api/h5p, a Node program built on Lumi’s @lumieducation/h5p-server. It is licensed
GPL-3.0-or-later and runs as a separate container. For the admin screen see
H5P libraries.
Licence boundary
Section titled “Licence boundary”H5P’s server code is GPL. ulams keeps it in its own process (LICENSING.md, ADR 0003):
- No GPL or AGPL code is linked into the API or bundled into the admin or the frontends.
Those reach the service only over HTTP, the CLI or an iframe with
postMessage. - Never copy or port code from
api/h5pinto other folders. ESLint blocks@lumieducation/*imports in the admin and the legacy front, andyarn lint:gplchecks the front. - The frontends embed
/h5p/embed/play/:idand/h5p/embed/edit/:idand talk to them with theulams-h5p:*message protocol. - The Laravel package
api/packages/h5p(MIT) contains no H5P code. It calls the service with an internal token (X-Internal-Token: $H5P_INTERNAL_TOKEN, acting as a system user with every permission) and the tenant host inX-Forwarded-Host. It may read theh5p.contentstable but never writes to theh5pschema.
Content types have their own licences, usually MIT, but check each one before you ship content that depends on it.
Install content types
Section titled “Install content types”| Way | Who | How |
|---|---|---|
| H5P Hub in the editor | users with h5p_library_install / h5p_library_update |
the content-type selector of the editor lists Hub types; installing is one click |
| Admin screen | the same permissions | upload a .h5p library package, restrict, delete, refresh the Hub cache |
| Content upload | callers allowed to install libraries | POST /h5p/contents/upload installs every library inside the package |
| Library package | h5p_library_upload or h5p_library_install |
POST /h5p/libraries with the field file |
| CLI | operators | seed in the service container (below) |
The Hub is enabled by H5P_HUB_ENABLED (default true). The H5P Content Hub (shared content) is
off.
Seed CLI
Section titled “Seed CLI”Run it in the service container. It acts as the system user, prints a JSON report and exits with code 2 if any item failed.
docker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --helpdocker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --hub H5P.MultiChoice,H5P.DragQuestiondocker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --samples # curated examplesdocker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --samples multiple-choice,drag-and-dropdocker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --list-samplesdocker compose -f api/docker-compose.yml exec h5p node dist/cli/seed.js --hub H5P.MultiChoice ./packages/ https://example.org/x.h5p--out file.json writes the report to a file. In development, corepack yarn workspace api-h5p seed:dev
runs the TypeScript source. The samples are defined in api/h5p/src/cli/samples.ts.
Restrict or remove
Section titled “Restrict or remove”PATCH /h5p/libraries/H5P.Foo-1.2{ "restricted": true }DELETE /h5p/libraries/:uber (h5p_library_delete) removes a library. GET /h5p/libraries lists
them (h5p_library_list).
Libraries are shared by all tenants
Section titled “Libraries are shared by all tenants”The per-tenant parts of the Hub (content-type cache, Hub registration, profile cache) are in
Redis under h5p:t:<tenantId>:…. The service refreshes the Hub cache for each tenant in the
background at start.
Develop the service
Section titled “Develop the service”- Download the H5P core and editor files:
corepack yarn workspace api-h5p download:core. - Run it:
corepack yarn workspace api-h5p dev. - Test it:
corepack yarn workspace api-h5p test. The integration tests (test:integration) run on manual dispatch in CI.
Changes to the service stay inside api/h5p and keep its GPL licence. To give learners
something H5P cannot do, write a topic type or integrate an
LTI tool instead.