Skip to content

Add HTTPS gateway kernel support to Papermill provider - #73250

Open
gaviiin wants to merge 1 commit into
apache:mainfrom
gaviiin:papermill-https-gateway-52893
Open

gaviiin wants to merge 1 commit into
apache:mainfrom
gaviiin:papermill-https-gateway-52893

Conversation

@gaviiin

@gaviiin gaviiin commented Sep 16, 2026

Copy link
Copy Markdown

The Papermill provider supports remote Jupyter kernels only over raw ZMQ/TCP, which requires the kernel's five ZMQ ports to be directly reachable. Deployments based on JupyterHub, Jupyter Kernel Gateway, or Enterprise Gateway instead expose kernels through an HTTPS REST + WebSocket API secured with a token, so their users cannot run notebooks on remote kernels at all.

This PR adds a second, parallel "gateway" mode to the Jupyter Kernel connection:

  • When the connection host is an http(s):// URL (or the use_gateway extra is set), the hook returns a GatewayKernelConnection and the notebook is executed through a new papermill engine built on jupyter_server's gateway machinery (GatewayKernelManager / GatewayKernelClient), which already implements the kernel REST + WebSocket protocol.
  • The auth token comes from the connection password (or a token extra). Optional extras cover verify_ssl (with proper CERT_NONE handling for self-signed certificates), ca_certs/client_cert/client_key, request_timeout/connect_timeout, custom headers, and kernel_id to attach to a pre-existing kernel instead of starting a new one.
  • Two gaps in jupyter_server's GatewayKernelClient.start_channels (present on main and v2.21.0) are worked around in a small subclass: the kernel-channels WebSocket handshake is opened without the authorization/cookie headers that load_connection_args applies to REST calls (any token-secured server rejects it with 403), and validate_cert=False is not honored for the WebSocket. The subclass routes the WebSocket headers through load_connection_args so token renewal and session cookies behave exactly as they do for REST requests.
  • Kernel lifecycle is managed defensively: kernels started for a run are shut down even when execution or client setup fails (no kernel leaks on the gateway), attached kernels are never shut down by any cleanup path, attaching to an unknown kernel_id fails fast instead of silently starting a leaked default-named kernel, and the gateway client singleton is rebuilt per run so one connection's credentials/timeouts cannot leak into another run in the same process.
  • The existing raw-ZMQ path is unchanged and remains the default for plain hostname/IP connections.

Includes unit tests, a system-test example Dag, and documentation for the new connection mode. The one new dependency is jupyter_server (BSD-3-Clause, ASF Category A). Verified end-to-end against a local token-secured Jupyter Kernel Gateway over plain HTTP and over self-signed HTTPS, including attach mode and kernel-leak checks.

closes: #52893


Was generative AI tooling used to co-author this PR?
  • Yes (AI-assisted development tooling)

Generated with AI assistance following the guidelines; all code was reviewed, statically checked, and tested locally (unit tests plus live end-to-end runs against a token-secured Jupyter Kernel Gateway).

The Papermill provider could reach remote Jupyter kernels only over raw
ZMQ/TCP, which requires directly exposed kernel ports. Deployments based
on JupyterHub, Jupyter Kernel Gateway, or Enterprise Gateway expose
kernels through an HTTPS REST + WebSocket API secured with a token, so
their users could not run notebooks on remote kernels at all.

The Jupyter Kernel connection now also accepts an http(s):// URL with a
token, and the notebook is executed through the gateway API in that
case. This includes TLS options (verify_ssl, CA/client certificates),
custom headers and timeouts, and attaching to a pre-existing kernel via
a kernel_id extra. Kernel lifecycle is managed so that kernels started
for a run are always shut down (even on failure) while attached kernels
are never touched, and gateway credentials are scoped to a single run.
@boring-cyborg

boring-cyborg Bot commented Sep 16, 2026

Copy link
Copy Markdown

Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our Contributors' Guide
Here are some useful points:

  • Pay attention to the quality of your code (ruff, mypy and type annotations). Our prek-hooks will help you with that.
  • In case of a new feature add useful documentation (in docstrings or in docs/ directory). Adding a new operator? Check this short guide Consider adding an example Dag that shows how users should use it.
  • Consider using Breeze environment for testing locally, it's a heavy docker but it ships with a working Airflow and a lot of integrations.
  • Be patient and persistent. It might take some time to get a review or get the final approval from Committers.
  • Please follow ASF Code of Conduct for all communication including (but not limited to) comments on Pull Requests, Mailing list and Slack.
  • Be sure to read the Airflow Coding style.
  • Always keep your Pull Requests rebased, otherwise your build might fail due to changes not related to your commits.
    Apache Airflow is a community-driven project and together we are making it better 🚀.
    In case of doubts contact the developers at:
    Mailing List: dev@airflow.apache.org
    Slack: https://s.apache.org/airflow-slack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for Papermill using https

1 participant