Custom magic commands

Along with the standard magic commands IPython provides, you can create custom magic commands that can be useful. Some good candidates would be to simplify tasks that you normally do but they take significant time to set up, initializing an object or objects for extensive testing, or maintenance routines that you find yourself doing over and over.

Just like we used cell and line magic, these two types exist for creating your own magic commands. For most of my use cases, line magic suffices, because I either don’t need an argument, or I can use a singular one-- I haven’t come across a case where it would benefit me to use the multiple lines available for cell magic, but it is an option if you so choose.

To use custom magic, create a Python file (I name mine but the name can be anything you like) and place it in your profile’s startup directory.

When working on a local machine, it makes things easier if all users have the same password, which may not always be the case, especially right after a database refresh. I typically use something trivial because locally, security is not an issue, so I’d like to get around the sometimes stringent requirements that a user’s password must abide by. We can invoke this password normalizer using a line magic decorator:

# /Users/eric/.ipython/profile_zagnut/startup/
from IPython.core.magic import register_line_magic

def reset_passwords(line):
    new_password = line or 'foobar'
    all_users = User.objects.all()
    first_user = all_users.first()
    hashed_password = first_user.password
    num_users = all_users.update(password=hashed_password)
    print(f'{num_users} passwords were changed to "{new_password}"')

This can be executed in the shell by simply running %reset_passwords. If you want to use something besides the given default of foobar, just pass it in:

In [1]: %reset_passwords apples
15 passwords were changed to "apples"

Another use case that you may find handy is generating UUIDs. I had a task where I needed to be able to generate one or more on the fly, and having a command that can do so is quite useful:

# /Users/eric/.ipython/profile_zagnut/startup/
import uuid

def generate_uuid(line):
    def gen(n=1):
        for _ in range(n):
    if line:
        except ValueError:
            print('You must pass in an integer.')

Again, you can pass %generate_uuid by itself or with an argument:

In [1]: %generate_uuid

In [2]: %generate_uuid 4

In [3]: %generate_uuid abc
You must pass in an integer.