notebooker: turning committed Jupyter notebooks into scheduled, parameterised reports
Productionise & schedule your Jupyter Notebooks as easily as you wrote them.
At a glance
- What is it?
- Notebooker is a Python webapp that executes and parameterises Jupyter notebooks as soon as they are committed to git, stores the results in MongoDB and serves them as searchable reports. It leans on papermill, jupytext and nbconvert rather than reimplementing notebook execution, which keeps the integration surface small but ties it to MongoDB and to a copyleft licence.
- Who is it for?
- Adopt notebooker when a team already writes notebooks in git and needs the same notebooks to run on a schedule with parameters, and when MongoDB is an acceptable dependency. Do not adopt it as a general notebook runner, since the storage layer and the copyleft licence are part of the design rather than optional extras.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 40 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A notebook that runs when it reaches git
notebooker is a webapp built around one idea: a Jupyter notebook becomes a report the moment it is committed. The project description puts it plainly, productionise and schedule your Jupyter Notebooks just as interactively as you wrote them.
The mechanism has three parts. Notebooks are executed, and can be parameterised, on the web service or from the command line. The outputs are written to MongoDB. The web interface then turns that store into something searchable, which is what makes the result feel like a report rather than a pile of files in a bucket.
The audience is an analyst or quant who already writes notebooks interactively and then discovers that the real request is for the same analysis to run every morning, with a different date or universe each time, and to be readable by someone who does not have a Jupyter environment. The project is aimed squarely at that transition, and the feature list is organised around it: run a notebook as a report with parameters, execute notebooks on the webservice or the command line, view outputs as static HTML, and drill down into each template's results from the home page.
What it is not is a notebook authoring environment. You still write the notebook elsewhere. Notebooker is the deployment layer around it.
papermill, jupytext and nbconvert do the actual work
The credits section names the projects notebooker builds on, and reading that list is the fastest way to understand the architecture. The credits section names the projects notebooker is built alongside: Jupytext, papermill, nbconvert and Fomantic-UI.
The repository layout follows the same division. There is a `notebooker/` package containing the code, a `docker/` directory that holds the example deployment, a `docs/` directory that feeds the readthedocs site, a `tests/` directory, and packaging files in `setup.py`, `setup.cfg` and `pyproject.toml`. A `.circleci/` directory and a `.pre-commit-config.yaml` sit at the top level, so continuous integration and pre-commit hooks are part of the project's own workflow rather than something added later.
The important consequence for an adopter is that notebooker is an integration layer, not a notebook engine. Its own code is the web interface, the scheduling and execution plumbing, the MongoDB persistence and the template handling. Anything about how a notebook is parameterised or how its output is converted lives in papermill and nbconvert, which means the behaviour of those two projects is part of notebooker's behaviour, and the documentation for them matters as much as the notebooker documentation.
Notebooker also describes templates, the run a report dialog, and template results listings, so the unit of work for a user is a template rather than an arbitrary notebook file.
Getting a first look with docker-compose
The README points to the documentation at notebooker.readthedocs.io for installation instructions, and then offers a faster route for anyone who just wants to see the thing work. It says that if you want to explore an example right away, you can use docker-compose.
cd docker
docker-compose upThe README states that this will expose Notebooker at http://localhost:8080/ with the example templates. That is the whole first-run experience: a directory in the repository, a compose file, and a local URL. It is worth noting what this path does not require, because it shapes who can try the project. No Python environment, no MongoDB provisioning and no scheduling setup are needed for the demo, since the compose file handles the service graph. If a colleague wants to see whether the reporting model fits their work, this is the cheapest possible test.
The README also records the platforms the project has been tested on: Linux, Windows 10 and OSX, with the webapp tested on Google Chrome. That is a narrow but specific statement about what the maintainers actually exercised.
For anything beyond the demo, the documentation is the reference, since the README does not document pip installation steps, the MongoDB connection settings, the scheduling mechanism or how results are retained.
Five console entry points hiding in setup.py
The packaging file is where the tool's shape becomes clearest, because the entry point list is longer than the README's feature list would suggest.
"console_scripts": [
"notebooker-cli = notebooker._entrypoints:base_notebooker",
"notebooker_execute = notebooker.execute_notebook:docker_compose_entrypoint",
"notebooker_template_sanity_check = notebooker.utils.template_testing:sanity_check",
"notebooker_template_regression_test = notebooker.utils.template_testing:regression_test",
"convert_ipynb_to_py = notebooker.convert_to_py:main",
]Five commands are installed. `notebooker-cli` is the main command line interface. `notebooker_execute` points at a function named `docker_compose_entrypoint`, which tells you the command line execution path is expected to run inside the compose deployment rather than as a standalone process. Two further commands, `notebooker_template_sanity_check` and `notebooker_template_regression_test`, exist to test templates, and the last one, `convert_ipynb_to_py`, converts a notebook to a Python file.
That last command pairs with the Jupytext dependency and with the project's stated interest in parametrised, productionised notebooks. Converting a notebook into a script is the step that turns an analysis into something a scheduler can run, and notebooker ships a command for it rather than leaving it to you.
The two template testing commands are the ones most likely to be overlooked by a new user, and they are the most useful in practice. Before a template is put on a schedule, it can be checked with the sanity and regression checks the project provides.
Where notebooker is the wrong shape for the job
There are three constraints worth weighing before you commit, and none of them are hidden.
The first is MongoDB. Results are stored in MongoDB, so a deployment means running a MongoDB instance, and a team without one in its stack inherits an operational dependency purely for report storage. If your results are a handful of daily HTML files, that is a large piece of infrastructure for a small job.
The second is the licence. The licence field on the repository says AGPL-3.0, a strong copyleft licence. For a service that is modified and then offered over a network, that identifier has consequences for how the modified source is made available, and organisations with a standing policy against strong copyleft should have that read by someone qualified. Nothing in this article is legal advice, and the point here is only that the licence is a design input here, not a detail.
The third is the Python floor. setup.py declares `python_requires=">=3.6"`, and the formatting configuration in pyproject.toml targets py36, py37 and py38 with a line length of 120 for both black and ruff.
[tool.black]
line-length = 120
target-version = ['py36', 'py37', 'py38']
[tool.ruff]
line-length = 120A floor of 3.6 is generous by today's standards and makes installation easy on old machines, but the tool targets are older than the versions most teams now standardise on, so the project is not asserting compatibility with a recent Python release in its own configuration. The README also does not document a supported upgrade path for the stored results, so treat a schema change as something to check rather than assume.
Release history and what it says about the project
Three releases appear in the recent history: 0.8.1 on 2026-06-05, 0.8.0 on 2026-05-22 and 0.7.3 on 2026-05-20. The version numbers are below 1.0, which is a signal about the project's own expectations for its interface, and the 0.7.3 to 0.8.0 step is where behaviour is most likely to shift.
The repository is not archived, and the last push was on 2026-09-13. The README states that Notebooker has been actively maintained at Man Group since late 2018, with the original concept built by Jon Bannister, and it credits a list of individual contributors plus the upstream projects it builds on.
For an adopter, the practical consequence of that history is that the project has been developed inside one organisation for a long time and carries that organisation's deployment assumptions, particularly around Docker and MongoDB. The cost of adoption is not the install. It is the size of the gap between how Man Group runs the service and how your infrastructure runs services, and the AGPL-3.0 licence, which in an enterprise setting is usually a bigger question than the code.
Editorial conclusion
Adopt notebooker when a team already writes notebooks in git and needs the same notebooks to run on a schedule with parameters, and when MongoDB is an acceptable dependency. Do not adopt it as a general notebook runner, since the storage layer and the copyleft licence are part of the design rather than optional extras. Before deploying, read the installation instructions at notebooker.readthedocs.io and confirm that the AGPL-3.0 licence in the repository is acceptable for how you intend to run the service.
Frequently asked questions
How do I try notebooker without setting up MongoDB and Python myself?
The README offers a docker-compose example. Run `cd docker` and then `docker-compose up`, which the README says will expose Notebooker at http://localhost:8080/ with the example templates.
Does notebooker run notebooks on a schedule and with parameters?
Yes. The project describes itself as a webapp which can execute and parametrise Jupyter Notebooks as soon as they have been committed to git, and the description says it can productionise and schedule notebooks.
Where are notebooker results stored?
The README states that the results are stored in MongoDB and are searchable via the web interface. Outputs can also be viewed as static HTML, and each template's results can be drilled into from the home page.
Can I run a notebook from the command line with notebooker?
Yes. The packaging file installs a `notebooker-cli` console script and a separate `notebooker_execute` entry point that points at a docker compose entrypoint, and the README describes executing notebooks either on the webservice or on the command line.
What licence is notebooker released under?
The licence field on the repository says AGPL-3.0. Whether that suits your organisation is a question for whoever handles licence review, since the project is intended to be deployed as a web service.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/man-group-notebooker)Was this useful?