Skip to main content

A structured and backup-friendly way to manage `.txt` files with multi-console and debugging support.

Project description


🪖 WithOpen as f : "Your code's .txt guide"

A robust, zero-dependency .txt file manager for structured automation, pipelines, and bots. Built for reliability, integrity, and confidence. Replacing 20+ lines of code and logic with a single one-liner.

This project started from a simple frustration: After writing hundreds of with open(file) as .. lines, building backups, validating structures, and hacking delete filters, I realized I was reinventing the same patterns over and over.

So I made withopen: A zero-dependency Python utility that treats plain .txt files like structured datasets. Safely and scalably.

It's not a database. It's a reliable, structured backend for:

  • Automations
  • Bots
  • CLI tools
  • Low overhead microservices

🎯 Key Capabilities

  • Structure Enforcement: First write or append defines whether data is 1D or 2D. Future data must match.
  • CRUD Operations: w() (write), r() (read), a() (append), d() (delete, trim, filter)
  • Multi console safe: Handles concurrent processes to avoid corruption.
  • Backups & Snapshots: Automatic and manual backups. Time-based snapshots.
  • Backdate: Point the DB to a previous backup folder for reading or restoring past states.
  • Auto Folder Organization: All files, backups, and snapshots are kept in structured folders. No clutter.
  • Anti-Tamper Safe Mode: Hidden files and structure locking help protect against manual edits or file corruption.
  • Debug & Recovery: Scan for structural errors and selectively repair.
  • Hide / Unhide: Protect files from accidental user tampering.
  • Zero dependencies, intuitive API, and minimal setup.

🔑 Core Functions

w(): Write or Overwrite

w(txt_name, write_list, is2d=None)
Parameter Type Description
txt_name str Name of the file (without extension).
write_list list Data to write (1D or 2D list). Overwrites existing content.
is2d bool or None Specify structure type on first write or when resetting. Only required if the file is new or empty.

📝 Use [] to reset file structure.

📖 r(): Read

r(txt_name, index=None, set_new=[], notify_new=True)
Parameter Type Description
txt_name str Name of the file.
index int, list, or None Return only data from specific index or columns.
set_new list If file doesn't exist, create it using this list.
notify_new bool Print a message if the file was auto-created. Default is True.

a(): Append

a(txt_name, append_list, is2d=None)
Parameter Type Description
txt_name str Name of the file.
append_list list Data to append (must match existing structure).
is2d bool or None Required only for new or empty files.

d(): Delete, Filter, or Trim

d(txt_name, del_list=[], index=None, cutoff=None, keep=None, reverse=False, size=None)
Parameter Type Description
txt_name str Name of the file.
del_list list or str Values to match for deletion.
index int, list, "*" or None Column or columns to match values in. "*" matches whole row.
cutoff int Maximum number of deletions per value.
keep int Retain only N matching rows.
reverse bool Delete from end instead of top.
size int Trim the file to only last N rows.

🧠 You can mix and match these for precise cleanup strategies.

⚙️ Installation

pip install withopen

Example Workflow

import withopen as f

# Write 2D data (first write locks structure)
f.w("tasks", [["Name", "Status"], ["Ping", "Done"], ["Build", "Pending"]])

# Append new row (must match shape)
f.a("tasks", [["Test", "Pending"]])

# Read all rows
print(f.r("tasks"))

# Read specific column or row
print(f.r("tasks", index=1))      # second column across all rows
print(f.r("tasks", index=[0, 2])) # columns 0 and 2

# Delete by matching value
f.d("tasks", del_list=["Done"], index=1)

# Trim to last N rows
f.d("tasks", size=3)

# Backup and snapshot
f.backup("tasks")
f.snapshot("tasks", unit="h", gap=4)

# Backdate to a previous backup state
f.backdate(recency=1)  # point DB to latest backup
f.backdate(recency=2)  # point DB to second latest backup

# Debug or fix structure errors
f.debug("tasks", is2d=True, length=2)

# Hide or unhide
f.hide("tasks")
f.unhide("tasks")

📋 Data Models: 1D and 2D

Mode Example Notes
1D ["apple", "banana", "pear"] Use is2d=False on first write or append
2D [["user","score"], ["alice",10], ["bob",8]] Use is2d=True on first write or append

To reset structure (clear file):

f.w("filename", [], is2d=None)

🧹 Deletion and Filtering

d() is versatile. Combine arguments:

  • del_list (values or rows)
  • index (column index, list of indices, or "*" for full row)
  • cutoff (max deletes per value)
  • keep (retain only N matches)
  • reverse (delete from end)
  • size (keep only last N rows)

Examples

Delete rows where status is "Done":

f.d("tasks", del_list=["Done"], index=1)

Delete a full exact row:

f.d("tasks", del_list=[["Ping","Done"]], index="*")

Trim to last 5 rows:

f.d("tasks", size=5)

Keep only N occurrences of a value:

f.d("tasks", del_list=["Pending"], index=1, keep=2)

🔢 Index Matching Patterns

1. Match by Single Index (Column)

f.d("tasks", del_list=["Pending"], index=1)

Deletes all rows where column 1 (status) is "Pending".

2. Match by Multiple Indexes (Multi-Column Logic)

f.d("tasks", del_list=[["Fix Bug", "High"]], index=[0, 2])

Deletes rows where column 0 is "Fix Bug" and column 2 is "High".

3. Match Entire Row

f.d("tasks", del_list=[["Fix Bug", "Done", "Low"]], index="*")

Deletes exact row match across all columns.

4. Match Multiple Rows by Value in a Column

f.d("tasks", del_list=[["Deploy"], ["Write Docs"]], index=0)

Deletes any row where column 0 (task name) matches "Deploy" or "Write Docs".

5. Selective Cutoff Deletes

f.d("tasks", del_list=["Pending"], index=1, cutoff=2)

Deletes only the first 2 rows where column 1 is "Pending".

6. Reverse Delete

f.d("tasks", del_list=["Done"], index=1, reverse=True)

Deletes from the bottom up, not top-down.

7. Trim by Row Count (No index)

f.d("tasks", size=5)

Keeps only the last 5 rows. Trims the rest.

🛠 Debugging and Recovery

When a file's structure is compromised:

debug("tasks", is2d=True, length=2)
  • Flags bad rows and optionally cleans them.
  • Use majority-vote backups to restore when corruption occurs.

📁 Backups, Snapshots, and Backdate

  • backup("tasks"): manual backup
  • snapshot("tasks", unit, gap, trim=None, begin=0): time-based backup
    • Units: 's', 'm', 'h', 'd', 'mo', 'y'
    • gap: minimum time between snapshots
    • trim: max rows in snapshot
  • backdate(recency, display=True): point the DB to a previous backup folder
    • recency=1 → latest backup, recency=2 → second latest, and so on
    • Useful for reading or restoring a past state without modifying the main folder

Backups and snapshots are stored in structured subfolders.

🔐 Hide or Unhide Files

  • hide("tasks"): prevents accidental edits or reads
  • unhide("tasks"): makes file visible again
  • Use "*" to hide or unhide all files

🧠 Best Practices

  1. Always use the API (w, a, r, d) and avoid manual edits.
  2. Run debug() periodically for long-lived files.
  3. Use snapshot() in scripts that run continuously.
  4. Use backdate() to read or restore data from a previous backup state.
  5. Use hide() when bundling scripts to protect internal files.
  6. Reset structure if your shape definition changes (with w("file", [])).

🔧 Utility Functions

🖥️ consoles(): Console Mode Config

f.consoles(txt_name, multiple=True, alert=True)

Sets console interaction mode for:

  • Multiple scripts
  • Multiple tabs
  • Bots and automation tools

Ensures safe concurrent access by coordinating file locks per console context. Use this when your files are read or written by multiple parallel environments.


🔕 warning(): Enable or Disable Read Alerts

f.warning(alert=False)

Turns on or off the warning that appears when reading a file outside of console safe mode.

Useful for bots or CI/CD logs where alerts aren't needed.


backdate(recency, display=True)

Points the DB to a previous backup folder instead of the live main package. Useful for inspecting or restoring past states without touching current data.

Parameter Type Description
recency int How many backups ago. 1 = latest, 2 = second latest, etc.
display bool Whether to print the updated path. Default is True.
f.backdate(recency=1)  # point to latest backup
f.backdate(recency=3, display=False)  # silent, third latest

⚠️ This overrides the active package path. Re-run your app or call the main path restore to return to live data.


🗑️ remove(txt_name, display=True)

Deletes the target file along with all backups and snapshots. ⚠️ Use with caution. This is irreversible.

ℹ️ info(txt_name, display=True)

Returns metadata such as structure type, total rows, shape, and last modified time.

🧪 debug(txt_name, is2d=None, length=None, display=True)

Scans for structure issues like row length mismatches or corrupted lines. Can auto-fix when used with length or is2d.

📂 listdir(display=True)

Lists all structured text files currently being tracked.

🆘 help()

Prints a quick-reference summary of all available functions and parameters. Great for in-terminal use.

📄 License

This project is licensed under the MIT License. Use freely, modify, share. No warranties.


Project details


Download files

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

Source Distribution

withopen-7.0.0.tar.gz (56.3 kB view details)

Uploaded Source

Built Distribution

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

withopen-7.0.0-py3-none-any.whl (56.5 kB view details)

Uploaded Python 3

File details

Details for the file withopen-7.0.0.tar.gz.

File metadata

  • Download URL: withopen-7.0.0.tar.gz
  • Upload date:
  • Size: 56.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for withopen-7.0.0.tar.gz
Algorithm Hash digest
SHA256 b7d786e324835e0747f54b8df5baaf42caef295b73c2b32898172d7bff26f5a6
MD5 0e1d7aa90207c1873fd96489476325ba
BLAKE2b-256 c4024a070df41a36ccd8683a45bcd130c9bb0e79538033c936e7c2e94239f2db

See more details on using hashes here.

File details

Details for the file withopen-7.0.0-py3-none-any.whl.

File metadata

  • Download URL: withopen-7.0.0-py3-none-any.whl
  • Upload date:
  • Size: 56.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for withopen-7.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 551a3536526535172fff72ceff61db80205179ab3a6f39f6bace9e323d48aa52
MD5 1d6eed22b62031d5de671f25b857fb57
BLAKE2b-256 9844c8e5773239befcdd02c732fb224236bc1c86855fd4a4b54c1990384ddc53

See more details on using hashes here.

Supported by

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