phistory
You know a script worked yesterday—but not how you ran it. The useful command is buried in one terminal's scrollback, missing from another terminal's shell history, or mixed in with hundreds of unrelated commands.
phistory fixes that at the script level: each argparse script keeps its own
copy/paste-ready run history. It also includes a tiny YAML parameter loader for
the long, experiment-style commands that are easier to review and version
control as configuration files.
It supports Python 3.10+.
Source and issue tracker: https://github.com/amorriso/phistory.
Never reconstruct a command again
# myscript.py
import phistory # must be first
import argparse
p = argparse.ArgumentParser()
p.add_argument("--foo")
p.add_argument("bar")
args = p.parse_args()
print(args)
Run
python myscript.py --foo 123 hello
python myscript.py --foo 999 world
python myscript.py --history
# outputs:
# myscript.py --foo 123 hello
# myscript.py --foo 999 world
That history belongs to myscript.py, not to whichever shell or terminal
happened to run it. Open a new terminal, come back next week, or switch between
projects: python myscript.py --history shows the commands that ran that
script.
What it does
- Saves each execution’s CLI (
script name + args) to~/.python-history/<script>.history. - When run with
--history, prints previous runs (copy/paste friendly) and exits. - Only writes history when your script calls
argparse.parse_argsorparse_known_args. - The
--historyflag itself is never recorded.
History directory: ~/.python-history/
Use --history date to include timestamps, --history unique to show only
the first occurrence of each command, or both options together.
phistoryintentionally monkey-patchesargparse.ArgumentParserwhen it is imported. Import it before importing or configuringargparsein a script that should record history.
When the command has too many arguments
For a script with a handful of flags, a command line is great. For a training, reporting, or batch job with a dozen settings, it is often easier to keep the run configuration in a YAML file. The configuration is readable and reviewable. One useful idea: a params file can also be version-controlled with your script when you want to keep a reproducible record of a run.
For example, instead of remembering this:
python train_model.py --dataset data/races-2025.parquet --output-dir artifacts/v3 \
--learning-rate 0.0003 --batch-size 128 --epochs 80 --seed 42 \
--validation-days 28 --feature-set market-v4 --early-stopping-patience 10 \
--notes "baseline before feature experiment"
write configs/baseline.params.yaml:
dataset: data/races-2025.parquet
output_dir: artifacts/v3
learning_rate: 0.0003
batch_size: 128
epochs: 80
seed: 42
validation_days: 28
feature_set: market-v4
early_stopping_patience: 10
notes: baseline before feature experiment
Then make the script self-documenting:
# train_model.py
from phistory import yaml_args
args = yaml_args.load(required=["dataset", "output_dir", "learning_rate"])
print(args.output_dir) # YAML keys are available as attributes
Run it with:
python train_model.py configs/baseline.params.yaml
You might version-control configs/baseline.params.yaml when it represents a
run worth preserving. Keep credentials, API keys, and machine-specific paths
in an ignored local YAML file instead.
Behavior
- Default file:
<script_stem>.params.yamlin the current directory (e.g.runner.params.yaml) - You can also provide the path explicitly or as a single argument:
python runner.py configs/myexp.yaml
- Validate required keys:
args = yaml_args.load(required=["experiment-name", "outpath", "description"])
Helper functions
from phistory import derive_params_filename, load_yaml_params
Installation
pip install phistory
License
MIT. See LICENSE.
Metadata
Release files for phistory 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| phistory-0.2.1.tar.gz | 11.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| phistory-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.2 kB
Release files / phistory-0.2.1.tar.gz
| Download URL | phistory-0.2.1.tar.gz |
|---|---|
| Size | 11.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
14c393c2809687cecf9a6d2bb8653a979f0ba258005b5b189f2ffa81c878bbdf
|
|
BLAKE2b-256 checksum How to use checksums |
40287a86d334ef69c8d2036c577d850ab82694e29e065bddd59dd5f263ec8d3d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / phistory-0.2.1-py3-none-any.whl
| Download URL | phistory-0.2.1-py3-none-any.whl |
|---|---|
| Size | 9.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
81b19a3ddb08a70ecc49cffa6c3a508df411e127fcca7cfcfdcc65d4f3a1d2ac
|
|
BLAKE2b-256 checksum How to use checksums |
3ef629d06e51105002a17eae1ab9ece4a7778dabdbf094dbade770d976ef341e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log