Magics: line, cell and shell commands

Time, capture, run and shell out from a notebook, and write a small magic of your own when the built-in ones run out.

Line, cell and shell syntax

Magics are not Python. A line magic starts with one percent sign and applies to the rest of that line; a cell magic uses two and applies to the entire cell body; a leading exclamation mark sends the line to the system shell.

MagicApplies toTypical use
%timeitOne lineCompare two implementations quickly
%%timeWhole cellTime an expensive block once
%%captureWhole cellSuppress or collect noisy output
%%bashWhole cellRun a multi-line shell script
%runOne lineExecute a .py file in the kernel namespace
%load_extOne lineEnable an extension such as autoreload

The ones you will actually use

%timeit -n 100 -r 5 sorted(data)

%%time
model.fit(X_train, y_train)

%%capture noisy
plot_everything()          # output stored in "noisy", nothing rendered

%run preprocess.py            # definitions land in the notebook namespace
%load_ext autoreload
%autoreload 2                 # re-import edited modules automatically
%%bash
set -euo pipefail
for f in data/raw/*.csv; do
  wc -l "$f"
done
  • %timeit runs many iterations and reports statistics; use %%time when a single run is all you can afford.
  • Shell magics run in a fresh shell each time, so cd and exported variables do not persist between cells.
  • Output captured by %%capture name can be re-displayed later with display(name).

Writing your own magic

from IPython.core.magic import register_line_magic, register_cell_magic

@register_line_magic
def sql(line):
    """Run a query and return a DataFrame."""
    import pandas as pd, sqlite3
    con = sqlite3.connect("app.db")
    return pd.read_sql_query(line, con)

%sql SELECT status, count(*) FROM orders GROUP BY status

Loading a magic is just importing a module. Register the function once and every cell afterwards can use the syntax.

⚠️
Magics make a notebook un-runnable as plain Python: a script or a linter will choke on %timeit. Keep exploratory magics in notebooks and never let them leak into the modules your notebook imports.

FAQ

How do I install a package from inside a notebook?
Use %pip install package in a cell. It installs into the kernel's environment, unlike a bare !pip which may pick up a different interpreter. Restart the kernel if a C extension was replaced.
Is %timeit trustworthy?
It is reliable for micro-benchmarks, but it measures the kernel's view of the world: caches, warmed imports and background work all affect it. For real performance work, benchmark a script from the command line with a profiler.

Notebook fundamentals Debugging and the hidden-state trap

Last refreshed 2026-09-18.