Back to Scaling Python Applications guides

Getting Started with IPython

Stanley Ulili
Updated on April 10, 2025

IPython is an interactive shell for Python that offers enhanced features beyond the standard Python REPL (Read-Eval-Print Loop).

IPython's feature set includes syntax highlighting, tab completion, history recall, and magic commands that streamline your workflow and boost productivity.

This article will guide you through setting up and using IPython effectively in your Python development workflow.

Prerequisites

To follow this article, install Python 3.8 or higher on your system. This tutorial also assumes you are familiar with Python programming and command-line operations.

Getting started with IPython

In this section, you'll set up IPython and take your first steps using its powerful interactive features.

Start by creating a new directory for this tutorial and navigate into it:

 
mkdir ipython-tutorial
 
cd ipython-tutorial

It's best practice to use a virtual environment to manage your dependencies. Create and activate one with the following commands:

 
python3 -m venv venv
 
source venv/bin/activate   

Once activated, your shell prompt may change to show the environment name (e.g., (venv)), indicating that you're working inside the virtual environment.

Now install IPython using pip:

 
pip install ipython

Once installation is complete, you can launch IPython by simply typing the following in your terminal:

 
ipython

You should see an informative startup message followed by the IPython prompt, which looks like this:

 
Python 3.13.2 (main, Feb  4 2025, 14:51:09) [Clang 16.0.0 (clang-1600.0.26.6)]
Type 'copyright', 'credits' or 'license' for more information
IPython 9.1.0 -- An enhanced Interactive Python. Type '?' for help.
Tip: You can use `%hist` to view history, see the options with `%history?`

In [1]: 

The numbered prompt In [1]: is your first indication that you're in an environment different from the standard Python REPL. Let's try a simple command to see IPython in action:

 
In [1]: print("Hello, IPython!")
   ...: 
Hello, IPython!

In [2]: 

You'll immediately notice differences from the standard Python interpreter: syntax highlighting, automatic indentation, and a numbered prompt system that helps you keep track of your commands.

Enhanced features of IPython

IPython offers numerous improvements over the standard Python interpreter. Let's explore some of the most useful ones.

Diagram of some of the IPython features

Tab completion

One of IPython's most productivity-enhancing features is its tab completion. To experience this, type the first few letters of a variable, function, or module name, and press the Tab key:

 
In [2]: import mat<TAB>

IPython will show you available completions:

Output
math             matplotlib_inline

This works for exploring modules and objects too:

 
In [2]: import math
In [3]: math.<TAB>

This will display all available methods and attributes in the math module:

Output
acos()      atan()      ceil()      cosh()      erf()       .....

Tab completion also works for file paths, making it easy to load data files or scripts:

 
In [4]: with open("my_f<TAB>

Help system

IPython offers several ways to access documentation. Adding a question mark after any object displays its documentation:

 
In [4]: math.sin?

This will display detailed information about the sin function:

Output
Signature: math.sin(x, /)
Docstring: Return the sine of x (measured in radians).
Type:      builtin_function_or_method

Magic commands

IPython includes "magic" commands, which are special commands that extend Python's capabilities. They're prefixed with % for single-line commands (line magics) and %% for multi-line blocks (cell magics).

In the examples:

  • %timeit measures how long a code takes to run, helping with performance testing.
  • %pwd shows the current working directory.
  • %ls lists the contents of the current directory, similar to a shell command.

These magics are handy for tasks like timing code, navigating files, and interacting with the system without leaving the IPython environment:

 
In [7]: %timeit [i**2 for i in range(1000)]
33.1 μs ± 448 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
In [8]: %pwd
Out[8]: '/Users/stanley/ipython-tutorial'

In [9]: %ls
venv/

Cell magics operate on multiple lines:

 
In [10]: %%time
   ....: total = 0
   ....: for i in range(1000000):
   ....:     total += i
   ....: print(f"Sum: {total}")
Sum: 499999500000
CPU times: user 74.4 ms, sys: 1.98 ms, total: 76.4 ms
Wall time: 75.2 ms

You can view all available magic commands using:

 
In [11]: %lsmagic
Output
Available line magics:
%alias  %alias_magic  %autoawait  %autocall  %autoindent  %automagic  %bookmark  ...

History and session management

IPython maintains a history of your commands, making it easy to recall and reuse previous inputs.

Use up and down arrow keys to navigate your command history. You can also search your history by pressing Ctrl + R and typing part of a previous command.

The %history magic gives you more control over history display:

 
In [12]: %history -n 5-10
Output
    ...: 
   5: import math
   6: math.sqrt??
   7: %timeit [i**2 for i in range(1000)]
   8: %pwd
   9: %ls
  10:
%%time
total = 0

for i in range(1000000):
     total += i
print(f"Sum: {total}")

This shows commands 5 through 10 from your current session.

IPython also allows you to save and load sessions:

 
In [13]: %save my_session 1-13
The following commands were written to file `my_session.py`:
....
In [14]: %load my_session.py

Enhancing your IPython setup with extensions

IPython can be extended with a variety of extensions that add functionality. These extensions can be loaded directly into your session or configured to load automatically into your profile.

Let's install some popular extensions:

 
pip install ipython-extensions
 
pip install ipython-sql

Now, let's load an extension to enable SQL integration:

 
In [18]: %load_ext sql

Next, try setting a specific style for the SQL magic before using it:

 
%config SqlMagic.style = 'PLAIN'

Now you can run SQL queries directly in IPython

 
In [19]: %%sql sqlite://
   ....: CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT);
   ....: INSERT INTO test VALUES (1, 'Alice');
   ....: SELECT * FROM test;
Output
Done.
1 rows affected.
Done.

With that completed, let’s explore how debugging works in IPython.

Debugging in IPython

IPython makes debugging easier with interactive tools that help you quickly identify and fix problems in your code.

When an error occurs, you can jump into a live debug session using %debug to inspect variables and trace the issue. You can also enable automatic debugging with %pdb on, so you're dropped into the debugger as soon as an exception happens.

The diagram below shows how a typical IPython debugging workflow looks:

Screenshot of the IPython debugging workflow

When running code and hitting an exception, IPython captures the full traceback. To investigate what went wrong, you can enter debug mode by typing %debug right after the error:

 
In [29]: def problematic_function(x):
    ...:     return 1/x
    ...: 
In [30]: problematic_function(0)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
Cell In[10], line 1
----> 1 problematic_function(0)

Cell In[9], line 3, in problematic_function(x)
      1 def problematic_function(x):
----> 3     return 1/x

ZeroDivisionError: division by zero

In [31]: %debug
    ...: 
> <ipython-input-9-c93db0d28861>(3)problematic_function()
      1 def problematic_function(x):
      2 
----> 3     return 1/x
      4 

ipdb> x
0
ipdb> quit

You can also set up automatic debugging:

 
In [32]: %pdb on
Automatic pdb calling has been turned ON

In [33]: problematic_function(0)

This will automatically drop you into the debugger when an exception occurs.

Using IPython for efficient development workflows

IPython can significantly enhance your development workflow. Here's a pattern for interactive development:

  1. Write code in your editor/IDE
  2. Load it into IPython for testing
  3. Refine and reload

Exit the current IPython session by typing:

 
exit

or pressing Ctrl+D and confirming when prompted.

Then, from your terminal, install NumPy, as we'll use it for generating test data:

 
pip install numpy

Now, create a file called my_module.py with the following function:

 
def analyze_data(data):
    """Analyze input data and return results"""
    return data.mean(), data.std()

Start a new IPython session from your terminal:

 
ipython

Then, within IPython, you can load and test your function:

 
In [34]: import my_module

In [35]: import numpy as np

In [36]: data = np.random.normal(0, 1, 1000)

In [37]: my_module.analyze_data(data)
Out[37]: (np.float64(-0.005131730278217276), np.float64(1.0364205270716826))

If you modify the file, you can reload it easily:

 
In [38]: %load_ext autoreload

In [39]: %autoreload 2

Now, when you edit my_module.py, the changes will be automatically available without restarting IPython.

Integrating IPython with other tools

IPython works well with many other Python tools and libraries. For instance, you can use it with popular web frameworks like Flask for interactive debugging.

If Flask isn’t already installed, you can install it directly from your IPython session using the ! shell escape:

 
!pip install flask

Once installed, you can create and test a basic Flask route interactively:

 
In [41]: from flask import Flask
In [42]: app = Flask(__name__)

In [43]: @app.route('/')
    ...: def hello():
    ...:     return "Hello, World!"
    ...: 

In [43]: # Test your route logic
    ...: hello()
Out[43]: 'Hello, World!'

This makes IPython a great environment for exploring and debugging route logic before running a full web server.

Final thoughts

IPython is a powerful tool that makes working with Python faster, easier, and more interactive. From better debugging to auto-reloading code and using magic commands, it helps you write and test code more efficiently.

Whether building web apps, analyzing data, or experimenting, IPython can boost your workflow.

Want to go further? Check out the official IPython docs to learn more.

Happy coding!

Author's avatar
Article by
Stanley Ulili
Stanley Ulili is a technical educator at Better Stack based in Malawi. He specializes in backend development and has freelanced for platforms like DigitalOcean, LogRocket, and AppSignal. Stanley is passionate about making complex topics accessible to developers.
Got an article suggestion? Let us know
Next article
A Complete Guide to Python Type Hints
Learn how to use type hints in Python with the typing module and mypy. Improve your code quality, catch bugs early, and make your code easier to read and maintain with modern static typing techniques.
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Make your mark

Join the writer's program

Are you a developer and love writing and sharing your knowledge with the world? Join our guest writing program and get paid for writing amazing technical guides. We'll get them to the right readers that will appreciate them.

Write for us
Writer of the month
Marin Bezhanov
Marin is a software engineer and architect with a broad range of experience working...
Build on top of Better Stack

Write a script, app or project on top of Better Stack and share it with the world. Make a public repository and share it with us at our email.

community@betterstack.com

or submit a pull request and help us build better products for everyone.

See the full list of amazing projects on github