Metadata-Version: 2.4
Name: neverlose
Version: 1.0.4
Summary: 🧙‍♂️ Crash-proof any Python function with one decorator. Resume from where you stopped — automatically.
Author-email: NeverLose IO <hello@neverlose.io>
License-Expression: MIT
Project-URL: Homepage, https://github.com/neverlose-io/neverlose
Project-URL: Repository, https://github.com/neverlose-io/neverlose
Project-URL: Issues, https://github.com/neverlose-io/neverlose/issues
Project-URL: Changelog, https://github.com/neverlose-io/neverlose/blob/main/CHANGELOG.md
Keywords: resume,checkpoint,crash-recovery,fault-tolerance,decorator,pickle,checkpointing,recovery
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Recovery Tools
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# 🧙‍♂️ NeverLose

**Crash-proof any Python function with one decorator.**

Resume from where you stopped — automatically.

- **CI:** https://github.com/neverlose-io/neverlose/actions
- **PyPI:** https://pypi.org/project/neverlose/
- **GitHub:** https://github.com/neverlose-io/neverlose
- **License:** MIT
- **Python:** 3.9 → 3.13
- **Dependencies:** Zero

---

## 😩 The Problem

Every Python developer has felt this:

- 🧠 Train a model for 12 hours → power outage at hour 11 → everything gone.
- 🕷️ Scrape a million pages → accidental Ctrl+C → start from zero.
- 📦 Process 2TB of data → MemoryError at hour 6 → begin again.
- 🔬 Run a 48-hour simulation → cluster kills the job → rerun from scratch.

The usual answer: save checkpoints manually. You write try/except + pickle.dump, manage state files, handle corrupt saves — then forget one edge case, and it all falls apart anyway.

**There has to be a better way.**

---

## ✨ The Solution

```python
from neverlose import resurrect, checkpoint

@resurrect
def train():
    for epoch in range(1000):
        loss = do_epoch(epoch)
        checkpoint({"epoch": epoch, "loss": loss})

train()
```

That's it. Run it. Stop it. Crash it. Re-run the same file — it resumes automatically from the last epoch.

No try/except. No pickle.dump. No dependencies.

---

🚀 Install

```
pip install neverlose
```

Python 3.9 → 3.13. Zero dependencies (standard library only).

---

🎯 Features

· Automatic resume — re-run the same file → picks up where it left off
· Atomic writes — power loss mid-save = no corrupt checkpoints, ever
· Signal handling — catches Ctrl+C and SIGTERM, saves before exiting
· Fingerprinting — detects code changes, avoids stale resumes
· Zero dependencies — only Python stdlib
· Pure Python — no C extensions, no compiled wheels

---

📖 Usage

Machine Learning Training

```python
from neverlose import resurrect, checkpoint

@resurrect(key="gpt-small-v3")
def train_model():
    model = build_model()
    for epoch in range(100):
        for batch in dataloader:
            loss = train_step(model, batch)
        checkpoint({"epoch": epoch, "loss": loss})

train_model()
```

Change key= when hyperparameters change — forces a fresh start.

Web Scraping

```python
from neverlose import resurrect, checkpoint

@resurrect(key="news-2026")
def scrape_all():
    state = scrape_all.resume_state() or {"done": []}
    done = set(state["done"])
    for url in url_list:
        if url in done:
            continue
        save(fetch(url), url)
        done.add(url)
        checkpoint({"done": list(done)})

scrape_all()
```

Ctrl+C mid-scrape — re-run — continues from the last URL.

Data Processing Pipeline

```python
from pathlib import Path
from neverlose import resurrect, checkpoint

@resurrect
def process(path):
    files = list(Path(path).glob("*.parquet"))
    state = process.resume_state() or {"i": 0}
    for i, f in enumerate(files[state["i"] + 1:], start=state["i"] + 1):
        transform(f)
        checkpoint({"i": i, "total": len(files)})

process("/data/raw")
```

---

⚙️ API

```python
@resurrect(key="", keep=True, verbose=True)
def my_function():
    ...
```

Param Type Default Description
key str "" Extra fingerprint ingredient
keep bool True Keep checkpoint file after success
verbose bool True Print resume/save messages

```python
from neverlose import checkpoint, resume_state, reset

checkpoint({"step": 42})       # manual save
resume_state(my_function)      # last saved value, or None
my_function.reset()            # delete checkpoint file
```

Environment variable: NEVERLOSE_DIR (default: ~/.neverlose)

---

❓ FAQ

Why not just use pickle directly?
Pickle alone doesn't handle: (1) atomic writes so a crash mid-save can't corrupt the file, (2) catching SIGINT/SIGTERM to flush before exit, (3) fingerprinting to detect when code changed. NeverLose wraps all three.

Does it work with async def?
Not in v1.0. Async support lands in v1.1.

Is it thread-safe?
Yes — saves are guarded by threading.RLock. Each thread gets its own store via threading.local.

Does it support multiprocessing?
Partially. Writes are atomic, but each process has its own fingerprint. First-class support in v1.2.

How fast is it?
Sub-millisecond for small checkpoints on SSD.

What if the checkpoint file is lost?
The function starts fresh — safely.

Where are checkpoints stored?
Default: ~/.neverlose/. Override with NEVERLOSE_DIR=/path.

---

🗺️ Roadmap

☑ v1.0 — Sync functions, atomic writes, signal handling
☐ v1.1 — async def support
☐ v1.2 — Multiprocessing-safe checkpoints
☐ v1.3 — Cloud backends (S3, GCS, Azure)
☐ v2.0 — Distributed checkpoint registry

---

📜 License

MIT © 2026 NeverLose IO

---

💖 Support

If NeverLose saves you even one hour of lost work — give it a star on GitHub.

Bitcoin: bc1qyw4mj8zjcutzpsd6skq87qv03t52804t6jkwte
Ethereum: 0x009E3Cf6F51141DBF2EfEc33BC07c966651D0Da8

---

Full docs, GIF demo, and code: https://github.com/neverlose-io/neverlose
