A modular framework for quick & easy deployment of customizable user studies — for recommender systems and any other item-based interactive system.
Project description
EasyStudy
Open-source framework for building, running, and analyzing interactive user studies —
for recommender systems, HCI, and any item-based experiment.
EasyStudy is a modular, highly extensible framework for deploying customizable user studies. It ships out-of-the-box functionality for every phase of a study — data loading & presentation, preference elicitation, baseline algorithms, questionnaires, and results comparison — so a simple study can be deployed in a few clicks from a web UI, while complex designs stay fully programmable via plugins.
Built for recommender-systems research, EasyStudy is domain-generic: it has already been used for recommender-systems studies, data-visualization studies, and university teaching. If your study shows people items, records how they interact, and asks them questions, EasyStudy fits.
Credo: "Make simple things fast and hard things possible."
Who is this for?
- RS / IR / HCI researchers who want user studies without rebuilding UI, tracking, and elicitation each time.
- Instructors & students — try algorithms live, or implement and evaluate an extension in a single plugin.
Used in research
EasyStudy has powered the user studies behind peer-reviewed publications in recommender systems and data visualization — see Studies built with EasyStudy.
Using EasyStudy in your research or teaching? We'd genuinely love to know — it helps us understand where it's useful (labs, courses, companies) and what to improve:
- 📄 Add your paper: open a pull request or issue.
- 💬 Share feedback, ask questions, or say hi in GitHub Discussions.
- ✉️ Or email patrik.dokoupil@matfyz.cuni.cz.
Quickstart
Not on PyPI yet, so install from a clone — the core install is deliberately lightweight (Flask + pandas/numpy/scikit-learn); heavy backends live behind extras so nobody installs TensorFlow or PyTorch just to run a books-vs-movies study:
git clone https://github.com/pdokoupil/EasyStudy.git
cd EasyStudy
pip install -e ".[dev]" # lightweight core + dev tools
easystudy fetch-data --dataset ml-latest-small # small, fast demo dataset (~1 MB of CSVs)
easystudy create-user you@example.com yourpassword
easystudy serve --debug # http://localhost:8000
Open http://localhost:8000, log in with the account you just created, and create a study from
the fastcompare template. easystudy fetch-data/create-user/serve all use whichever directory
you run them from for the dataset/DB — no need to cd into server/.
easystudy serve uses Flask's own dev server (single-process, auto-reloads with --debug) —
good for trying things out, not for a real deployment. Gunicorn (same server Docker below uses)
is already installed alongside the core package; run easystudy serve --prod to use it directly,
no Docker required.
Item posters are fetched from IMDb on first view and cached to disk; to pre-fetch them all up front,
run easystudy fetch-images --dataset ml-latest-small.
By default only the lightweight-core algorithms appear (EASE, Popularity, Random). Install an extra to unlock more:
pip install -e ".[recbole]" # RecBole model zoo: BPR, LightGCN, NGCF, NeuMF, DMF
pip install -e ".[tensorflow]" # VAE, RBM
pip install -e ".[lenskit]" # ItemKNN, UserKNN, ImplicitMF
pip install -e ".[all]" # everything
The
recboleextra pulls a dependency with no Python 3.12+ wheels yet — use Python 3.10 or 3.11 for that one (python3.11 -m venv .venv && ...).
Once published, all of the above becomes clone-free: pip install "easystudy[recbole]".
Configuration is via environment variables (see .env.example): SECRET_KEY,
DATABASE_URL (SQLite by default, Postgres for scale), SESSION_TYPE/REDIS_URL, PORT.
Also works with uv
This repo is itself developed with uv — uv sync (backed by the
committed uv.lock) is what our own CI uses. It's a drop-in, much faster alternative to pip + venv,
and does a couple of things pip doesn't:
- Speed — dependency resolution/installs are typically 10–100× faster.
- One lockfile —
uv.lockpins exact versions across every extra, resolved together; there's no equivalent to that with plain pip. - Manages Python itself —
uv venv --python 3.11downloads that Python for you if you don't have it (handy for therecboleextra above); plain pip just uses whichever Python is already active.
git clone https://github.com/pdokoupil/EasyStudy.git
cd EasyStudy
uv sync --extra dev # creates .venv from uv.lock
uv run easystudy fetch-data --dataset ml-latest-small
uv run easystudy create-user you@example.com yourpassword
uv run easystudy serve --debug
Extras work the same way: uv sync --extra recbole, etc.
Docker
Useful if you'd rather not install any Python locally, or want something closer to a real deployment (gunicorn, optional redis-backed sessions):
git clone https://github.com/pdokoupil/EasyStudy.git
cd EasyStudy
python scripts/fetch_data.py --dataset ml-latest-small
docker compose up --build # http://localhost:8000
Create an account at /signup, or docker compose exec app flask create-user you@example.com yourpassword.
To unlock more algorithms, rebuild with extras (same Python 3.11 caveat for recbole applies):
EASYSTUDY_EXTRAS="recbole" docker compose up --build
PYTHON_VERSION=3.11 EASYSTUDY_EXTRAS="recbole" docker compose up --build
pip/uv vs. Docker — what actually differs
All three paths run the identical app; they only differ in how much Docker sets up for you:
easystudy serve |
easystudy serve --prod |
Docker | |
|---|---|---|---|
| WSGI server | Flask dev server (not for production) | gunicorn | gunicorn |
| Redis-backed sessions | run your own redis-server + set SESSION_TYPE/REDIS_URL |
same | docker compose --profile redis up starts one for you |
| Heavy extras | pip install -e ".[recbole]" / uv sync --extra recbole |
same | EASYSTUDY_EXTRAS=recbole build arg |
| Default port | 8000 (--port to change) |
8000 | 8000 (PORT env var to change) |
Gunicorn is a core dependency either way — Docker doesn't add capability, it just automates the setup (and gives you an isolated container). Redis works identically regardless of how you installed EasyStudy; it's just an environment-variable switch.
Datasets
Datasets and item images are fetched on demand (they are intentionally not committed to git). Use
python scripts/fetch_data.py before installing anything (it's stdlib-only), or easystudy fetch-data
after pip install/uv sync — same script either way:
python scripts/fetch_data.py --dataset ml-latest-small # small, fast demo (recommended first try)
python scripts/fetch_data.py --dataset all # MovieLens + goodbooks, CSVs + images
python scripts/fetch_data.py --dataset ml-latest --no-images
python scripts/fetch_images.py --dataset ml-latest-small # pre-cache all posters (optional, ~1 min)
Once you've pip install-ed and use easystudy serve from this same checkout directory, switch to
easystudy fetch-data/easystudy fetch-images for anything after that. The raw scripts always write
to server/static/datasets; the CLI redirects everything (including these) to your current directory
instead — mixing the two silently produces two different data directories, and easystudy serve won't
see anything the raw scripts fetched (it'll look empty and re-fetch slowly from IMDb/MovieLens on
every request instead of using the cache).
Sources: ml-latest-small / ml-latest, goodbooks-10k. Images mirror: ml_latest_img.zip, goodbooks_img.zip.
Plugins
See the paper for the detailed description of plugins.
- fastcompare — compare 2–3 algorithms on an implicit-feedback dataset. Extend it with new data loaders, algorithms, preference-elicitation methods, or metrics via subclassing.
- utils — shared functionality (not a study template).
- layoutshuffling — a plugin from one of our internal studies (illustrative).
- vae — MultVAE / StandardVAE / RBM algorithms for fastcompare (needs
[tensorflow]). - recbole — BPR / LightGCN / NGCF / NeuMF / DMF for fastcompare (needs
[recbole]). - empty_template — the minimal working plugin; start here.
Development
Extending fastcompare
Add a class subclassing the appropriate base — either directly in plugins/fastcompare/algo/*.py or in a
separate plugin plugins/<yourplugin>/*.py:
- Datasets → subclass
DataLoaderBase(seeGoodbooksDataLoader); put data under static/datasets or ship it inside your plugin and usepm.emit_assets(...). - Algorithms → subclass
AlgorithmBase. - Preference elicitation → subclass
PreferenceElicitationBase. - Evaluation metrics → subclass
EvaluationMetricBase.
All abstract methods/properties are documented in the base-class docstrings. Algorithm parameters annotated on your class automatically become clickable, configurable fields in the study-creation UI.
Heads-up: heavy backends (RecBole, TensorFlow, LensKit) are optional extras. Plugin discovery skips modules whose optional dependency isn't installed, so the lightweight core runs fine without them — install the matching extra to enable those algorithms.
Adding a plugin
Create a folder under server/plugins/. A study plugin should expose:
/create— renders the parameter page; must ultimately call/create-user-study./initialize— post-creation setup (do long work in a background daemon; then mark the studyinitialized=True,active=True)./join— entry point when a participant follows the study URL./results(optional) — custom evaluation view; falls back toutils' default if omitted.
Start from empty_template. See CONTRIBUTING.md.
Links
- Documentation — quickstart, concepts, guides, API reference.
- Studies built with EasyStudy — peer-reviewed publications whose user studies were run on EasyStudy (recommender systems & data visualization).
- Live demo & hosted instance — hosted administration/database (access details in the paper) and the walkthrough video. Hosted URLs can change, so they live on that page rather than in short links here.
- Walkthrough recording (YouTube).
Citation
If you use EasyStudy in your research, please cite the RecSys'23 paper (see CITATION.cff):
@inproceedings{dokoupil2023easystudy,
author = {Dokoupil, Patrik and Peska, Ladislav},
title = {EasyStudy: Framework for Easy Deployment of User Studies on Recommender Systems},
year = {2023},
isbn = {9798400702419},
publisher = {Association for Computing Machinery},
address = {New York, NY, USA},
url = {https://doi.org/10.1145/3604915.3610640},
doi = {10.1145/3604915.3610640},
booktitle = {Proceedings of the 17th ACM Conference on Recommender Systems},
pages = {1196–1199},
numpages = {4},
keywords = {Recommender systems, evaluation frameworks, user centric, user studies},
location = {Singapore, Singapore},
series = {RecSys '23}
}
License
MIT. Contributions welcome — see CONTRIBUTING.md.
Contact
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file easystudy-1.0.0.tar.gz.
File metadata
- Download URL: easystudy-1.0.0.tar.gz
- Upload date:
- Size: 2.3 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
929834b72050c4163839a03ce6d1245935ac70e5412988c95d742c2f1fccc0b4
|
|
| MD5 |
b489850af9c4519b082280fe350c82ab
|
|
| BLAKE2b-256 |
104798134f2c97ab3f2a013bcbd25f6738f2bcd644c1043ab6361af2250c8be6
|
File details
Details for the file easystudy-1.0.0-py3-none-any.whl.
File metadata
- Download URL: easystudy-1.0.0-py3-none-any.whl
- Upload date:
- Size: 2.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5416bd73dc2699c04c96adff2ff747390ff23b3cb7d98e0200744b0ac5e0d2ff
|
|
| MD5 |
cdb0a9b649da88101f2c2eaff0961e5e
|
|
| BLAKE2b-256 |
ee3916fcbd2e45de9d9c740836e6026e922537ae3568cf78f2f4cb17175a07c1
|