ADVfile-manager


NameADVfile-manager JSON
Version 1.0.3 PyPI version JSON
download
home_pageNone
SummaryUnified file abstractions with backups, context manager, and exit cleanup.
upload_time2025-09-03 19:48:27
maintainerNone
docs_urlNone
authorAvi Twil
requires_python>=3.8
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
# ADVfile\_manager

[![PyPI version](https://badge.fury.io/py/ADVfile_manager.svg)](https://pypi.org/project/ADVfile_manager/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)

**Author:** Avi Twil
**Repo:** [https://github.com/avitwil/ADVfile\_manager](https://github.com/avitwil/ADVfile_manager)

Unified file abstractions for Python with **safe writes, caching, backups, context managers, and exit-time cleanup** — all under a consistent API for **Text**, **JSON**, **CSV**, and **YAML** files.

* `TextFile` – read/write/append lines with `lines()` and `read_line()`.
* `JsonFile` – works with dict or list roots, `append()`, `get_item()`, `items()`.
* `CsvFile` – `DictReader`/`DictWriter` based, `read_row()`, `rows()`, column-order control.
* `YamlFile` – like `JsonFile`, requires `PyYAML`.

The base class `File` adds **backups**, **restore**, **retention**, **human-readable sizes**, **cache control**, and a **context manager** that automatically backs up and can restore on error. “Ephemeral” backups are cleaned up via a **silent atexit hook**.

---

## Table of Contents

* [Why ADVfile\_manager?](#why-advfile_manager)
* [Installation](#installation)
* [Quick Start](#quick-start)
* [Detailed Usage](#detailed-usage)

  * [Common Base: `File`](#common-base-file)
  * [`TextFile`](#textfile)
  * [`JsonFile`](#jsonfile)
  * [`CsvFile`](#csvfile)
  * [`YamlFile`](#yamlfile)
* [Backups, Retention & Exit Cleanup](#backups-retention--exit-cleanup)
* [Context Manager Safety](#context-manager-safety)
* [Advanced Notes](#advanced-notes)
* [Full Examples](#full-examples)
* [Feature-by-Feature Guide (Usage & Examples)](#feature-by-feature-guide-usage--examples)
* [License](#license)

---

## Why ADVfile\_manager?

Typical file code ends up as a mix of ad-hoc helpers and repeated patterns.
ADVfile\_manager provides one consistent interface across common formats:

* **Safer writes**: atomic replace to avoid corrupted files.
* **Backups**: create timestamped `.bak` files, list, restore, retain N most recent.
* **Context safety**: `with` block makes a backup on enter (optional) and restores on exceptions.
* **Exit cleanup**: ephemeral backups (for temp edits) are auto-removed via atexit.
* **Streaming helpers**: iterate lines/rows/items without loading everything.
* **Cache control**: in-memory cache when convenient, `clear_cache()` when not.

---

## Installation

### From PyPI (recommended)

```bash
pip install ADVfile_manager
```

> `YamlFile` requires [PyYAML](https://pypi.org/project/PyYAML/). If your environment doesn’t bring it automatically:

```bash
pip install pyyaml
```

### From source

```bash
git clone https://github.com/avitwil/ADVfile_manager
cd ADVfile_manager
pip install -e .
```

---

# 🔎 Comparison: ADVfile\_manager vs Similar Tools

| Feature / Tool             | **ADVfile\_manager**                                           | [pathlib (stdlib)](https://docs.python.org/3/library/pathlib.html) | [os / shutil (stdlib)](https://docs.python.org/3/library/shutil.html) | [pandas](https://pandas.pydata.org/) | [ruamel.yaml](https://pypi.org/project/ruamel.yaml/) / [PyYAML](https://pyyaml.org/) |
| -------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------ |
| **Supported formats**      | TXT, JSON, CSV, YAML                                           | Works with paths only                                              | Copy/move/delete files                                                | CSV, Excel, JSON, parquet, etc.      | YAML only                                                                            |
| **Unified API**            | ✅ One interface across all formats                             | ❌                                                                  | ❌                                                                     | ❌                                    | ❌                                                                                    |
| **Read/Write/Append**      | ✅ Consistent methods (`read`, `write`, `append`)               | Manual file ops                                                    | Manual file ops                                                       | ✅ (DataFrames)                       | ✅ (YAML load/dump)                                                                   |
| **Cache system**           | ✅ In-memory cache + `clear_cache`                              | ❌                                                                  | ❌                                                                     | Internal DF cache                    | ❌                                                                                    |
| **Line/Row helpers**       | ✅ `lines()`, `read_line()`, `read_row()`, `rows()`             | ❌                                                                  | ❌                                                                     | ✅ but via DataFrame ops              | ❌                                                                                    |
| **Backup & restore**       | ✅ `backup()`, `restore()`, `list_backups()`, `clear_backups()` | ❌                                                                  | ❌                                                                     | ❌                                    | ❌                                                                                    |
| **Backup retention**       | ✅ `max_backups`                                                | ❌                                                                  | ❌                                                                     | ❌                                    | ❌                                                                                    |
| **Atomic writes**          | ✅ via `.tmp` + `os.replace()`                                  | ❌                                                                  | ❌                                                                     | ❌ (relies on storage FS)             | ❌                                                                                    |
| **Human-readable size**    | ✅ `get_size_human()`                                           | ❌                                                                  | ❌                                                                     | ❌                                    | ❌                                                                                    |
| **Context manager safety** | ✅ auto-backup + auto-restore on exception                      | ❌                                                                  | ❌                                                                     | ❌                                    | ❌                                                                                    |
| **Ephemeral backups**      | ✅ Auto-cleaned with `atexit` (if `keep_backup=False`)          | ❌                                                                  | ❌                                                                     | ❌                                    | ❌                                                                                    |
| **Exit cleanup controls**  | ✅ `set_exit_cleanup`, `cleanup_backups_for_all`                | ❌                                                                  | ❌                                                                     | ❌                                    | ❌                                                                                    |
| **Dependencies**           | Optional: `pyyaml`                                             | None                                                               | None                                                                  | Heavy (numpy, etc.)                  | Yes                                                                                  |
| **Target use case**        | General-purpose file management with safety                    | File system path manipulation                                      | File system operations                                                | Data analysis                        | YAML-specific parsing                                                                |

---

## 📌 Key Takeaways

### What ADVfile\_manager does *better*:

* 🔒 **Safety-first**: atomic writes, automatic backups, and restore-on-error context manager.
* 🧩 **Unified API**: instead of juggling `open()`, `json`, `csv`, and `yaml`, you get one interface.
* 🗂 **Backups with retention**: none of the compared tools provide this out-of-the-box.
* 🧹 **Exit cleanup**: ephemeral backups auto-clean themselves.
* ⚡ **Lightweight**: works without pandas overhead (which is overkill if you only want CSV/JSON/YAML).

### When to prefer others:

* **pathlib / shutil** → if you only need filesystem manipulation, not file contents.
* **pandas** → if you need heavy data analysis, joins, filtering, and numeric operations on tabular data.
* **ruamel.yaml / PyYAML** → if you need advanced YAML features (comments preservation, round-trip editing).

---

## 🎯 Example Use Cases for ADVfile\_manager

* **Config management**: load/modify JSON or YAML configs safely, with rollback if something breaks.
* **Logs & reports**: append text or CSV logs with automatic backup retention.
* **Transactional edits**: use `with File(...) as f:` to ensure no data corruption even on crash.
* **Cross-format tools**: build utilities that handle multiple formats with the same code patterns.

---

## Quick Start

```python
from ADVfile_manager import TextFile, JsonFile, CsvFile, YamlFile

# Text
txt = TextFile("notes.txt", "data")
txt.write("first line")
txt.append("second line")
print(txt.read_line(2))     # "second line"
for i, line in txt.lines():
    print(i, line)

# JSON (dict root)
j = JsonFile("config.json", "data")
j.write({"users": [{"id": 1}]})
j.append({"active": True})  # shallow dict update
print(j.get_item("active")) # True

# CSV
c = CsvFile("table.csv", "data")
c.write([{"name":"Avi","age":30},{"name":"Dana","age":25}], fieldnames=["name","age"])
c.append({"name":"Noa","age":21})
print(c.read_row(2))        # {"name":"Dana","age":"25"}
for idx, row in c.rows():
    print(idx, row)

# YAML
y = YamlFile("config.yaml", "data")
y.write({"app":{"name":"demo"}, "features":["a"]})
y.append({"features":["b"]})  # shallow dict update
print(y.get_item("app"))
```

---

## Detailed Usage

### Common Base: `File`

All file types inherit from `File` and share:

* `read()`, `write(data)`, `append(data)`
* `clear_cache()` — clear in-memory cache so next `read()` hits disk
* `get_size()` / `get_size_human()`
* Backups: `backup()`, `list_backups()`, `restore(backup_path=None)`, `clear_backups()`
* Context manager: `with File(...)(keep_backup=True) as f: ...`
* Exit cleanup controls (module-level):
  `set_exit_cleanup(enabled: bool)` and `cleanup_backups_for_all()`

#### Constructor

```python
File(
  file_name: str,
  file_path: str | pathlib.Path | None = None,  # defaults to CWD if None
  keep_backup: bool = True,                     # default keep backups
  max_backups: int | None = None                # retain only N latest backups
)
```

* `keep_backup=False` marks the instance as **ephemeral**: its backups are registered to be removed automatically at interpreter exit (and you can also call `cleanup_backups_for_all()` manually).
* `max_backups` enforces retention whenever `backup()` runs.

#### Backups

* `backup()` creates `backups/<file>.<YYYYMMDD_HHMMSS_micro>.bak`
* `list_backups()` returns sorted list (oldest → newest)
* `restore(path=None)` restores a specific backup, or the latest if `None`
* `clear_backups()` deletes all backups for that file and returns the deleted count

#### Human size

* `get_size_human()` returns `"12.3 KB"` style strings.

---

### `TextFile`

**Extras**:

* `lines()` → generator of `(line_no, text)`
* `read_line(n)` → 1-based line access

```python
txt = TextFile("example.txt", "data")
txt.write("Hello")
txt.append("World")
print(txt.read())           # "Hello\nWorld"
print(txt.read_line(2))     # "World"
for i, line in txt.lines(): # (1, "Hello"), (2, "World")
    print(i, line)
```

---

### `JsonFile`

Works with dict **or** list roots.

**Extras**:

* `get_item(index_or_key)`

  * list-backed: 1-based index (`int`)
  * dict-backed: key (`str`)
* `items()`

  * list-backed: yields `(index, value)` (1-based)
  * dict-backed: yields `(key, value)`
* `append(data)`

  * list-backed: append/extend
  * dict-backed: shallow `dict.update()`

```python
# dict root
j = JsonFile("conf.json", "data")
j.write({"users":[{"id":1}]})
j.append({"active": True})     # shallow merge
print(j.get_item("active"))    # True
for k, v in j.items():
    print(k, v)

# list root
jl = JsonFile("list.json", "data")
jl.write([{"id":1}])
jl.append({"id":2})
jl.append([{"id":3},{"id":4}])
print(jl.get_item(2))          # {"id":2}
for i, item in jl.items():
    print(i, item)
```

---

### `CsvFile`

**Design**: uses `csv.DictReader/DictWriter` (rows are dicts).

**Extras**:

* `write(data, fieldnames=None)` — define columns order; else inferred from data
* `read_row(n)` — 1-based row access
* `rows()` — generator of `(row_no, row_dict)`
* `append(dict | iterable[dict])`

```python
c = CsvFile("table.csv", "data")
c.write(
    [{"name":"Avi","age":30},{"name":"Dana","age":25}],
    fieldnames=["name","age"]           # control column order
)
c.append({"name":"Noa","age":21})
print(c.read_row(2))                    # {"name":"Dana","age":"25"}
for i, row in c.rows():
    print(i, row)
```

---

### `YamlFile`

Like `JsonFile`, but using YAML.
**Requires**: `pip install pyyaml`.

**Extras**:

* `get_item(index_or_key)` — 1-based indexes for lists, keys for dicts
* `items()` — same iteration semantics as `JsonFile`
* `append()` — list append/extend, dict shallow update

```python
from ADVfile_manager import YamlFile

y = YamlFile("config.yaml", "data")
y.write({"app":{"name":"demo"}, "features":["a"]})
y.append({"features":["b"]})            # shallow dict update
print(y.get_item("app"))
for k, v in y.items():
    print(k, v)
```

---

## Backups, Retention & Exit Cleanup

* **Create**: `path = f.backup()`
  Backups are timestamped down to microseconds to avoid collisions.
* **Retention**: set `max_backups=N` on the instance; when `backup()` runs, old backups beyond N are deleted.
* **List**: `f.list_backups()` → sorted list (oldest → newest)
* **Restore**:

  * latest: `f.restore()`
  * specific: `f.restore(path)`
* **Clear**: `f.clear_backups()` returns the deleted count

**Ephemeral backups** (`keep_backup=False`):

* Mark the instance transient with `File(..., keep_backup=False)` or via `obj(keep_backup=False)`.
* These are **registered** for deletion at **interpreter exit** by a silent atexit hook.
* You can control this globally:

```python
from ADVfile_manager import set_exit_cleanup, cleanup_backups_for_all

set_exit_cleanup(True)          # enable (default)
set_exit_cleanup(False)         # disable

removed = cleanup_backups_for_all()  # manual cleanup (returns deleted count)
```

---

## Context Manager Safety

* `with` creates a **backup on enter** (unless you set `keep_backup=False`).
* If an **exception** is raised inside the block and `keep_backup=True`, the file is **restored** from the latest backup.
* **Cache is always cleared** on exit to ensure the next `read()` hits disk.

```python
# default: keep_backup=True
with TextFile("draft.txt", "data") as f:
    f.write("safe transactional edit")
    # if an exception occurs here, latest backup will be restored

# ephemeral: backups are registered for exit cleanup
with TextFile("temp.txt", "data")(keep_backup=False) as f:
    f.write("temporary content")
```

---

## Advanced Notes

* **Atomic writes**: `write()` methods use a `*.tmp` + `os.replace()` strategy so files aren’t left half-written.
* **Pathlib**: all classes accept `str` or `pathlib.Path` for `file_path`.
* **Caching**: `read()` caches content. Use `clear_cache()` if the file was modified externally or you want a fresh read.
* **Append semantics**:

  * Text: appends `"\n"+data"` when file is non-empty.
  * JSON/YAML:

    * list root → append/extend
    * dict root → **shallow** `dict.update()`
* **CSV types**: values read by `DictReader` are `str`. After `append()`, cached rows keep stringified values for consistency.
* **Python**: 3.8+ recommended.

---

## Full Examples

### 1) Text + Backups + Restore Specific

```python
from ADVfile_manager import TextFile

txt = TextFile("example.txt", "example_data")
txt.write("v1"); b1 = txt.backup()
txt.write("v2"); b2 = txt.backup()
txt.write("v3"); b3 = txt.backup()

print("Backups:", txt.list_backups())
txt.restore(b2)
print("Restored content:", txt.read())  # "v2"
```

### 2) Retention (keep only last 2)

```python
txt.max_backups = 2
txt.write("v4"); txt.backup()
txt.write("v5"); txt.backup()
print("After retention:", txt.list_backups())  # only 2 latest remain
```

### 3) Ephemeral Backups + Exit Cleanup

```python
from ADVfile_manager import TextFile, cleanup_backups_for_all, set_exit_cleanup

with TextFile("temp.txt", "example_data")(keep_backup=False) as f:
    f.write("temporary content")

# You can manually clean now (or rely on atexit):
deleted = cleanup_backups_for_all()
print("Deleted backup files:", deleted)

# Disable/Enable the global atexit cleanup:
set_exit_cleanup(False)   # no automatic cleanup on interpreter exit
set_exit_cleanup(True)    # re-enable
```

### 4) CSV with Column Order Control

```python
from ADVfile_manager import CsvFile

rows = [{"name":"Avi","age":30},{"name":"Dana","age":25}]
c = CsvFile("table.csv", "example_data")
c.write(rows, fieldnames=["name","age"])  # explicit order
c.append({"name":"Noa","age":21})

print(c.read_row(2))      # {"name":"Dana","age":"25"}
for i, row in c.rows():
    print(i, row)
```

### 5) JSON/YAML Dict & List Behaviors

```python
from ADVfile_manager import JsonFile, YamlFile

# JSON dict
j = JsonFile("data.json", "example_data")
j.write({"users":[{"id":1}]})
j.append({"active": True})
print(j.get_item("active"))  # True

# JSON list
jl = JsonFile("list.json", "example_data")
jl.write([{"id":1}])
jl.append([{"id":2},{"id":3}])
print(jl.get_item(2))        # {"id":2}

# YAML dict
y = YamlFile("config.yaml", "example_data")
y.write({"app":{"name":"demo"},"features":["a"]})
y.append({"features":["b"]})
print(y.get_item("app"))
```

---

## Feature-by-Feature Guide (Usage & Examples)

Below you’ll find **every feature** with a **Usage explanation** (what & why) and **Examples** (how).

---

### ✔️ Safe Writes (Atomic)

**Usage explanation:**
Avoids partially-written files if your program crashes mid-write. Data is written to a temp file and then **atomically** replaces the target with `os.replace()`. This pattern is ideal for configs and logs where consistency matters.

**Examples:**

```python
from ADVfile_manager import TextFile

cfg = TextFile("settings.txt", "data")
cfg.write("mode=prod")     # safe atomic write
cfg.write("mode=debug")    # previous state remains intact until replace
```

---

### 🧠 In-Memory Cache & `clear_cache()`

**Usage explanation:**
`read()` caches content to save disk I/O on repeated calls. If the file might have been changed by another process or manually edited, call `clear_cache()` before next `read()`.

**Examples:**

```python
log = TextFile("app.log", "data")
print(log.read())     # loads + caches
# ... external edit happens ...
log.clear_cache()
print(log.read())     # reloads from disk
```

---

### 📏 File Size & `get_size_human()`

**Usage explanation:**
Display storage size in UI/CLI or for sanity checks. `get_size()` returns bytes; `get_size_human()` returns “12.3 KB” style strings.

**Examples:**

```python
f = TextFile("notes.txt", "data")
f.write("Hello world")
print(f.get_size())         # e.g. 11
print(f.get_size_human())   # e.g. "11.0 B"
```

---

### 🛟 Backups: `backup`, `list_backups`, `restore`, `clear_backups`

**Usage explanation:**
Before risky edits, create a backup. If something breaks, restore it. Use `list_backups()` to inspect available snapshots; `clear_backups()` to purge when done.

**Examples:**

```python
txt = TextFile("daily.txt", "data")
txt.write("v1"); b1 = txt.backup()
txt.write("v2"); b2 = txt.backup()

print(txt.list_backups())   # [b1, b2]
txt.restore(b1)             # restore specific
print(txt.read())           # "v1"

txt.restore()               # restore latest
print(txt.read())           # "v2"

print("Removed:", txt.clear_backups())
```

---

### ♻️ Backup Retention (`max_backups`)

**Usage explanation:**
Keep only the **last N** backups to control disk usage. Retention is enforced when `backup()` runs.

**Examples:**

```python
rpt = TextFile("report.txt", "data", max_backups=2)
for i in range(5):
    rpt.write(f"v{i}")
    rpt.backup()
print(rpt.list_backups())   # only 2 latest
```

---

### 🧰 Context Manager (Transactional Safety)

**Usage explanation:**
`with` creates a backup on enter (if `keep_backup=True`). If an exception occurs inside the block, it auto-restores on exit. Cache is always cleared when leaving the context.

**Examples:**

```python
# Normal usage
with TextFile("draft.txt", "data") as f:
    f.write("transactional content")

# Auto-restore on error
try:
    with TextFile("draft.txt", "data") as f:
        f.write("new content")
        raise RuntimeError("Simulated crash")
except:
    pass

print("Restored:", TextFile("draft.txt", "data").read())
```

---

### 🧹 Ephemeral Backups & Exit Cleanup

**Usage explanation:**
Temporary operations can request `keep_backup=False`. Such backups are automatically cleaned up at interpreter exit (or manually via `cleanup_backups_for_all`). Control the global behavior with `set_exit_cleanup`.

**Examples:**

```python
from ADVfile_manager import set_exit_cleanup, cleanup_backups_for_all

with TextFile("tmp.txt", "data")(keep_backup=False) as f:
    f.write("temp content")

# switch global behavior
set_exit_cleanup(False)
set_exit_cleanup(True)

# manual immediate cleanup
removed = cleanup_backups_for_all()
print("Removed ephemeral backups:", removed)
```

---

### 📝 `TextFile`: `lines()` & `read_line()`

**Usage explanation:**
Stream large files line-by-line without loading everything; randomly access a specific line (1-based).

**Examples:**

```python
poem = TextFile("poem.txt", "data")
poem.write("Line 1"); poem.append("Line 2"); poem.append("Line 3")

print(poem.read_line(2))  # "Line 2"

for i, line in poem.lines():
    print(i, line)
```

---

### 🧩 `JsonFile`: Dict/List roots, `append`, `get_item`, `items`

**Usage explanation:**
Handles both dict and list roots. `append()` **extends lists** or **shallow-merges dicts**. `get_item()` accesses by **1-based index** (list) or **key** (dict). `items()` iterates useful pairs.

**Examples:**

```python
from ADVfile_manager import JsonFile

# Dict root
conf = JsonFile("conf.json", "data")
conf.write({"users":[{"id":1}]})
conf.append({"active": True})       # shallow dict update
print(conf.get_item("active"))      # True
for k, v in conf.items():
    print(k, v)

# List root
lst = JsonFile("list.json", "data")
lst.write([{"id":1}])
lst.append({"id":2})
lst.append([{"id":3},{"id":4}])
print(lst.get_item(2))              # {"id":2}
for i, item in lst.items():
    print(i, item)
```

---

### 🧾 `CsvFile`: `write`, `append`, `read_row`, `rows`, column order

**Usage explanation:**
Treat CSV as **list-of-dicts**. Control header order with `fieldnames`. Append rows safely. `read_row()` retrieves a 1-based row. `rows()` streams rows.

**Examples:**

```python
from ADVfile_manager import CsvFile

rows = [{"name":"Avi","age":30}, {"name":"Dana","age":25}]
csvf = CsvFile("table.csv", "data")
csvf.write(rows, fieldnames=["name","age"])
csvf.append({"name":"Noa","age":21})

print(csvf.read_row(2))    # {"name":"Dana","age":"25"}
for i, row in csvf.rows():
    print(i, row)
```

---

### 🧱 `YamlFile`: Dict/List roots, `append`, `get_item`, `items`

**Usage explanation:**
Same semantics as `JsonFile`, powered by PyYAML. Perfect for configs.

**Examples:**

```python
from ADVfile_manager import YamlFile

yamlf = YamlFile("config.yaml", "data")
yamlf.write({"app":{"name":"demo"},"features":["a"]})
yamlf.append({"features":["b"]})     # shallow update
print(yamlf.get_item("app"))
for k, v in yamlf.items():
    print(k, v)
```

---

### 🧭 Path Handling (str / pathlib.Path)

**Usage explanation:**
All classes accept either `str` or `pathlib.Path` for `file_path`, so you can integrate easily with modern path code.

**Examples:**

```python
from pathlib import Path
from ADVfile_manager import TextFile

p = Path("data")
txt = TextFile("notes.txt", p)
txt.write("hello with pathlib")
```

---

## License

**MIT License** — © 2025 Avi Twil.
See [`LICENSE`](./LICENSE) for details.

---

Questions or suggestions? Open an issue or PR:
**[https://github.com/avitwil/ADVfile\_manager](https://github.com/avitwil/ADVfile_manager)**

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "ADVfile-manager",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": null,
    "author": "Avi Twil",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/ef/92/e7d00293d90fa206b1c4607ca63b5833ec03bbf8e30a144e3f3383ffce57/advfile_manager-1.0.3.tar.gz",
    "platform": null,
    "description": "\r\n# ADVfile\\_manager\r\n\r\n[![PyPI version](https://badge.fury.io/py/ADVfile_manager.svg)](https://pypi.org/project/ADVfile_manager/)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n[![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/)\r\n\r\n**Author:** Avi Twil\r\n**Repo:** [https://github.com/avitwil/ADVfile\\_manager](https://github.com/avitwil/ADVfile_manager)\r\n\r\nUnified file abstractions for Python with **safe writes, caching, backups, context managers, and exit-time cleanup** \u2014 all under a consistent API for **Text**, **JSON**, **CSV**, and **YAML** files.\r\n\r\n* `TextFile` \u2013 read/write/append lines with `lines()` and `read_line()`.\r\n* `JsonFile` \u2013 works with dict or list roots, `append()`, `get_item()`, `items()`.\r\n* `CsvFile` \u2013 `DictReader`/`DictWriter` based, `read_row()`, `rows()`, column-order control.\r\n* `YamlFile` \u2013 like `JsonFile`, requires `PyYAML`.\r\n\r\nThe base class `File` adds **backups**, **restore**, **retention**, **human-readable sizes**, **cache control**, and a **context manager** that automatically backs up and can restore on error. \u201cEphemeral\u201d backups are cleaned up via a **silent atexit hook**.\r\n\r\n---\r\n\r\n## Table of Contents\r\n\r\n* [Why ADVfile\\_manager?](#why-advfile_manager)\r\n* [Installation](#installation)\r\n* [Quick Start](#quick-start)\r\n* [Detailed Usage](#detailed-usage)\r\n\r\n  * [Common Base: `File`](#common-base-file)\r\n  * [`TextFile`](#textfile)\r\n  * [`JsonFile`](#jsonfile)\r\n  * [`CsvFile`](#csvfile)\r\n  * [`YamlFile`](#yamlfile)\r\n* [Backups, Retention & Exit Cleanup](#backups-retention--exit-cleanup)\r\n* [Context Manager Safety](#context-manager-safety)\r\n* [Advanced Notes](#advanced-notes)\r\n* [Full Examples](#full-examples)\r\n* [Feature-by-Feature Guide (Usage & Examples)](#feature-by-feature-guide-usage--examples)\r\n* [License](#license)\r\n\r\n---\r\n\r\n## Why ADVfile\\_manager?\r\n\r\nTypical file code ends up as a mix of ad-hoc helpers and repeated patterns.\r\nADVfile\\_manager provides one consistent interface across common formats:\r\n\r\n* **Safer writes**: atomic replace to avoid corrupted files.\r\n* **Backups**: create timestamped `.bak` files, list, restore, retain N most recent.\r\n* **Context safety**: `with` block makes a backup on enter (optional) and restores on exceptions.\r\n* **Exit cleanup**: ephemeral backups (for temp edits) are auto-removed via atexit.\r\n* **Streaming helpers**: iterate lines/rows/items without loading everything.\r\n* **Cache control**: in-memory cache when convenient, `clear_cache()` when not.\r\n\r\n---\r\n\r\n## Installation\r\n\r\n### From PyPI (recommended)\r\n\r\n```bash\r\npip install ADVfile_manager\r\n```\r\n\r\n> `YamlFile` requires [PyYAML](https://pypi.org/project/PyYAML/). If your environment doesn\u2019t bring it automatically:\r\n\r\n```bash\r\npip install pyyaml\r\n```\r\n\r\n### From source\r\n\r\n```bash\r\ngit clone https://github.com/avitwil/ADVfile_manager\r\ncd ADVfile_manager\r\npip install -e .\r\n```\r\n\r\n---\r\n\r\n# \ud83d\udd0e Comparison: ADVfile\\_manager vs Similar Tools\r\n\r\n| Feature / Tool             | **ADVfile\\_manager**                                           | [pathlib (stdlib)](https://docs.python.org/3/library/pathlib.html) | [os / shutil (stdlib)](https://docs.python.org/3/library/shutil.html) | [pandas](https://pandas.pydata.org/) | [ruamel.yaml](https://pypi.org/project/ruamel.yaml/) / [PyYAML](https://pyyaml.org/) |\r\n| -------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------ | --------------------------------------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------ |\r\n| **Supported formats**      | TXT, JSON, CSV, YAML                                           | Works with paths only                                              | Copy/move/delete files                                                | CSV, Excel, JSON, parquet, etc.      | YAML only                                                                            |\r\n| **Unified API**            | \u2705 One interface across all formats                             | \u274c                                                                  | \u274c                                                                     | \u274c                                    | \u274c                                                                                    |\r\n| **Read/Write/Append**      | \u2705 Consistent methods (`read`, `write`, `append`)               | Manual file ops                                                    | Manual file ops                                                       | \u2705 (DataFrames)                       | \u2705 (YAML load/dump)                                                                   |\r\n| **Cache system**           | \u2705 In-memory cache + `clear_cache`                              | \u274c                                                                  | \u274c                                                                     | Internal DF cache                    | \u274c                                                                                    |\r\n| **Line/Row helpers**       | \u2705 `lines()`, `read_line()`, `read_row()`, `rows()`             | \u274c                                                                  | \u274c                                                                     | \u2705 but via DataFrame ops              | \u274c                                                                                    |\r\n| **Backup & restore**       | \u2705 `backup()`, `restore()`, `list_backups()`, `clear_backups()` | \u274c                                                                  | \u274c                                                                     | \u274c                                    | \u274c                                                                                    |\r\n| **Backup retention**       | \u2705 `max_backups`                                                | \u274c                                                                  | \u274c                                                                     | \u274c                                    | \u274c                                                                                    |\r\n| **Atomic writes**          | \u2705 via `.tmp` + `os.replace()`                                  | \u274c                                                                  | \u274c                                                                     | \u274c (relies on storage FS)             | \u274c                                                                                    |\r\n| **Human-readable size**    | \u2705 `get_size_human()`                                           | \u274c                                                                  | \u274c                                                                     | \u274c                                    | \u274c                                                                                    |\r\n| **Context manager safety** | \u2705 auto-backup + auto-restore on exception                      | \u274c                                                                  | \u274c                                                                     | \u274c                                    | \u274c                                                                                    |\r\n| **Ephemeral backups**      | \u2705 Auto-cleaned with `atexit` (if `keep_backup=False`)          | \u274c                                                                  | \u274c                                                                     | \u274c                                    | \u274c                                                                                    |\r\n| **Exit cleanup controls**  | \u2705 `set_exit_cleanup`, `cleanup_backups_for_all`                | \u274c                                                                  | \u274c                                                                     | \u274c                                    | \u274c                                                                                    |\r\n| **Dependencies**           | Optional: `pyyaml`                                             | None                                                               | None                                                                  | Heavy (numpy, etc.)                  | Yes                                                                                  |\r\n| **Target use case**        | General-purpose file management with safety                    | File system path manipulation                                      | File system operations                                                | Data analysis                        | YAML-specific parsing                                                                |\r\n\r\n---\r\n\r\n## \ud83d\udccc Key Takeaways\r\n\r\n### What ADVfile\\_manager does *better*:\r\n\r\n* \ud83d\udd12 **Safety-first**: atomic writes, automatic backups, and restore-on-error context manager.\r\n* \ud83e\udde9 **Unified API**: instead of juggling `open()`, `json`, `csv`, and `yaml`, you get one interface.\r\n* \ud83d\uddc2 **Backups with retention**: none of the compared tools provide this out-of-the-box.\r\n* \ud83e\uddf9 **Exit cleanup**: ephemeral backups auto-clean themselves.\r\n* \u26a1 **Lightweight**: works without pandas overhead (which is overkill if you only want CSV/JSON/YAML).\r\n\r\n### When to prefer others:\r\n\r\n* **pathlib / shutil** \u2192 if you only need filesystem manipulation, not file contents.\r\n* **pandas** \u2192 if you need heavy data analysis, joins, filtering, and numeric operations on tabular data.\r\n* **ruamel.yaml / PyYAML** \u2192 if you need advanced YAML features (comments preservation, round-trip editing).\r\n\r\n---\r\n\r\n## \ud83c\udfaf Example Use Cases for ADVfile\\_manager\r\n\r\n* **Config management**: load/modify JSON or YAML configs safely, with rollback if something breaks.\r\n* **Logs & reports**: append text or CSV logs with automatic backup retention.\r\n* **Transactional edits**: use `with File(...) as f:` to ensure no data corruption even on crash.\r\n* **Cross-format tools**: build utilities that handle multiple formats with the same code patterns.\r\n\r\n---\r\n\r\n## Quick Start\r\n\r\n```python\r\nfrom ADVfile_manager import TextFile, JsonFile, CsvFile, YamlFile\r\n\r\n# Text\r\ntxt = TextFile(\"notes.txt\", \"data\")\r\ntxt.write(\"first line\")\r\ntxt.append(\"second line\")\r\nprint(txt.read_line(2))     # \"second line\"\r\nfor i, line in txt.lines():\r\n    print(i, line)\r\n\r\n# JSON (dict root)\r\nj = JsonFile(\"config.json\", \"data\")\r\nj.write({\"users\": [{\"id\": 1}]})\r\nj.append({\"active\": True})  # shallow dict update\r\nprint(j.get_item(\"active\")) # True\r\n\r\n# CSV\r\nc = CsvFile(\"table.csv\", \"data\")\r\nc.write([{\"name\":\"Avi\",\"age\":30},{\"name\":\"Dana\",\"age\":25}], fieldnames=[\"name\",\"age\"])\r\nc.append({\"name\":\"Noa\",\"age\":21})\r\nprint(c.read_row(2))        # {\"name\":\"Dana\",\"age\":\"25\"}\r\nfor idx, row in c.rows():\r\n    print(idx, row)\r\n\r\n# YAML\r\ny = YamlFile(\"config.yaml\", \"data\")\r\ny.write({\"app\":{\"name\":\"demo\"}, \"features\":[\"a\"]})\r\ny.append({\"features\":[\"b\"]})  # shallow dict update\r\nprint(y.get_item(\"app\"))\r\n```\r\n\r\n---\r\n\r\n## Detailed Usage\r\n\r\n### Common Base: `File`\r\n\r\nAll file types inherit from `File` and share:\r\n\r\n* `read()`, `write(data)`, `append(data)`\r\n* `clear_cache()` \u2014 clear in-memory cache so next `read()` hits disk\r\n* `get_size()` / `get_size_human()`\r\n* Backups: `backup()`, `list_backups()`, `restore(backup_path=None)`, `clear_backups()`\r\n* Context manager: `with File(...)(keep_backup=True) as f: ...`\r\n* Exit cleanup controls (module-level):\r\n  `set_exit_cleanup(enabled: bool)` and `cleanup_backups_for_all()`\r\n\r\n#### Constructor\r\n\r\n```python\r\nFile(\r\n  file_name: str,\r\n  file_path: str | pathlib.Path | None = None,  # defaults to CWD if None\r\n  keep_backup: bool = True,                     # default keep backups\r\n  max_backups: int | None = None                # retain only N latest backups\r\n)\r\n```\r\n\r\n* `keep_backup=False` marks the instance as **ephemeral**: its backups are registered to be removed automatically at interpreter exit (and you can also call `cleanup_backups_for_all()` manually).\r\n* `max_backups` enforces retention whenever `backup()` runs.\r\n\r\n#### Backups\r\n\r\n* `backup()` creates `backups/<file>.<YYYYMMDD_HHMMSS_micro>.bak`\r\n* `list_backups()` returns sorted list (oldest \u2192 newest)\r\n* `restore(path=None)` restores a specific backup, or the latest if `None`\r\n* `clear_backups()` deletes all backups for that file and returns the deleted count\r\n\r\n#### Human size\r\n\r\n* `get_size_human()` returns `\"12.3 KB\"` style strings.\r\n\r\n---\r\n\r\n### `TextFile`\r\n\r\n**Extras**:\r\n\r\n* `lines()` \u2192 generator of `(line_no, text)`\r\n* `read_line(n)` \u2192 1-based line access\r\n\r\n```python\r\ntxt = TextFile(\"example.txt\", \"data\")\r\ntxt.write(\"Hello\")\r\ntxt.append(\"World\")\r\nprint(txt.read())           # \"Hello\\nWorld\"\r\nprint(txt.read_line(2))     # \"World\"\r\nfor i, line in txt.lines(): # (1, \"Hello\"), (2, \"World\")\r\n    print(i, line)\r\n```\r\n\r\n---\r\n\r\n### `JsonFile`\r\n\r\nWorks with dict **or** list roots.\r\n\r\n**Extras**:\r\n\r\n* `get_item(index_or_key)`\r\n\r\n  * list-backed: 1-based index (`int`)\r\n  * dict-backed: key (`str`)\r\n* `items()`\r\n\r\n  * list-backed: yields `(index, value)` (1-based)\r\n  * dict-backed: yields `(key, value)`\r\n* `append(data)`\r\n\r\n  * list-backed: append/extend\r\n  * dict-backed: shallow `dict.update()`\r\n\r\n```python\r\n# dict root\r\nj = JsonFile(\"conf.json\", \"data\")\r\nj.write({\"users\":[{\"id\":1}]})\r\nj.append({\"active\": True})     # shallow merge\r\nprint(j.get_item(\"active\"))    # True\r\nfor k, v in j.items():\r\n    print(k, v)\r\n\r\n# list root\r\njl = JsonFile(\"list.json\", \"data\")\r\njl.write([{\"id\":1}])\r\njl.append({\"id\":2})\r\njl.append([{\"id\":3},{\"id\":4}])\r\nprint(jl.get_item(2))          # {\"id\":2}\r\nfor i, item in jl.items():\r\n    print(i, item)\r\n```\r\n\r\n---\r\n\r\n### `CsvFile`\r\n\r\n**Design**: uses `csv.DictReader/DictWriter` (rows are dicts).\r\n\r\n**Extras**:\r\n\r\n* `write(data, fieldnames=None)` \u2014 define columns order; else inferred from data\r\n* `read_row(n)` \u2014 1-based row access\r\n* `rows()` \u2014 generator of `(row_no, row_dict)`\r\n* `append(dict | iterable[dict])`\r\n\r\n```python\r\nc = CsvFile(\"table.csv\", \"data\")\r\nc.write(\r\n    [{\"name\":\"Avi\",\"age\":30},{\"name\":\"Dana\",\"age\":25}],\r\n    fieldnames=[\"name\",\"age\"]           # control column order\r\n)\r\nc.append({\"name\":\"Noa\",\"age\":21})\r\nprint(c.read_row(2))                    # {\"name\":\"Dana\",\"age\":\"25\"}\r\nfor i, row in c.rows():\r\n    print(i, row)\r\n```\r\n\r\n---\r\n\r\n### `YamlFile`\r\n\r\nLike `JsonFile`, but using YAML.\r\n**Requires**: `pip install pyyaml`.\r\n\r\n**Extras**:\r\n\r\n* `get_item(index_or_key)` \u2014 1-based indexes for lists, keys for dicts\r\n* `items()` \u2014 same iteration semantics as `JsonFile`\r\n* `append()` \u2014 list append/extend, dict shallow update\r\n\r\n```python\r\nfrom ADVfile_manager import YamlFile\r\n\r\ny = YamlFile(\"config.yaml\", \"data\")\r\ny.write({\"app\":{\"name\":\"demo\"}, \"features\":[\"a\"]})\r\ny.append({\"features\":[\"b\"]})            # shallow dict update\r\nprint(y.get_item(\"app\"))\r\nfor k, v in y.items():\r\n    print(k, v)\r\n```\r\n\r\n---\r\n\r\n## Backups, Retention & Exit Cleanup\r\n\r\n* **Create**: `path = f.backup()`\r\n  Backups are timestamped down to microseconds to avoid collisions.\r\n* **Retention**: set `max_backups=N` on the instance; when `backup()` runs, old backups beyond N are deleted.\r\n* **List**: `f.list_backups()` \u2192 sorted list (oldest \u2192 newest)\r\n* **Restore**:\r\n\r\n  * latest: `f.restore()`\r\n  * specific: `f.restore(path)`\r\n* **Clear**: `f.clear_backups()` returns the deleted count\r\n\r\n**Ephemeral backups** (`keep_backup=False`):\r\n\r\n* Mark the instance transient with `File(..., keep_backup=False)` or via `obj(keep_backup=False)`.\r\n* These are **registered** for deletion at **interpreter exit** by a silent atexit hook.\r\n* You can control this globally:\r\n\r\n```python\r\nfrom ADVfile_manager import set_exit_cleanup, cleanup_backups_for_all\r\n\r\nset_exit_cleanup(True)          # enable (default)\r\nset_exit_cleanup(False)         # disable\r\n\r\nremoved = cleanup_backups_for_all()  # manual cleanup (returns deleted count)\r\n```\r\n\r\n---\r\n\r\n## Context Manager Safety\r\n\r\n* `with` creates a **backup on enter** (unless you set `keep_backup=False`).\r\n* If an **exception** is raised inside the block and `keep_backup=True`, the file is **restored** from the latest backup.\r\n* **Cache is always cleared** on exit to ensure the next `read()` hits disk.\r\n\r\n```python\r\n# default: keep_backup=True\r\nwith TextFile(\"draft.txt\", \"data\") as f:\r\n    f.write(\"safe transactional edit\")\r\n    # if an exception occurs here, latest backup will be restored\r\n\r\n# ephemeral: backups are registered for exit cleanup\r\nwith TextFile(\"temp.txt\", \"data\")(keep_backup=False) as f:\r\n    f.write(\"temporary content\")\r\n```\r\n\r\n---\r\n\r\n## Advanced Notes\r\n\r\n* **Atomic writes**: `write()` methods use a `*.tmp` + `os.replace()` strategy so files aren\u2019t left half-written.\r\n* **Pathlib**: all classes accept `str` or `pathlib.Path` for `file_path`.\r\n* **Caching**: `read()` caches content. Use `clear_cache()` if the file was modified externally or you want a fresh read.\r\n* **Append semantics**:\r\n\r\n  * Text: appends `\"\\n\"+data\"` when file is non-empty.\r\n  * JSON/YAML:\r\n\r\n    * list root \u2192 append/extend\r\n    * dict root \u2192 **shallow** `dict.update()`\r\n* **CSV types**: values read by `DictReader` are `str`. After `append()`, cached rows keep stringified values for consistency.\r\n* **Python**: 3.8+ recommended.\r\n\r\n---\r\n\r\n## Full Examples\r\n\r\n### 1) Text + Backups + Restore Specific\r\n\r\n```python\r\nfrom ADVfile_manager import TextFile\r\n\r\ntxt = TextFile(\"example.txt\", \"example_data\")\r\ntxt.write(\"v1\"); b1 = txt.backup()\r\ntxt.write(\"v2\"); b2 = txt.backup()\r\ntxt.write(\"v3\"); b3 = txt.backup()\r\n\r\nprint(\"Backups:\", txt.list_backups())\r\ntxt.restore(b2)\r\nprint(\"Restored content:\", txt.read())  # \"v2\"\r\n```\r\n\r\n### 2) Retention (keep only last 2)\r\n\r\n```python\r\ntxt.max_backups = 2\r\ntxt.write(\"v4\"); txt.backup()\r\ntxt.write(\"v5\"); txt.backup()\r\nprint(\"After retention:\", txt.list_backups())  # only 2 latest remain\r\n```\r\n\r\n### 3) Ephemeral Backups + Exit Cleanup\r\n\r\n```python\r\nfrom ADVfile_manager import TextFile, cleanup_backups_for_all, set_exit_cleanup\r\n\r\nwith TextFile(\"temp.txt\", \"example_data\")(keep_backup=False) as f:\r\n    f.write(\"temporary content\")\r\n\r\n# You can manually clean now (or rely on atexit):\r\ndeleted = cleanup_backups_for_all()\r\nprint(\"Deleted backup files:\", deleted)\r\n\r\n# Disable/Enable the global atexit cleanup:\r\nset_exit_cleanup(False)   # no automatic cleanup on interpreter exit\r\nset_exit_cleanup(True)    # re-enable\r\n```\r\n\r\n### 4) CSV with Column Order Control\r\n\r\n```python\r\nfrom ADVfile_manager import CsvFile\r\n\r\nrows = [{\"name\":\"Avi\",\"age\":30},{\"name\":\"Dana\",\"age\":25}]\r\nc = CsvFile(\"table.csv\", \"example_data\")\r\nc.write(rows, fieldnames=[\"name\",\"age\"])  # explicit order\r\nc.append({\"name\":\"Noa\",\"age\":21})\r\n\r\nprint(c.read_row(2))      # {\"name\":\"Dana\",\"age\":\"25\"}\r\nfor i, row in c.rows():\r\n    print(i, row)\r\n```\r\n\r\n### 5) JSON/YAML Dict & List Behaviors\r\n\r\n```python\r\nfrom ADVfile_manager import JsonFile, YamlFile\r\n\r\n# JSON dict\r\nj = JsonFile(\"data.json\", \"example_data\")\r\nj.write({\"users\":[{\"id\":1}]})\r\nj.append({\"active\": True})\r\nprint(j.get_item(\"active\"))  # True\r\n\r\n# JSON list\r\njl = JsonFile(\"list.json\", \"example_data\")\r\njl.write([{\"id\":1}])\r\njl.append([{\"id\":2},{\"id\":3}])\r\nprint(jl.get_item(2))        # {\"id\":2}\r\n\r\n# YAML dict\r\ny = YamlFile(\"config.yaml\", \"example_data\")\r\ny.write({\"app\":{\"name\":\"demo\"},\"features\":[\"a\"]})\r\ny.append({\"features\":[\"b\"]})\r\nprint(y.get_item(\"app\"))\r\n```\r\n\r\n---\r\n\r\n## Feature-by-Feature Guide (Usage & Examples)\r\n\r\nBelow you\u2019ll find **every feature** with a **Usage explanation** (what & why) and **Examples** (how).\r\n\r\n---\r\n\r\n### \u2714\ufe0f Safe Writes (Atomic)\r\n\r\n**Usage explanation:**\r\nAvoids partially-written files if your program crashes mid-write. Data is written to a temp file and then **atomically** replaces the target with `os.replace()`. This pattern is ideal for configs and logs where consistency matters.\r\n\r\n**Examples:**\r\n\r\n```python\r\nfrom ADVfile_manager import TextFile\r\n\r\ncfg = TextFile(\"settings.txt\", \"data\")\r\ncfg.write(\"mode=prod\")     # safe atomic write\r\ncfg.write(\"mode=debug\")    # previous state remains intact until replace\r\n```\r\n\r\n---\r\n\r\n### \ud83e\udde0 In-Memory Cache & `clear_cache()`\r\n\r\n**Usage explanation:**\r\n`read()` caches content to save disk I/O on repeated calls. If the file might have been changed by another process or manually edited, call `clear_cache()` before next `read()`.\r\n\r\n**Examples:**\r\n\r\n```python\r\nlog = TextFile(\"app.log\", \"data\")\r\nprint(log.read())     # loads + caches\r\n# ... external edit happens ...\r\nlog.clear_cache()\r\nprint(log.read())     # reloads from disk\r\n```\r\n\r\n---\r\n\r\n### \ud83d\udccf File Size & `get_size_human()`\r\n\r\n**Usage explanation:**\r\nDisplay storage size in UI/CLI or for sanity checks. `get_size()` returns bytes; `get_size_human()` returns \u201c12.3 KB\u201d style strings.\r\n\r\n**Examples:**\r\n\r\n```python\r\nf = TextFile(\"notes.txt\", \"data\")\r\nf.write(\"Hello world\")\r\nprint(f.get_size())         # e.g. 11\r\nprint(f.get_size_human())   # e.g. \"11.0 B\"\r\n```\r\n\r\n---\r\n\r\n### \ud83d\udedf Backups: `backup`, `list_backups`, `restore`, `clear_backups`\r\n\r\n**Usage explanation:**\r\nBefore risky edits, create a backup. If something breaks, restore it. Use `list_backups()` to inspect available snapshots; `clear_backups()` to purge when done.\r\n\r\n**Examples:**\r\n\r\n```python\r\ntxt = TextFile(\"daily.txt\", \"data\")\r\ntxt.write(\"v1\"); b1 = txt.backup()\r\ntxt.write(\"v2\"); b2 = txt.backup()\r\n\r\nprint(txt.list_backups())   # [b1, b2]\r\ntxt.restore(b1)             # restore specific\r\nprint(txt.read())           # \"v1\"\r\n\r\ntxt.restore()               # restore latest\r\nprint(txt.read())           # \"v2\"\r\n\r\nprint(\"Removed:\", txt.clear_backups())\r\n```\r\n\r\n---\r\n\r\n### \u267b\ufe0f Backup Retention (`max_backups`)\r\n\r\n**Usage explanation:**\r\nKeep only the **last N** backups to control disk usage. Retention is enforced when `backup()` runs.\r\n\r\n**Examples:**\r\n\r\n```python\r\nrpt = TextFile(\"report.txt\", \"data\", max_backups=2)\r\nfor i in range(5):\r\n    rpt.write(f\"v{i}\")\r\n    rpt.backup()\r\nprint(rpt.list_backups())   # only 2 latest\r\n```\r\n\r\n---\r\n\r\n### \ud83e\uddf0 Context Manager (Transactional Safety)\r\n\r\n**Usage explanation:**\r\n`with` creates a backup on enter (if `keep_backup=True`). If an exception occurs inside the block, it auto-restores on exit. Cache is always cleared when leaving the context.\r\n\r\n**Examples:**\r\n\r\n```python\r\n# Normal usage\r\nwith TextFile(\"draft.txt\", \"data\") as f:\r\n    f.write(\"transactional content\")\r\n\r\n# Auto-restore on error\r\ntry:\r\n    with TextFile(\"draft.txt\", \"data\") as f:\r\n        f.write(\"new content\")\r\n        raise RuntimeError(\"Simulated crash\")\r\nexcept:\r\n    pass\r\n\r\nprint(\"Restored:\", TextFile(\"draft.txt\", \"data\").read())\r\n```\r\n\r\n---\r\n\r\n### \ud83e\uddf9 Ephemeral Backups & Exit Cleanup\r\n\r\n**Usage explanation:**\r\nTemporary operations can request `keep_backup=False`. Such backups are automatically cleaned up at interpreter exit (or manually via `cleanup_backups_for_all`). Control the global behavior with `set_exit_cleanup`.\r\n\r\n**Examples:**\r\n\r\n```python\r\nfrom ADVfile_manager import set_exit_cleanup, cleanup_backups_for_all\r\n\r\nwith TextFile(\"tmp.txt\", \"data\")(keep_backup=False) as f:\r\n    f.write(\"temp content\")\r\n\r\n# switch global behavior\r\nset_exit_cleanup(False)\r\nset_exit_cleanup(True)\r\n\r\n# manual immediate cleanup\r\nremoved = cleanup_backups_for_all()\r\nprint(\"Removed ephemeral backups:\", removed)\r\n```\r\n\r\n---\r\n\r\n### \ud83d\udcdd `TextFile`: `lines()` & `read_line()`\r\n\r\n**Usage explanation:**\r\nStream large files line-by-line without loading everything; randomly access a specific line (1-based).\r\n\r\n**Examples:**\r\n\r\n```python\r\npoem = TextFile(\"poem.txt\", \"data\")\r\npoem.write(\"Line 1\"); poem.append(\"Line 2\"); poem.append(\"Line 3\")\r\n\r\nprint(poem.read_line(2))  # \"Line 2\"\r\n\r\nfor i, line in poem.lines():\r\n    print(i, line)\r\n```\r\n\r\n---\r\n\r\n### \ud83e\udde9 `JsonFile`: Dict/List roots, `append`, `get_item`, `items`\r\n\r\n**Usage explanation:**\r\nHandles both dict and list roots. `append()` **extends lists** or **shallow-merges dicts**. `get_item()` accesses by **1-based index** (list) or **key** (dict). `items()` iterates useful pairs.\r\n\r\n**Examples:**\r\n\r\n```python\r\nfrom ADVfile_manager import JsonFile\r\n\r\n# Dict root\r\nconf = JsonFile(\"conf.json\", \"data\")\r\nconf.write({\"users\":[{\"id\":1}]})\r\nconf.append({\"active\": True})       # shallow dict update\r\nprint(conf.get_item(\"active\"))      # True\r\nfor k, v in conf.items():\r\n    print(k, v)\r\n\r\n# List root\r\nlst = JsonFile(\"list.json\", \"data\")\r\nlst.write([{\"id\":1}])\r\nlst.append({\"id\":2})\r\nlst.append([{\"id\":3},{\"id\":4}])\r\nprint(lst.get_item(2))              # {\"id\":2}\r\nfor i, item in lst.items():\r\n    print(i, item)\r\n```\r\n\r\n---\r\n\r\n### \ud83e\uddfe `CsvFile`: `write`, `append`, `read_row`, `rows`, column order\r\n\r\n**Usage explanation:**\r\nTreat CSV as **list-of-dicts**. Control header order with `fieldnames`. Append rows safely. `read_row()` retrieves a 1-based row. `rows()` streams rows.\r\n\r\n**Examples:**\r\n\r\n```python\r\nfrom ADVfile_manager import CsvFile\r\n\r\nrows = [{\"name\":\"Avi\",\"age\":30}, {\"name\":\"Dana\",\"age\":25}]\r\ncsvf = CsvFile(\"table.csv\", \"data\")\r\ncsvf.write(rows, fieldnames=[\"name\",\"age\"])\r\ncsvf.append({\"name\":\"Noa\",\"age\":21})\r\n\r\nprint(csvf.read_row(2))    # {\"name\":\"Dana\",\"age\":\"25\"}\r\nfor i, row in csvf.rows():\r\n    print(i, row)\r\n```\r\n\r\n---\r\n\r\n### \ud83e\uddf1 `YamlFile`: Dict/List roots, `append`, `get_item`, `items`\r\n\r\n**Usage explanation:**\r\nSame semantics as `JsonFile`, powered by PyYAML. Perfect for configs.\r\n\r\n**Examples:**\r\n\r\n```python\r\nfrom ADVfile_manager import YamlFile\r\n\r\nyamlf = YamlFile(\"config.yaml\", \"data\")\r\nyamlf.write({\"app\":{\"name\":\"demo\"},\"features\":[\"a\"]})\r\nyamlf.append({\"features\":[\"b\"]})     # shallow update\r\nprint(yamlf.get_item(\"app\"))\r\nfor k, v in yamlf.items():\r\n    print(k, v)\r\n```\r\n\r\n---\r\n\r\n### \ud83e\udded Path Handling (str / pathlib.Path)\r\n\r\n**Usage explanation:**\r\nAll classes accept either `str` or `pathlib.Path` for `file_path`, so you can integrate easily with modern path code.\r\n\r\n**Examples:**\r\n\r\n```python\r\nfrom pathlib import Path\r\nfrom ADVfile_manager import TextFile\r\n\r\np = Path(\"data\")\r\ntxt = TextFile(\"notes.txt\", p)\r\ntxt.write(\"hello with pathlib\")\r\n```\r\n\r\n---\r\n\r\n## License\r\n\r\n**MIT License** \u2014 \u00a9 2025 Avi Twil.\r\nSee [`LICENSE`](./LICENSE) for details.\r\n\r\n---\r\n\r\nQuestions or suggestions? Open an issue or PR:\r\n**[https://github.com/avitwil/ADVfile\\_manager](https://github.com/avitwil/ADVfile_manager)**\r\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Unified file abstractions with backups, context manager, and exit cleanup.",
    "version": "1.0.3",
    "project_urls": {
        "Homepage": "https://github.com/avitwil/ADVfile_manager"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a77b65453de1f5941ee34b8f55790b7563ac08d7d135b855ac34e1f23b6ccd4e",
                "md5": "92c811649718c2a1e2eafa395dea872b",
                "sha256": "495c3cc233d7d2f8379622126f503279c74e242a69a9442b0cd9c085f8c5d212"
            },
            "downloads": -1,
            "filename": "advfile_manager-1.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "92c811649718c2a1e2eafa395dea872b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 18291,
            "upload_time": "2025-09-03T19:48:26",
            "upload_time_iso_8601": "2025-09-03T19:48:26.202776Z",
            "url": "https://files.pythonhosted.org/packages/a7/7b/65453de1f5941ee34b8f55790b7563ac08d7d135b855ac34e1f23b6ccd4e/advfile_manager-1.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ef92e7d00293d90fa206b1c4607ca63b5833ec03bbf8e30a144e3f3383ffce57",
                "md5": "0d62af58613718ff1de5bbda9d542ef8",
                "sha256": "c5447c592f98d45ddcfefe027a0399b48cb254401b0331b05a62870fa48a9205"
            },
            "downloads": -1,
            "filename": "advfile_manager-1.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "0d62af58613718ff1de5bbda9d542ef8",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 24163,
            "upload_time": "2025-09-03T19:48:27",
            "upload_time_iso_8601": "2025-09-03T19:48:27.385788Z",
            "url": "https://files.pythonhosted.org/packages/ef/92/e7d00293d90fa206b1c4607ca63b5833ec03bbf8e30a144e3f3383ffce57/advfile_manager-1.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-03 19:48:27",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "avitwil",
    "github_project": "ADVfile_manager",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "advfile-manager"
}
        
Elapsed time: 0.78558s