How to log IPython history to text file?

Question:

After some searching and trawling through the IPython documentation and some code, I can’t seem to figure out whether it’s possible to store the command history (not the output log) to a text file rather than an SQLite database. ipython --help-all seems to indicate that this option doesn’t exist.

This would be very nice for version controlling frequently used commands like in .bash_history.

Edit: Working solution based on @minrk’s answer.

Asked By: l0b0

||

Answers:

Using a pure text file to store history would result in commands from different sessions to be interleaved, as well as make overly complicated and slow to add features like ‘run third command from session-x’ or search back in history. Hence the sqlite database,

Still, it should be pretty easy to write a script dumping history to a file and do stat at the same time. Everything you do with a text file should be doable with sqlite.

Answered By: Matt

You can emulate bash’s behavior by adding this in one of your startup scripts (e.g. $(ipython locate profile)/startup/log_history.py:

import atexit
import os

ip = get_ipython()
LIMIT = 1000 # limit the size of the history

def save_history():
    """save the IPython history to a plaintext file"""
    histfile = os.path.join(ip.profile_dir.location, "history.txt")
    print("Saving plaintext history to %s" % histfile)
    lines = []
    # get previous lines
    # this is only necessary because we truncate the history,
    # otherwise we chould just open with mode='a'
    if os.path.exists(histfile):
        with open(histfile, 'r') as f:
            lines = f.readlines()

    # add any new lines from this session
    lines.extend(record[2] + 'n' for record in ip.history_manager.get_range())

    with open(histfile, 'w') as f:
        # limit to LIMIT entries
        f.writelines(lines[-LIMIT:])

# do the save at exit
atexit.register(save_history)

Note that this emulates the bash/readline history behavior in that it will fail on an interpreter crash, etc.

in a gist

update: alternative

If what you actually want is to just have a few manual favorite commands available to readline (completion, ^R search, etc.) that you can version control, this startup file will allow you to maintain that file yourself, which will be purely in addition to the actual command history of IPython:

import os

ip = get_ipython()

favfile = "readline_favorites"

def load_readline_favorites():
    """load profile_dir/readline_favorites into the readline history"""
    path = os.path.join(ip.profile_dir.location, favfile)
    if not os.path.exists(path):
        return

    with open(path) as f:
        for line in f:
            ip.readline.add_history(line.rstrip('n'))

if ip.has_readline:
    load_readline_favorites()

Drop this in your profile_default/startup/ dir, and edit profile_default/readline_favorites, or anywhere you prefer to keep that file, and it will show up in readline completions, etc. on every IPython session.

Answered By: minrk

You can export all of your history in IPython to a text file with the %history magic like this:

%history -g -f filename

One way of getting what you want might be to do that export in a git hook. I usually put these "sync an external resource" actions in the post-checkout git hook.

Answered By: Christian Long

You can also choose which lines you would like to save. E.g.

%history 1 7-8 10 -f /tmp/bar.py

This will save line 1, 7 to 8 and 10 to a temp file bar.py. If you need the whole just skip the part of the line.

%history -f /tmp/foo.py
Answered By: Prayson W. Daniel

To save a Ipython session history:

%save [filename] [line start - line end] 

For example:

%save ~/Desktop/Ipython_session.txt 1-31

This will only save that particular session of ipython history but will not save the entire history of ipython commands.

Answered By: Q2Learn
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.