sparkmagic#
Sparkmagic is a set of tools for interactively working with remote Spark clusters in Jupyter notebooks. Sparkmagic communicates with remote Spark clusters through a REST server. Three server implementations are currently compatible with Sparkmagic:
- Livy β for running interactive sessions on YARN
- Lighter β for running interactive sessions on YARN or Kubernetes (PySpark sessions only)
- Ilum β for running interactive sessions on YARN or Kubernetes
Sparkmagic includes a set of magics for interactively running Spark code in multiple languages, as well as dedicated kernels that turn Jupyter into an integrated Spark environment β all without requiring any Spark components on the Jupyter server itself.
![]()
![]()
![]()
![]()
Features#
- Multi-language Spark execution β Run Spark code in Python, Scala, and R against any remote cluster through Livy
- Automatic context creation β
SparkContext(sc) andHiveContext(sqlContext) are created automatically at session startup - SparkSQL support β Run SQL queries easily with the
%%sqlmagic - Automatic visualization β Results from SQL queries are automatically visualized in PySpark, Spark, and SparkR kernels using an interactive, no-code visual interface
- Logs and app info β Inspect Spark application information and driver logs with the
%%infoand%%logsmagics - Pandas integration β Capture SQL query output as Pandas DataFrames to interact with any Python data science library
- Local-to-Spark data transfer β Send local variables, files, or DataFrames to the remote cluster with
%%send_to_spark - Flexible authentication β Supports no authentication, HTTP Basic Access, and Kerberos
- Configurable retries and heartbeats β Built-in session resilience via configurable retry policies and heartbeat management
Installation#
Prerequisites#
- Python 3.8 or later β CI tests run against Python 3.8, 3.9, 3.10, 3.11, and 3.12
- Jupyter Notebook or JupyterLab (see version-specific steps below)
- libkrb5-dev (Linux) β required only if you plan to use Kerberos authentication
Jupyter Notebook 7.x / JupyterLab 3.x#
-
Install the library
pip install sparkmagic -
Ensure ipywidgets is installed
pip install ipywidgets -
(Optional) Install the wrapper kernels
Run
pip show sparkmagicto find the installation path, thencdto that location and run:jupyter-kernelspec install sparkmagic/kernels/sparkkernel jupyter-kernelspec install sparkmagic/kernels/pysparkkernel jupyter-kernelspec install sparkmagic/kernels/sparkrkernel -
(Optional) Configure Sparkmagic
Edit (or create)
~/.sparkmagic/config.json. Seesparkmagic/example_config.jsonfor a full list of options. -
(Optional) Enable the server extension
Enables programmatic cluster switching via the
/reconnectsparkmagicAPI:jupyter server extension enable --py sparkmagic
Jupyter Notebook 5.2 or Earlier / JupyterLab 1 or 2#
-
Install the library
pip install sparkmagic -
Enable the notebook widget extension
jupyter nbextension enable --py --sys-prefix widgetsnbextension -
JupyterLab 1 or 2 only β install the JupyterLab widget manager:
jupyter labextension install "@jupyter-widgets/jupyterlab-manager" -
(Optional) Install the wrapper kernels (same as above)
-
(Optional) Configure
~/.sparkmagic/config.json -
(Optional) Enable the server extension (legacy command):
jupyter serverextension enable --py sparkmagic
Installing from Source#
If you want to contribute or test the latest unreleased changes, install the three constituent packages in editable mode:
git clone https://github.com/jupyter-incubator/sparkmagic
cd sparkmagic
pip install -e hdijupyterutils
pip install -e autovizwidget
pip install -e sparkmagic
Alternatively, use Poetry for an isolated virtual environment:
poetry install
# If numpy or pandas installation fails, run:
# poetry run pip install numpy pandas
# then re-run:
poetry install
Configuration#
Sparkmagic reads its configuration from ~/.sparkmagic/config.json. If the file does not exist, sensible defaults are used. A fully annotated reference is available at sparkmagic/example_config.json.
Kernel Credentials#
Set the Livy endpoint, credentials, and auth type for each kernel language:
{
"kernel_python_credentials": {
"username": "",
"password": "",
"url": "http://your-livy-server:8998",
"auth": "None"
},
"kernel_scala_credentials": {
"username": "",
"password": "",
"url": "http://your-livy-server:8998",
"auth": "None"
},
"kernel_r_credentials": {
"username": "",
"password": "",
"url": "http://your-livy-server:8998",
"auth": "None"
}
}
Valid auth values are "None", "Basic_Access", and "Kerberos".
Spark Session Defaults#
Two keys control default Spark session configuration :
session_configsβ Default settings that are replaced whenever a user calls%%configure.session_configs_defaultsβ Settings that are preserved even after a user calls%%configure; a user must explicitly override them.
{
"session_configs": {
"driverMemory": "1000M",
"executorCores": 2
},
"session_configs_defaults": {
"spark.sql.catalog.type": "hive"
}
}
Timeouts and Retries#
{
"wait_for_idle_timeout_seconds": 15,
"livy_session_startup_timeout_seconds": 60,
"heartbeat_refresh_seconds": 30,
"livy_server_heartbeat_timeout_seconds": 0,
"heartbeat_retry_seconds": 10,
"retry_policy": "configurable",
"retry_seconds_to_sleep_list": [0.2, 0.5, 1, 3, 5],
"configurable_retry_policy_max_retries": 8
}
HTTP Session Adapters#
For custom HTTP behavior (mTLS, custom retry logic, etc.), configure a transport adapter :
{
"http_session_config": {
"adapters": [
{
"prefix": "http://",
"adapter": "myadapter.module.MyAdapter"
}
]
}
}
Papermill Integration#
To make Sparkmagic stop on Spark errors during Papermill rendering :
{
"shutdown_session_on_spark_statement_errors": true,
"all_errors_are_fatal": true
}
To clean up all registered Livy sessions on exit regardless of process termination type:
{
"cleanup_all_sessions_on_exit": true,
"all_errors_are_fatal": true
}
Programmatic Overrides#
Configuration options can also be overridden at runtime in a notebook :
import sparkmagic.utils.configuration as conf
conf.override('cleanup_all_sessions_on_exit', True)
# Or reference the config key by name:
conf.override(conf.cleanup_all_sessions_on_exit.__name__, True)
Note: Any override that affects session initialization (such as
cleanup_all_sessions_on_exit) must be set before loading the extension with%load_ext sparkmagic.magics.
Authentication#
Sparkmagic supports three built-in authentication methods for connecting to Livy:
| Auth Type | Config Key | Description |
|---|---|---|
| No auth | "None" | Unauthenticated requests |
| HTTP Basic | "Basic_Access" | Username + password |
| Kerberos | "Kerberos" | Ticket-based negotiation |
Kerberos#
Kerberos authentication is implemented via the requests-kerberos package. Sparkmagic expects a valid Kerberos ticket to already be present in the system credential cache β run kinit first.
The default constructor used is:
HTTPKerberosAuth(mutual_authentication=REQUIRED)
This can be customized in ~/.sparkmagic/config.json :
{
"kerberos_auth_configuration": {
"mutual_authentication": 1,
"service": "HTTP",
"delegate": false,
"force_preemptive": false,
"principal": "principal",
"hostname_override": "hostname_override",
"sanitize_mutual_error_response": true,
"send_cbt": true
}
}
Custom Authenticators#
You can implement custom authentication by subclassing the base Authenticator class and overriding __call__(request), which attaches HTTP authentication to the outgoing request.
Subclasses that add new credential attributes (like the built-in Basic authenticator which adds username and password) should also override __hash__, __eq__, update_with_widget_values, and get_widgets so the widget-based credential UI works correctly.
Registering your custom authenticator:
After installing your custom package (e.g. pip install git+https://git_repo_url/#egg=customauthenticator), register it in ~/.sparkmagic/config.json :
{
"authenticators": {
"Kerberos": "sparkmagic.auth.kerberos.Kerberos",
"None": "sparkmagic.auth.customauth.Authenticator",
"Basic_Access": "sparkmagic.auth.basic.Basic",
"Custom_Auth": "customauthenticator.customauthenticator.CustomAuthenticator"
}
}
The key ("Custom_Auth") becomes the display name in the %manage_spark widget dropdown and the value passed to the -t flag in %%spark add.
Usage#
There are two ways to use Sparkmagic. Full working examples are available in the examples/ directory.
1. Via the IPython Kernel#
Use Sparkmagic as a magic extension inside a standard IPython/Jupyter notebook.
Load the extension:
%load_ext sparkmagic.magics
Manage connections with the widget:
%manage_spark
This opens an interactive widget for adding/removing Spark endpoints and sessions.
Run Spark code with %%spark:
%%spark -s mysession -l python
sc.version
Run a SQL query:
%%spark -s mysession -c sql
SELECT * FROM my_table LIMIT 10
Available %%spark subcommands include add, config, run, logs, delete, cleanup, and info. See the Magics in IPython Kernel notebook for a full walkthrough.
2. Via the Spark Kernels#
Sparkmagic provides three dedicated Jupyter kernels that automatically connect to a remote Spark cluster. Select one when creating or switching a notebook:
| Kernel | Language | Kernel Name |
|---|---|---|
| PySpark | Python | pysparkkernel |
| Spark | Scala | sparkkernel |
| SparkR | R | sparkrkernel |
Once inside a kernel, the following magics are available:
| Magic | Description |
|---|---|
%%spark | Execute Spark code; -o captures output as a Pandas DataFrame |
%%sql | Run SparkSQL queries; -o captures results as a Pandas DataFrame |
%%local | Execute code in the local Python process |
%%send_to_spark | Send local variables or DataFrames to the remote cluster |
%%configure | Set Spark session creation parameters (use -f to force if session exists) |
%%info | Show current Spark session info |
%%logs | View Spark driver logs |
%%cleanup | Delete all sessions (requires -f) |
%%delete | Delete a specific session |
%%pretty | Render a DataFrame as an HTML table |
%matplot | Render a matplotlib figure from the remote cluster |
%setup_auth | Configure authentication credentials |
%%help | List all available magics with descriptions |
Example β run Spark code and capture results locally:
%%spark -o df
spark.sql("SELECT year, count(*) as cnt FROM events GROUP BY year ORDER BY year")
%%local
import matplotlib.pyplot as plt
df.plot(x="year", y="cnt", kind="bar")
plt.show()
Example β send a local DataFrame to Spark:
%%send_to_spark -i local_df -t df -n remote_df
3. Sending Local Data to Spark#
See the Send Local Data to Spark notebook for a step-by-step guide on moving DataFrames and other objects between your local environment and the remote Spark cluster.
Docker (Local Development)#
The included docker-compose.yml spins up a complete Sparkmagic stack for local testing and development: a Jupyter notebook server with all extensions installed, and a Livy server backed by a local-mode Spark instance.
Note: This setup is intended for developing and testing Sparkmagic itself. In production, Sparkmagic is most useful when your Spark cluster runs on a separate, remote machine.
Requirements: Docker and Docker Compose
Start the stack:
docker compose build
docker compose up
Open Jupyter in your browser at http://localhost:8888. Inside a notebook, configure a Sparkmagic endpoint at http://spark:8998. This endpoint supports both Scala and Python sessions. You can also start a wrapper kernel for Scala, Python, or R directly from the kernel list.
Stop the stack:
# Interrupt docker compose with Ctrl-C, then optionally:
docker compose down
Developing with live edits:
Set dev_mode: true in the docker-compose.yml build arguments for the jupyter service, then rebuild. This installs your local versions of autovizwidget, hdijupyterutils, and sparkmagic in editable mode, so changes to the source files are reflected immediately inside the running container.
# After changing dev_mode to true:
docker compose build
docker compose up
Server Extension API#
Sparkmagic ships an optional Jupyter server extension that exposes a REST endpoint for programmatic cluster management. Enable it with:
jupyter server extension enable --py sparkmagic # Jupyter Notebook 7.x / JupyterLab 3.x
# or
jupyter serverextension enable --py sparkmagic # older Jupyter
POST /reconnectsparkmagic#
Connects (or reconnects) a specific notebook to a Spark cluster. The kernel is started or restarted and pointed at the provided endpoint.
Request body:
{
"path": "path/to/notebook.ipynb",
"username": "username",
"password": "password",
"endpoint": "http://your-livy-server:8998",
"auth": "Kerberos",
"kernelname": "pysparkkernel"
}
authmust be one ofNone,Basic_Access, orKerberos.kernelnameis optional and defaults to the value set inconfig.json(pysparkkernelif not configured).
Responses:
| Status | Meaning |
|---|---|
200 | Success |
400 | Request body is not valid JSON or a required key is missing |
500 | An error occurred while changing the cluster |
Success response body:
{
"success": true,
"error": null
}
Architecture#
Sparkmagic uses Livy, a REST server for Spark, to remotely execute all user code. The library collects output from your code β as plain text or a JSON document β and displays results as formatted text or Pandas DataFrames, as appropriate.
![]()
Advantages#
-
No local Spark installation required β All Spark code runs remotely; the Jupyter server only needs Python and Sparkmagic installed.
-
Uniform multi-language support β Python, Scala, and R kernels share the same feature set. Adding new language support requires only a new kernel wrapper.
-
Multiple simultaneous endpoints β A single notebook can open Spark jobs in different languages against different remote clusters concurrently.
-
Ecosystem integration β SQL output is materialized as Pandas DataFrames, making it trivially composable with any Python data science or visualization library (e.g., matplotlib, Plotly).
Limitations#
-
Livy overhead β All code and results travel through the Livy REST API, which adds latency compared to running code directly on the cluster.
-
JSON serialization boundary β Structured data (DataFrames) must be serialized to JSON by Livy and deserialized by Sparkmagic on the client side. Client-side data manipulation should use
%%localmode with Python.
Repository Structure#
This repository is a monorepo containing three interdependent Python packages:
| Package | Description |
|---|---|
sparkmagic/ | Core package β Livy client, magics, kernels, server extension, and auth |
autovizwidget/ | Auto-visualization library for Pandas DataFrames |
hdijupyterutils/ | Shared Jupyter utility library |
Contributing#
Contributions of all kinds are welcome β bug reports, feature requests, documentation improvements, and code changes!
Reporting Issues#
- Bugs and feature requests: Open an issue on GitHub.
- Security vulnerabilities: Report privately via https://jupyter.org/security (
security@ipython.org) or through Tidelift. Do not open a public issue for security reports.
Development Setup#
-
Clone the repository
git clone https://github.com/jupyter-incubator/sparkmagic cd sparkmagic -
Install packages in editable mode
pip install -e hdijupyterutils pip install -e autovizwidget pip install -e sparkmagicOr use Poetry for an isolated virtual environment:
poetry install # If numpy/pandas installation fails: # poetry run pip install numpy pandas && poetry install
Running Tests#
Tests use pytest and run against Python 3.8β3.12 in CI.
# Standard install
pytest
# Poetry install
poetry run pytest
Tests are organized per package. The CI workflow runs all three packages (hdijupyterutils, autovizwidget, sparkmagic) on every push and pull request, and on a daily schedule.
To run tests for a specific package only:
cd sparkmagic && pytest
Kerberos note: The CI environment installs
libkrb5-devbefore running tests. If you are testing Kerberos-related code locally, ensure this system library is installed.
Code Style#
All code is formatted with Black. Style compliance is enforced by CI on every push and pull request.
# Format your changes before committing:
black .
Submitting a Pull Request#
- Fork the repository and create a feature branch.
- Make your changes, ensuring tests pass and code is formatted with Black.
- Open a pull request against the
masterbranch with a clear description of the change.
Releases#
Releases are fully automated via GitHub Actions. Maintainers trigger a release by running the Release workflow, selecting the release type (patch, minor, or major). The CHANGELOG.md should be updated on master before triggering a release.
License#
Sparkmagic is licensed under the Modified BSD License (3-Clause BSD).
Copyright Β© 2001β2015 IPython Development Team; 2015β Jupyter Development Team.