mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-11-13 12:13:46 +01:00
feat(ipython): add data helpers without persisted history (#510)
Add a dedicated IPython module with startup helpers for JSON, YAML, TOML, and CSV plus a small set of common standard-library imports for interactive use. Disable SQLite history and stop preserving ~/.ipython: interactive sessions can contain credentials and other sensitive data, so that profile state must not survive reboots implicitly. Assisted-by: DeepSeek Harness 0.2.2-alpha.2 (deepseek-flash)
This commit is contained in:
1 parent
179b20a42c
commit
7ea9fd3197
7 files changed
+140
-4
No files matched your search
@@ -7,5 +7,5 @@ closure.
|
||||
Editor programs, keymaps, `$EDITOR` defaults, and usage docs live under
|
||||
[`../../core/editors/`](../../core/editors/README.md) (Helix, Neovim backup, glossary, cheatsheets).
|
||||
|
||||
[`default.nix`](./default.nix) imports `./packages.nix` so `home/base/tui` can keep pulling in
|
||||
tooling without mixing it into `core/editors`.
|
||||
[`default.nix`](./default.nix) imports [`ipython/`](./ipython/) and `./packages.nix` so
|
||||
`home/base/tui` can keep pulling in tooling without mixing it into `core/editors`.
|
||||
@@ -1,4 +1,7 @@
|
||||
# Editor-related language servers and heavy tooling — kept out of `core/editors`.
|
||||
{
|
||||
imports = [ ./packages.nix ];
|
||||
imports = [
|
||||
./ipython
|
||||
./packages.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# IPython
|
||||
|
||||
[`default.nix`](./default.nix) manages `~/.ipython/profile_default` with two pieces:
|
||||
|
||||
- `ipython_config.py` disables SQLite history because interactive sessions may contain secrets.
|
||||
- `startup/10-data-helpers.py` loads JSON, YAML, TOML, and CSV helpers at every IPython start. It
|
||||
also pre-imports a small set of common standard-library names such as `Path`, `Counter`, and
|
||||
`datetime`.
|
||||
|
||||
[`data-helpers.py`](./data-helpers.py) deliberately keeps heavier libraries such as NumPy and pandas
|
||||
out of startup; import them explicitly when needed. The `~/.ipython` profile is not persisted by
|
||||
`hosts/idols-ai/preservation.nix`, so Home Manager recreates the config and helpers from the Nix
|
||||
store on every activation.
|
||||
@@ -0,0 +1,102 @@
|
||||
# ruff: noqa: F401
|
||||
"""IPython startup helpers for inspecting structured data.
|
||||
|
||||
IPython executes files in this profile's startup directory before the first
|
||||
prompt, so these helpers are available in every interactive session.
|
||||
"""
|
||||
|
||||
# A small set of common names preloaded for interactive use. The unused-import
|
||||
# exception is intentional: IPython exposes these names directly in the prompt.
|
||||
import csv
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tomllib
|
||||
from collections import Counter, defaultdict
|
||||
from datetime import date, datetime, timedelta, timezone
|
||||
from pathlib import Path
|
||||
from pprint import pprint
|
||||
|
||||
import toml
|
||||
import yaml
|
||||
|
||||
|
||||
def loads_json(text: str):
|
||||
return json.loads(text)
|
||||
|
||||
|
||||
def dumps_json(value, indent: int = 2) -> str:
|
||||
return json.dumps(value, ensure_ascii=False, indent=indent)
|
||||
|
||||
|
||||
def loads_yaml(text: str):
|
||||
return yaml.safe_load(text)
|
||||
|
||||
|
||||
def dumps_yaml(value) -> str:
|
||||
return yaml.safe_dump(value, allow_unicode=True, sort_keys=False)
|
||||
|
||||
|
||||
def loads_toml(text: str):
|
||||
return tomllib.loads(text)
|
||||
|
||||
|
||||
def dumps_toml(value) -> str:
|
||||
return toml.dumps(value)
|
||||
|
||||
|
||||
def loads_csv(text: str) -> list[dict[str, str]]:
|
||||
return list(csv.DictReader(io.StringIO(text)))
|
||||
|
||||
|
||||
def dumps_csv(rows, fieldnames=None) -> str:
|
||||
rows = list(rows)
|
||||
if not rows:
|
||||
return ""
|
||||
|
||||
fieldnames = fieldnames or list(rows[0])
|
||||
buffer = io.StringIO(newline="")
|
||||
writer = csv.DictWriter(buffer, fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
writer.writerows(rows)
|
||||
return buffer.getvalue()
|
||||
|
||||
|
||||
def show(value):
|
||||
"""Pretty-print a value and return it for further use."""
|
||||
pprint(value, width=120, sort_dicts=False)
|
||||
return value
|
||||
|
||||
|
||||
def show_json(text: str):
|
||||
return show(loads_json(text))
|
||||
|
||||
|
||||
def show_yaml(text: str):
|
||||
return show(loads_yaml(text))
|
||||
|
||||
|
||||
def show_toml(text: str):
|
||||
return show(loads_toml(text))
|
||||
|
||||
|
||||
def show_csv(text: str):
|
||||
return show(loads_csv(text))
|
||||
|
||||
|
||||
def copy_to_clipboard(text: str) -> str:
|
||||
"""Copy text to the system clipboard and return it."""
|
||||
commands = (
|
||||
[["pbcopy"]]
|
||||
if sys.platform == "darwin"
|
||||
else [["wl-copy"], ["xclip", "-selection", "clipboard"]]
|
||||
)
|
||||
for command in commands:
|
||||
if shutil.which(command[0]):
|
||||
subprocess.run(command, input=text, text=True, check=True)
|
||||
return text
|
||||
raise RuntimeError("No clipboard command found (need wl-copy, xclip, or pbcopy)")
|
||||
@@ -0,0 +1,14 @@
|
||||
{ ... }:
|
||||
{
|
||||
# Interactive IPython sessions routinely handle credentials and other
|
||||
# sensitive values, so keep the SQLite history disabled rather than relying
|
||||
# on the profile directory's lifetime. Home Manager recreates these files
|
||||
# from the Nix store on every activation.
|
||||
home.file = {
|
||||
".ipython/profile_default/ipython_config.py".text = ''
|
||||
c = get_config()
|
||||
c.HistoryManager.enabled = False
|
||||
'';
|
||||
".ipython/profile_default/startup/10-data-helpers.py".source = ./data-helpers.py;
|
||||
};
|
||||
}
|
||||
@@ -71,6 +71,7 @@
|
||||
requests
|
||||
pyquery
|
||||
pyyaml
|
||||
toml # TOML writing; reading uses stdlib tomllib
|
||||
protobuf # protocol buffer compiler
|
||||
]
|
||||
))
|
||||
|
||||
@@ -216,7 +216,10 @@ in
|
||||
".config/Joplin" # joplin-desktop
|
||||
|
||||
".local/share/jupyter"
|
||||
".ipython"
|
||||
# Deliberately not persisted: ~/.ipython contains history.sqlite, and
|
||||
# interactive sessions may contain credentials or other sensitive
|
||||
# values. Home Manager recreates the profile config and startup helpers
|
||||
# from the Nix store on every activation.
|
||||
|
||||
# ======================================
|
||||
# Cloud Native
|
||||
|
||||
Reference in new issue
Block a user