How to Automatically Play Sound in IPython Notebook When a Long-Running Cell Finishes Executing

If you’ve ever worked with IPython Notebooks (or Jupyter Notebooks) for data analysis, machine learning, or scientific computing, you’ve likely encountered long-running cells. These might be training a neural network, processing large datasets, or running complex simulations—tasks that can take minutes or even hours to complete. Staring at the notebook while waiting is inefficient, but stepping away often means missing when the cell finishes.

A simple solution? Play a sound automatically when the cell completes execution. This way, you can focus on other tasks, and the sound will alert you when your code is ready. In this blog, we’ll explore three methods to achieve this, ranging from quick one-off solutions to persistent, notebook-wide automation.

Table of Contents#

  1. Prerequisites
  2. Method 1: Using IPython’s Audio and Custom Cell Magics (Flexible, Cross-Platform)
  3. Method 2: Custom Jupyter Notebook Extension (Automatic for All Cells)
  4. Method 3: Using Python’s winsound (Windows-Only, No External Dependencies)
  5. Troubleshooting Common Issues
  6. Conclusion
  7. References

Prerequisites#

Before diving in, ensure you have the following:

  • A working Jupyter Notebook/Lab environment (install with pip install jupyterlab or pip install notebook).
  • Basic familiarity with Python and Jupyter Notebook workflows.
  • For some methods:
    • An audio file (e.g., .wav, .mp3) for custom sounds (free options linked in References).
    • For Method 2: Basic knowledge of JavaScript (to write a simple extension).

Method 1: Using IPython’s Audio and Custom Cell Magics (Flexible, Cross-Platform)#

This method is ideal if you want to trigger sounds only for specific cells (e.g., long-running training loops). It uses IPython’s built-in Audio class to play sounds and custom "cell magics" to wrap your code for automatic alerts.

Step 1: Prepare an Audio File (Optional)#

You can use a built-in system beep, but a custom sound (e.g., a chime or notification tone) is more noticeable. For this example, we’ll use a .wav file. You can:

  • Download a free sound (e.g., from Freesound) and save it in your notebook’s directory (e.g., alert.wav).
  • Use a system beep (no file needed—see Step 3).

Step 2: Play Sound with IPython.display.Audio#

First, test if sound playback works in your notebook. Run this code to play your audio file:

from IPython.display import Audio, display  
 
def play_sound(file_path="alert.wav"):  
    """Play a sound from a file."""  
    try:  
        audio = Audio(file_path, autoplay=True)  # autoplay=True plays immediately  
        display(audio)  
    except FileNotFoundError:  
        print(f"Error: Audio file '{file_path}' not found.")  
 
# Test the function  
play_sound("alert.wav")  # Replace with your file path  

If the sound plays, you’re ready to proceed! If not, check the file path or try a different audio format (.wav is most reliable).

Step 3: Wrap Long-Running Code with Sound Alerts#

To trigger the sound after a cell finishes, wrap your code in a try-finally block (to ensure the sound plays even if the code errors) and call play_sound() at the end:

from IPython.display import Audio, display  
 
def play_sound(file_path="alert.wav"):  
    try:  
        display(Audio(file_path, autoplay=True))  
    except FileNotFoundError:  
        # Fallback: Play a system beep (works in some environments)  
        import os  
        os.system('echo -e "\a"')  # Linux/macOS beep  
        # For Windows: os.system('cmd /c "echo ^G"') (where ^G is Ctrl+G in cmd)  
 
# Example long-running cell  
try:  
    # Replace with your code (e.g., training a model, data processing)  
    import time  
    time.sleep(5)  # Simulate 5-second task  
    print("Task completed!")  
finally:  
    play_sound("alert.wav")  # Sound plays after completion (even if there's an error)  

Step 4: Create a Custom Cell Magic (Reusable for Any Cell)#

For frequent use, define a custom cell magic to automate the wrapping. Cell magics (e.g., %%time) let you prefix a cell with a command to modify its behavior. Here’s how to create a %%alert magic that runs your code and plays a sound:

from IPython.core.magic import register_cell_magic  
from IPython.display import Audio, display  
 
@register_cell_magic  
def alert(line, cell):  
    """Cell magic to run code and play a sound on completion.  
    Usage: %%alert [audio_file]  
    Example: %%alert alert.wav  
    """  
    audio_file = line.strip() or "alert.wav"  # Use default if no file specified  
    try:  
        # Execute the cell's code  
        exec(cell, globals())  
    finally:  
        # Play sound after execution (success or failure)  
        try:  
            display(Audio(audio_file, autoplay=True))  
        except FileNotFoundError:  
            print(f"Warning: Audio file '{audio_file}' not found. Using beep.")  
            import os  
            os.system('echo -e "\a"')  # Fallback beep  
 
# Now use it in any cell!  
%%alert alert.wav  
# Your long-running code here  
import time  
time.sleep(3)  
print("This cell used the %%alert magic!")  

Now, any cell prefixed with %%alert (and optional audio file) will play your sound when done!

Method 2: Custom Jupyter Notebook Extension (Automatic for All Cells)#

If you want all cells (not just specific ones) to trigger a sound on completion, use a Jupyter Notebook extension. Extensions are JavaScript-based and can listen to notebook events (e.g., when a cell finishes running).

Step 1: Understand Jupyter Notebook Events#

Jupyter Notebooks expose an API to interact with cell execution. We’ll use the on_cell_executed event to trigger a sound after any cell runs.

Step 2: Create the Extension (JavaScript)#

Create a new file named sound_alert_extension.js in your notebook directory with this code:

// sound_alert_extension.js  
define([  
    'base/js/namespace',  
    'base/js/events'  
], function(IPython, events) {  
    "use strict";  
 
    // Function to play sound  
    function playCompletionSound() {  
        // Option 1: Play a built-in beep  
        // var audio = new Audio('data:audio/wav;base64,UklGRigAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQQAAAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMw=='); // Short beep  
 
        // Option 2: Play a custom sound (host the file locally or use a URL)  
        var audio = new Audio('alert.wav');  // Replace with your file path  
        audio.play().catch(error => {  
            console.error("Sound playback failed:", error);  
        });  
    }  
 
    // Listen for cell execution completion  
    events.on('notebook_model_changed.Notebook', function() {  
        // Check if the last cell executed successfully  
        var notebook = IPython.notebook;  
        var last_cell = notebook.get_selected_cell();  
        if (last_cell && last_cell.metadata.execution && last_cell.metadata.execution.status === 'ok') {  
            playCompletionSound();  
        }  
    });  
 
    console.log("Sound alert extension loaded!");  
    return {playCompletionSound: playCompletionSound};  
});  

Step 3: Load the Extension in Jupyter Notebook#

To use the extension:

  1. Place the audio file (e.g., alert.wav) in the same directory as sound_alert_extension.js.
  2. Open your notebook and run this code to load the extension:
from IPython.display import Javascript  
Javascript(filename="sound_alert_extension.js")  
  1. Test it! Run any cell (e.g., print("Hello")). You should hear the sound after execution.

Step 4: Persist the Extension (Optional)#

To load the extension automatically every time you start Jupyter:

  1. Install the extension as a notebook extension:
    jupyter nbextension install --user sound_alert_extension.js  
    jupyter nbextension enable sound_alert_extension.js --user  
  2. Restart Jupyter Notebook. The extension will now load automatically.

Method 3: Using Python’s winsound (Windows-Only, No External Dependencies)#

Windows users can use Python’s built-in winsound module to play system sounds or beeps without external libraries. This is a quick, no-frills solution but works only on Windows.

Step 1: Play a Simple Beep#

Use winsound.Beep(frequency, duration) to generate a beep. For example:

import winsound  
import time  
 
# Simulate long-running task  
time.sleep(3)  
 
# Play a beep: 1000 Hz (frequency), 500 ms (duration)  
winsound.Beep(1000, 500)  

Step 2: Play a WAV File (Windows Only)#

To play a custom .wav file (e.g., alert.wav), use winsound.PlaySound:

import winsound  
import time  
 
time.sleep(3)  # Simulate task  
 
# Play a WAV file (replace with your file path)  
winsound.PlaySound("alert.wav", winsound.SND_FILENAME)  

Note: winsound only supports .wav files and is limited to Windows.

Troubleshooting Common Issues#

Sound Not Playing?#

  • File path error: Ensure the audio file (e.g., alert.wav) is in your notebook’s directory, or use an absolute path (e.g., C:/notebooks/alert.wav).
  • Browser permissions: Some browsers block autoplay. Check if your browser allows sound for the Jupyter Notebook tab (look for a speaker icon in the address bar).
  • Jupyter server not local: If your notebook runs on a remote server, sound playback may fail (browsers block autoplay for remote content).
  • Ad blockers: Extensions like AdBlock may block audio playback. Disable them for the Jupyter tab.

Extension Not Loading (Method 2)?#

  • Jupyter version mismatch: Ensure you’re using Jupyter Notebook (not Jupyter Lab, which uses a different extension system). For Jupyter Lab, use JupyterLab Extensions.
  • Incorrect file path: The sound_alert_extension.js and alert.wav must be in the same directory as your notebook.

Conclusion#

Whether you need a quick alert for specific cells or automatic notifications for all tasks, these methods have you covered:

  • Method 1 (IPython Audio + cell magics): Flexible, cross-platform, and ideal for one-off long-running cells.
  • Method 2 (Jupyter extension): Persistent and automatic for all cells, but requires basic JavaScript.
  • Method 3 (winsound): Windows-only, no dependencies, perfect for simple beeps.

With these tools, you’ll never miss a finished cell again—stay productive and let the sound do the talking!

References#