How to log IPython history to text file?

2020-05-25 05:58发布

问题:

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.

回答1:

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.



回答2:

You can export all of your history in IPython to a text file 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.



回答3:

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


回答4:

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.



回答5:

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.