pyfileops is a simple, friendly Python library for everyday file and directory operations.
No need to juggle os, shutil, pathlib, or zipfile — everything lives behind one clean object: fs.
from pyfileops import fs
fs.copy("report.pdf", "backup/")
fs.delete("temp.log")
print(fs.size("video.mp4"))pip install pyfileopsRequires Python 3.8+. No external dependencies — only the standard library.
from pyfileops import fs
# ── Files ──────────────────────────────────────────────────────────────
fs.copy("notes.txt", "backup/") # copy into an existing folder
fs.copy("notes.txt", "backup/notes2.txt") # copy with a new name
fs.cut("draft.docx", "archive/") # move file
fs.rename("old.txt", "new.txt") # rename in place
fs.delete("trash.log") # delete a file
# ── Directories ────────────────────────────────────────────────────────
fs.mkdir("project/src/utils") # create (nested) directories
fs.rmdir("tmp") # remove directory and contents
# ── Compression ────────────────────────────────────────────────────────
fs.zip("project", "project_v1.zip") # zip a directory
fs.zip("report.pdf", "report.zip") # zip a single file
fs.unzip("project_v1.zip", "restored/") # extract a zip
# ── Queries ────────────────────────────────────────────────────────────
fs.exists("config.ini") # True or False
fs.size("video.mp4") # size in bytes (int)
fs.is_file("data.csv") # True or False
fs.is_dir("assets") # True or FalseCopies a file or directory to destination.
- If
destinationis an existing directory, the source is placed inside it. - If
destinationdoes not exist, it becomes the new file/folder name. - Missing intermediate directories are created automatically.
fs.copy("logo.png", "assets/") # → assets/logo.png
fs.copy("logo.png", "assets/icon.png") # → assets/icon.png
fs.copy("src/", "src_backup/") # copies whole directory treeMoves a file or directory to destination (copy + delete original).
fs.cut("uploads/photo.jpg", "gallery/")Renames a file or directory in place (same parent directory).
To move to a different location, use cut().
fs.rename("report_draft.pdf", "report_final.pdf")Deletes a file or an entire directory tree.
fs.delete("temp.log") # file
fs.delete("cache/") # directory and all its contentsCreates a directory (and any missing parent directories). Safe to call even if it already exists.
fs.mkdir("project/assets/images")Removes a directory and everything inside it.
fs.rmdir("build/")Compresses source (file or directory) into a ZIP archive at zip_file.
fs.zip("my_project", "my_project.zip")
fs.zip("data.csv", "data.zip")Extracts a ZIP archive into destination.
fs.unzip("my_project.zip", "restored/")Returns True if path exists (file or directory).
if fs.exists("config.ini"):
print("Config found!")Returns the size in bytes.
- For files: the file size.
- For directories: the total size of all contained files.
bytes_used = fs.size("video.mp4")
print(f"{bytes_used / 1_000_000:.2f} MB")Returns True if path is a regular file (returns False if it doesn't exist).
fs.is_file("README.md") # True
fs.is_file("src/") # FalseReturns True if path is a directory (returns False if it doesn't exist).
fs.is_dir("src/") # True
fs.is_dir("README.md") # Falsepyfileops raises clear, specific exceptions so you always know what went wrong.
| Exception | When it's raised |
|---|---|
FileOpsError |
Base class for all pyfileops errors |
PathNotFoundError |
Source path does not exist |
CopyError |
A copy or move operation failed |
DeleteError |
A delete operation failed |
ZipError |
A zip or unzip operation failed |
All exceptions inherit from FileOpsError, which inherits from Exception.
from pyfileops import fs
from pyfileops import PathNotFoundError, CopyError, ZipError, FileOpsError
# Catch a specific error
try:
fs.copy("missing.txt", "backup/")
except PathNotFoundError as e:
print(e) # Path not found: 'missing.txt'
# Catch any pyfileops error
try:
fs.zip("project", "output.zip")
fs.delete("tmp/")
except FileOpsError as e:
print(f"Operation failed: {e}")Made by Fede · github.com/FefinDev/pyfileops