Name | ADVfile-manager JSON |
Version |
1.0.3
JSON |
| download |
home_page | None |
Summary | Unified file abstractions with backups, context manager, and exit cleanup. |
upload_time | 2025-09-03 19:48:27 |
maintainer | None |
docs_url | None |
author | Avi Twil |
requires_python | >=3.8 |
license | MIT |
keywords |
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# ADVfile\_manager
[](https://pypi.org/project/ADVfile_manager/)
[](https://opensource.org/licenses/MIT)
[](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[](https://pypi.org/project/ADVfile_manager/)\r\n[](https://opensource.org/licenses/MIT)\r\n[](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"
}