Running Notebooks the Ruby Way: From PoC to Production with RubyPyMill

Senior Ruby Engineer · Open-Source Author (ruby-libgd, libgd-gis) · FinTech & GIS

January 20, 2026

In modern development teams, Proofs of Concept (PoC) are everywhere.

They usually start as Jupyter notebooks: quick experiments, charts, metrics, comparisons, and visual insights. They work well for exploration — but too often, they stop there. The knowledge stays locked inside a notebook, on someone’s machine, disconnected from real systems.

This raises a familiar question:

How do we move insights born in notebooks into real, reproducible, production-grade workflows — without rewriting everything?

This is where Ruby as an orchestration language becomes surprisingly powerful.


PoC Is Not the End — It’s the Beginning

A PoC should not be a dead artifact. It should be the first node in a knowledge circulation system.

Yet in practice, many teams struggle with:

  • notebooks that can’t be reproduced reliably
  • parameters hard-coded in cells
  • ad-hoc execution
  • no clear integration with the main application stack

For Ruby teams, this is even more visible when:

  • the core system is written in Ruby (Rails, jobs, services)
  • but experimentation happens in Python notebooks
  • and the two worlds never truly connect
Article content

Ruby as the Orchestration Layer

Ruby has always excelled at:

  • expressive DSLs
  • orchestration
  • pipelines
  • clear intent over ceremony

Rather than competing with Python’s scientific ecosystem, Ruby can coordinate it.

This philosophy aligns closely with the idea of multi-language collaboration, often discussed in the Ruby community and articulated by Yukihiro Matsumoto:

“Ruby aims to connect people with people, and tools with tools.”

Ruby does not need to execute everything — it needs to connect execution into systems.


Introducing RubyPyMill

RubyPyMill is a lightweight Ruby tool designed precisely for this role.

At its core, RubyPyMill allows Ruby to control and orchestrate the execution of Jupyter notebooks using Papermill under the hood.

Important clarification:

  • RubyPyMill does not replace notebooks
  • It does not reimplement Python tooling
  • It does not render charts itself

Instead, it acts as a higher-level execution controller, bringing notebooks into Ruby-driven workflows.


Design Philosophy

RubyPyMill follows a clear separation of responsibilities:

RoleResponsibilityRubyDSLs, orchestration, control, reproducibilityPythonExecution, computation, visualization (notebooks)

This separation is intentional. Ruby defines what should run and how. Python focuses on executing the notebook.


How the Execution Pipeline Works

When RubyPyMill runs a notebook, the flow looks like this:

  1. Load the notebook as JSON
  2. Filter cells by tags (while always preserving parameters)
  3. Inject parameters from JSON files
  4. Generate a temporary filtered notebook
  5. Execute it once via Papermill
  6. Save the executed notebook as an output artifact

This ensures:

  • deterministic execution
  • reproducibility
  • clean separation between setup, analysis, and output
  • notebook execution that can be automated and audited

Why Tags Matter

Tag-based execution is one of the most powerful aspects of this approach.

By tagging notebook cells, teams can:

  • run only relevant sections
  • separate setup from analysis
  • avoid unnecessary re-computation
  • generate different outputs from the same notebook

This turns notebooks from exploratory scratchpads into structured, reusable assets.


Practical Use Cases

RubyPyMill fits naturally into workflows such as:

  • scheduled batch jobs
  • CI pipelines
  • report generation
  • technical comparisons
  • automated analysis runs
  • Ruby-driven data pipelines

All without opening Jupyter or manually executing cells.

The notebook becomes an executable document, controlled by Ruby.


CLI First, API Second

RubyPyMill is intentionally designed as a CLI-first tool.

  • The CLI is stable and production-oriented
  • The internal Ruby API exists, but is experimental

This choice reinforces a key idea: automation and reproducibility come before abstractions.


Why This Matters for Ruby Teams

RubyPyMill highlights an important shift:

Ruby is not just a web language. It is increasingly a coordination language.

In a world of heterogeneous tools, Ruby’s role as a glue language — connecting systems, people, and workflows — becomes more relevant than ever.


Final Thoughts

RubyPyMill is not about notebooks. It is about what happens after the notebook.

It acknowledges a reality many teams face and offers a pragmatic solution:

  • keep Python where it shines
  • bring execution control back into Ruby
  • transform PoCs into reproducible system components

For Ruby developers working alongside data-heavy experimentation, this approach feels both modern and deeply Ruby-like.

Article content

Leave a comment