Skip to main content

A reversible-operations journal library with session-based history and undo orchestration.

Project description

unmake

unmake is a Python library for recording destructive operations in sessions and orchestrating undos later.

It is intentionally split into:

  • Storage backend (you choose persistence strategy, e.g., SQLite)
  • Operation payload (you define schema and reconstruction)
  • Undo orchestration (library provides session + operation ordering)

Install

uv sync

Quickstart

from pathlib import Path

from unmake import HistoryManager, OperationRegistry, SQLiteStorage

manager = HistoryManager(SQLiteStorage("history.db"))

# Record a run
with manager.start_session(script="dangerous_script.py", args=["--force"]) as session:
    Path("a.txt").rename("b.txt")
    session.record_operation("fs.move", {"src": "a.txt", "dst": "b.txt"})

# Register reconstruction logic for undo
class MoveUndo:
    def __init__(self, payload: dict):
        self.src = payload["src"]
        self.dst = payload["dst"]

    def undo(self) -> None:
        Path(self.dst).rename(self.src)

registry = OperationRegistry()
registry.register("fs.move", MoveUndo)

# Undo all operations in reverse order
session_id = manager.list_sessions(limit=1)[0].session_id
manager.undo_session(session_id, registry)

Development workflow

This project is configured for uv, make, and PEP 621 metadata.

make install
make test
make lint
make build

Publish

# Configure token in env first
# export UV_PUBLISH_TOKEN=...
make publish

Bump version

make bump-patch
make bump-minor
make bump-major

Thread Safety

InMemoryStorage

  • Not thread-safe by default
  • Use external locking for concurrent access:
import threading

from unmake import HistoryManager, InMemoryStorage

storage = InMemoryStorage()
manager = HistoryManager(storage)
lock = threading.Lock()

with lock:
    with manager.start_session(script="safe.py") as session:
        session.record_operation("demo.noop", {"value": 1})

SQLiteStorage

  • Thread-safe for standard usage with one connection per method call
  • SQLite handles concurrent access with internal locking
  • Performance may degrade under very high contention
  • Prefer one HistoryManager per thread

Best Practices

  • Use SQLiteStorage for multi-threaded applications
  • Use InMemoryStorage only with external locking when shared across threads
  • Avoid sharing a mutable HistoryManager + InMemoryStorage pair across threads

CLI

Install project dependencies and run:

unmake --db history.db list-sessions
unmake --db history.db show-session <session-id>
unmake --db history.db undo <session-id>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

unmake-0.1.3.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

unmake-0.1.3-py3-none-any.whl (16.8 kB view details)

Uploaded Python 3

File details

Details for the file unmake-0.1.3.tar.gz.

File metadata

  • Download URL: unmake-0.1.3.tar.gz
  • Upload date:
  • Size: 14.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for unmake-0.1.3.tar.gz
Algorithm Hash digest
SHA256 63f69e01d084f2068a7903b551f302a2ef05324537d614e26ccfccc17aaf85f1
MD5 9bddf6a8aeb8351f88994f94024c6904
BLAKE2b-256 57c4ea1fb401d6c79842c01a1da9bb4c631da8e44bb0bf045cf41c521a78cb28

See more details on using hashes here.

File details

Details for the file unmake-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: unmake-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 16.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.26 {"installer":{"name":"uv","version":"0.9.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for unmake-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 bf878fa1b9ccefedd6fcc2cb91760c3c598ddd0a2f48f6c14244e59652df326f
MD5 a6e35831dded9bd1d6f5a2db17283be7
BLAKE2b-256 c6f2a078343c5ed89bd1fb4cff3ec7c1d87cdbc45b0e91b8e53808b09aa2dbdb

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page