Python File Organizer Project

Python project 04

Python File Organizer Project

Build a Python utility that sorts files into folders such as Images, Documents, Audio, Videos, Archives, and Code. It is a practical way to learn file paths, extensions, folders, and safe handling of name conflicts while solving a real everyday problem.

Practise Python automation with mentorsView all project ideas

What you will build

The program asks for a folder path, inspects the files directly inside it, and moves each file into a category subfolder. For example, a PDF moves to Documents and a PNG moves to Images. It never overwrites an existing file: it creates a numbered name instead.

Skills practised

  • Pathlib and file paths
  • File extensions
  • Folders and iteration
  • Safe file moves

Requirements

  • Python 3.8 or later
  • A test folder with copies of files
  • No external libraries
  • About 30 minutes to build

Full Python code

Save this file as file_organizer.py. Test it first with a new folder containing copies of a few files. The program moves files, so starting with a safe practice folder is the right habit before using it on an important Downloads or Documents folder.

from pathlib import Path
import shutil


CATEGORIES = {
    "Images": {".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"},
    "Documents": {".pdf", ".doc", ".docx", ".txt", ".xlsx", ".csv", ".pptx"},
    "Audio": {".mp3", ".wav", ".m4a"},
    "Videos": {".mp4", ".mkv", ".avi", ".mov"},
    "Archives": {".zip", ".rar", ".7z", ".tar", ".gz"},
    "Code": {".py", ".js", ".html", ".css", ".java", ".json"},
}


def category_for(file_path):
    """Return the destination category for a file extension."""
    suffix = file_path.suffix.lower()
    for category, extensions in CATEGORIES.items():
        if suffix in extensions:
            return category
    return "Other"


def available_destination(destination):
    """Avoid overwriting a file that already exists in the destination folder."""
    if not destination.exists():
        return destination

    counter = 1
    while True:
        candidate = destination.with_name(
            f"{destination.stem}_{counter}{destination.suffix}"
        )
        if not candidate.exists():
            return candidate
        counter += 1


def organize_files(folder):
    """Move files in one folder into category subfolders and return a summary."""
    source = Path(folder).expanduser().resolve()
    if not source.is_dir():
        raise NotADirectoryError(f"Folder not found: {source}")

    moved = []
    for item in source.iterdir():
        if not item.is_file():
            continue

        category = category_for(item)
        destination_folder = source / category
        destination_folder.mkdir(exist_ok=True)
        destination = available_destination(destination_folder / item.name)
        shutil.move(str(item), str(destination))
        moved.append((item.name, category))

    return moved


def main():
    print("Python File Organizer")
    print("This moves files in the selected folder into category subfolders.")
    folder = input("Folder path to organise: ").strip()

    try:
        moved = organize_files(folder)
    except (NotADirectoryError, PermissionError, OSError) as error:
        print(f"Could not organise files: {error}")
        return

    if not moved:
        print("No files found to organise.")
        return

    print("\nMoved files:")
    for filename, category in moved:
        print(f"- {filename} -> {category}/")
    print(f"\nFinished. Organised {len(moved)} file(s).")


if __name__ == "__main__":
    main()

How the organizer works

Path(folder).expanduser().resolve() turns the path typed by the user into a complete path that Python can work with. Before moving anything, the code checks that this path is a real directory.

category_for() looks at a file’s extension and returns a matching category. The CATEGORIES dictionary makes the rules easy to read and change. If an extension is not listed, the file goes to Other instead of being ignored.

Before a move, available_destination() checks whether a file with the same name already exists in the destination folder. When it does, the function tries names such as report_1.pdf. This prevents accidental overwrites and is an important safety detail in any file-management tool.

Run the project

  1. Create a small test folder and put copies of a few files inside it.
  2. Open a terminal and run python file_organizer.py, or py file_organizer.py.
  3. Paste the path to the test folder when asked.
  4. Open the folder afterwards and check the new category subfolders.
Python File Organizer
This moves files in the selected folder into category subfolders.
Folder path to organise: C:\PracticeFiles

Moved files:
- photo.JPG -> Images/
- report.pdf -> Documents/
- script.py -> Code/

Finished. Organised 3 file(s).

Notes for your notebook

  • Pathlib: pathlib.Path is a readable, cross-platform way to work with file and folder paths.
  • Case handling: converting extensions to lowercase means photo.JPG is treated like photo.jpg.
  • Safety: test with copied files first. Any tool that moves files should be used carefully.
  • Name conflicts: avoid overwriting existing files unless that is an explicit, confirmed requirement.

Ways to extend this project

Add a dry-run mode that only previews the changes, create an undo log, organise nested folders, or build a drag-and-drop interface with Tkinter. Later, save an activity log to a CSV or JSON file using the Python file handling guide.

Where to take your file organizer next

Use the same file skills to add a saved history to the Python To-Do List Application, or revisit the Simple Calculator Project to see how validation can stay focused and readable. When you want another practical challenge, return to the project ideas library. For structured project work and feedback, explore the Python course in Vizag.