Cross-platform Python utilities with CLI and AI-friendly JSON envelopes
Project description
中文 | English
Cross-platform Python utilities (2.0): same code on Windows, macOS, and Linux. The etool command exposes major features from the shell; use --json for a pretty-printed JSON envelope (2-space indent, valid JSON) suitable for AI agents and scripts (ok / err).
Requires Python 3.12+.
Install
pip install -U etool
After install, the etool entry point is on your PATH. You can also run python -m etool .... With uv from a clone: uv run etool ....
CLI: --json envelope
With --json, stdout is one JSON document per invocation (pretty-printed with 2-space indent):
- Success:
{"ok": true, "data": { ... }} - Failure:
{"ok": false, "error": {"code", "message", "details"}}
Without --json, output is a human-readable form (often pretty-printed JSON for structured data).
Below, Input is the command; Output shows typical --json stdout (values such as paths, passwords, and timings are illustrative).
Version
Input
etool --json version
Output
{"ok": true, "data": {"version": "2.1.0"}}
Password
Random password
etool --json password random --length 16
{"ok": true, "data": {"password": "xYz9...16chars"}}
Base conversion
etool --json password convert-base --from-base 16 --to-base 2 A1F
{"ok": true, "data": {"result": "101000011111"}}
Speed (network / disk / memory)
Network (uses speedtest-cli; needs internet, can be slow)
etool --json speed network
{"ok": true, "data": {"report": "\n network test result:\ndownload speed: ... Mbps\n..."}}
Disk
etool --json speed disk --file-size-mb 10
{"ok": true, "data": {"report": "\n disk test result:\nread speed: ... MB/s\nwrite speed: ... MB/s\n"}}
Memory (stdlib buffer test)
etool --json speed memory --size-mb 32
{"ok": true, "data": {"report": "\n memory test result:\nread speed: ... MB/s\nwrite speed: ... MB/s"}}
PDF (ManagerPdf)
Merge
etool --json pdf merge --out merged.pdf part1.pdf part2.pdf
{"ok": true, "data": {"merged": "merged.pdf", "log": "merged: part1.pdf\nmerged: part2.pdf\nmerged file saved as: merged.pdf"}}
Split by page chunk size
etool --json pdf split-pages --pages 3 document.pdf
{"ok": true, "data": {"source": "document.pdf", "log": "generated: document_part_by_page1.pdf\n..."}}
Split into N parts
etool --json pdf split-num --parts 2 document.pdf
{"ok": true, "data": {"source": "document.pdf", "log": "..."}}
Encrypt / decrypt
etool --json pdf encrypt --password secret doc.pdf --out doc_encrypted.pdf
etool --json pdf decrypt --password secret doc_encrypted.pdf --out doc_clear.pdf
{"ok": true, "data": {"log": "encrypted file saved as: doc_encrypted.pdf"}}
Insert another PDF after a page index
etool --json pdf insert --pdf1 a.pdf --pdf2 b.pdf --after-page 0 --out out.pdf
{"ok": true, "data": {"output": "out.pdf", "log": "inserted file saved as: out.pdf"}}
Watermark
etool --json pdf watermark --target folder_or_file.pdf --watermark wm.pdf --out-dir watermarked
{"ok": true, "data": {"log": "..."}}
PDF → PNG images
etool --json pdf to-images --input doc.pdf --out-dir png_out --dpi 2
{"ok": true, "data": {"log": "found 1 PDF file(s)\n..."}}
Word (ManagerDocx)
Replace text
etool --json docx replace --path report.docx --old foo --new bar
{"ok": true, "data": {"path": "report.docx"}}
Swap page dimensions (landscape ↔ portrait style)
etool --json docx swap-dimensions --input in.docx --output out.docx
{"ok": true, "data": {"path": "out.docx"}}
Extract embedded images
etool --json docx extract-images --input in.docx --out-dir ./img_out
{"ok": true, "data": {"path": "./img_out"}}
Excel (ManagerExcel)
Copy formatting from a template workbook
etool --json excel copy-format --source template.xlsx --output out.xlsx
{"ok": true, "data": {"path": "out.xlsx"}}
Images (ManagerImage)
Merge left–right / top–bottom
etool --json image merge-lr left.png right.png --out lr.png
etool --json image merge-ud top.png bottom.png --out ud.png
{"ok": true, "data": {"path": "lr.png"}}
Pad to square / 3×3 grid crop / batch rename to WebP
etool --json image fill-square photo.jpg --out square.jpg
etool --json image cut-grid photo.jpg
etool --json image rename-webp ./shots --remove-original
{"ok": true, "data": {"paths": ["photo_cut00.jpg", "..."]}}
QR code (ManagerQrcode)
Generate
etool --json qrcode generate --text "https://example.com" --out qr.png
{"ok": true, "data": {"path": "qr.png"}}
Decode (local OpenCV)
etool --json qrcode decode qr.png
{"ok": true, "data": {"text": "https://example.com"}}
Jupyter (ManagerIpynb)
Merge all .ipynb in a directory
etool --json ipynb merge-dir ./notebooks/
{"ok": true, "data": {"path": "./notebooks.ipynb"}}
Notebook → Markdown file
etool --json ipynb to-markdown analysis.ipynb --out-dir ./md_out
{"ok": true, "data": {"path": "analysis.md"}}
Markdown (ManagerMd)
etool --json md to-docx notes.md --out notes.docx
etool --json md to-html notes.md --out notes.html
etool --json md tables-to-xlsx tables.md --out tables.xlsx
{"ok": true, "data": {"message": "已将Markdown文件转换为Word文档并保存至: notes.docx"}}
Standard-library usage analysis
One subcommand: stdlib analyze DIR. By default the envelope puts the nested counts under data.result (JSON object). With --json-string, the same analysis is returned as a single formatted JSON text under data.json (useful when you want one string field instead of nested JSON).
etool --json stdlib analyze ./src
etool --json stdlib analyze ./src --json-string
{"ok": true, "data": {"result": {"os": {"path.join": 12, "listdir": 3}}}}
{"ok": true, "data": {"json": "{\n \"os\": {\n \"path.join\": 12\n }\n}"}}
Install requirements (ManagerInstall)
Uses python -m pip install internally.
etool --json install-reqs --file requirements.txt --failed-file failed.txt --retry 2
{"ok": true, "data": {"success": true}}
On failure:
{"ok": false, "error": {"code": "RUNTIME_ERROR", "message": "some packages failed to install", "details": {}}}
Scheduler (ManagerScheduler.parse_schedule_time — debug printout)
etool --json scheduler parse 120
etool --json scheduler parse '"08:00"'
{"ok": true, "data": {"log": "Execute every 120 seconds"}}
Email (ManagerEmail.send_email)
Do not paste real passwords into shell history; prefer environment-specific secrets in automation.
etool --json email send \
--sender you@example.com \
--password "$SMTP_PASSWORD" \
--recipient other@example.com \
--message "Hello" \
--subject "Test"
{"ok": true, "data": {"result": "send success"}}
Python API and AI envelopes
Library usage matches the managers above. For structured envelopes in code:
from etool import ok, err, EtoolError, ErrorCode
payload = ok({"path": "/tmp/out.pdf"})
failure = err(EtoolError(ErrorCode.VALIDATION_ERROR, "bad input", {"field": "x"}))
Removed in 2.0
- Windows COM / registry / context menu (
ManagerMenu) - Screen sharing and Flask file share (
ManagerShare) - GPU memory / CUDA speed test
ManagerPdf.pdfconverter(Office → PDF via local Microsoft Office)
Development
With uv: uv sync installs runtime deps plus the dev group (pytest). Commit uv.lock with the repo.
uv sync
uv run pytest tests/test_etool.py -v
With pip:
pip install -e ".[dev]"
pytest tests/test_etool.py -v
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file etool-2.1.0.tar.gz.
File metadata
- Download URL: etool-2.1.0.tar.gz
- Upload date:
- Size: 40.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f50d34c393a0653bc160549ddc89bb9958703440c674973256d50ead3ebe3f85
|
|
| MD5 |
ea43ae59a45537d13abca7c4ba5cbd2f
|
|
| BLAKE2b-256 |
743b0fbd6be26c7605e25d2e970fec2a9f912420f2f8d7d9076f5ab247412b0d
|
File details
Details for the file etool-2.1.0-py3-none-any.whl.
File metadata
- Download URL: etool-2.1.0-py3-none-any.whl
- Upload date:
- Size: 39.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1dd8b4e529b915e1d1b39bec7435d28da791eaaf5dcd5e19374bd9d9ee701af7
|
|
| MD5 |
3a12f39a03c2ee2c6164b57649322621
|
|
| BLAKE2b-256 |
f82494a30c54a2c4c2c78ad91c347ea4e302094c0c42d0af2ead1abe9472596b
|