DEV Community

qing
qing

Posted on

Build a File Sync Tool with Python and Watchdog

Build a File Sync Tool with Python and Watchdog

Build a File Sync Tool with Python and Watchdog

Imagine you’re working on a project where you constantly edit files in one folder, but you need those changes instantly reflected in another location—maybe a backup drive, a cloud staging folder, or a deployment directory. Doing this manually is tedious, and relying on cron jobs introduces lag. What if you could build a tool that watches for changes and syncs them in real time? That’s exactly what we’re going to do today using Python and the powerful watchdog library.

Why Watchdog?

watchdog is a cross-platform Python library that lets you monitor file system events—like file creation, modification, and deletion—and trigger custom actions in response [1][8]. Unlike polling-based solutions, it’s event-driven, meaning it reacts immediately when a change happens. This makes it perfect for building real-time sync tools, automated testers, or even live documentation generators.

What You’ll Build

By the end of this post, you’ll have a working file sync tool that:

  • Watches a source directory for changes
  • Automatically copies new or modified files to a destination directory
  • Deletes files in the destination if they’re removed from the source
  • Runs continuously without blocking your main workflow

And yes, you can use this today to automate your own workflows.

Step 1: Set Up Your Environment

First, make sure you have Python 3 installed. Then, install watchdog:

pip install watchdog
Enter fullscreen mode Exit fullscreen mode

You’ll also need Python’s built-in os and shutil modules for file operations, so no extra installs there [2][4].

Create a project folder and set up two directories: one for your source files and one for the synced destination.

mkdir file_sync_demo
cd file_sync_demo
mkdir source destination
Enter fullscreen mode Exit fullscreen mode

Step 2: Build the Event Handler

The core of watchdog is the event handler—a class that defines what to do when specific file system events occur. We’ll create a custom handler that inherits from FileSystemEventHandler and overrides methods like on_created, on_modified, and on_deleted.

Here’s the full working code:

import os
import shutil
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class SyncHandler(FileSystemEventHandler):
    def __init__(self, source_dir, dest_dir):
        self.source_dir = source_dir
        self.dest_dir = dest_dir

    def on_created(self, event):
        if event.is_directory:
            return
        self.sync_file(event.src_path)

    def on_modified(self, event):
        if event.is_directory:
            return
        self.sync_file(event.src_path)

    def on_deleted(self, event):
        if event.is_directory:
            return
        dest_path = os.path.join(self.dest_dir, os.path.basename(event.src_path))
        if os.path.exists(dest_path):
            os.remove(dest_path)
            print(f"Deleted: {dest_path}")

    def sync_file(self, src_path):
        filename = os.path.basename(src_path)
        dest_path = os.path.join(self.dest_dir, filename)
        shutil.copy2(src_path, dest_path)
        print(f"Synced: {filename}")

if __name__ == "__main__":
    source = "source"
    destination = "destination"

    handler = SyncHandler(source, destination)
    observer = Observer()
    observer.schedule(handler, source, recursive=False)
    observer.start()

    print(f"Watching '{source}' for changes. Syncing to '{destination}'...")
    try:
        while True:
            pass
    except KeyboardInterrupt:
        observer.stop()
    observer.join()
Enter fullscreen mode Exit fullscreen mode

Save this as sync.py in your project folder [2][8].

Step 3: How It Works

Let’s break down the key parts:

  • SyncHandler: Our custom event handler. It stores the source and destination paths and defines behavior for each event type.
  • on_created / on_modified: Both trigger the same sync_file method, which copies the file using shutil.copy2 (this preserves metadata like timestamps).
  • on_deleted: Removes the corresponding file from the destination if it exists.
  • Observer: The engine that watches the directory. We schedule it to watch the source folder with recursive=False to avoid watching subdirectories [3][7].
  • observer.start(): Begins monitoring in a background thread, so your script doesn’t block [7].

Step 4: Test It Out

Now, let’s see it in action.

  1. Run the script:
   python sync.py
Enter fullscreen mode Exit fullscreen mode
  1. In another terminal, navigate to the source folder and create a file:
   cd source
   echo "Hello, sync!" > test.txt
Enter fullscreen mode Exit fullscreen mode
  1. Watch the output: you should see Synced: test.txt.
  2. Check the destination folder—you’ll find test.txt there, identical to the source.

Try editing test.txt, moving it, or deleting it. The tool will react instantly [2].

Practical Tips & Enhancements

This is a minimal but functional sync tool. Here are a few ways to level it up:

  • Filter by file type: Add a patterns argument to observer.schedule() to watch only .txt or .py files [9].
  • Add logging: Use Python’s logging module instead of print() for production-ready output [4].
  • Handle race conditions: If a file is being written, on_modified might fire multiple times. You can add a small delay or check file size stability before syncing.
  • Make it recursive: Set recursive=True in schedule() if you want to sync subdirectories too [3].
  • Add CLI args: Use argparse to let users specify source/dest paths at runtime [1].

Why This Matters

Real-time file sync isn’t just convenient—it’s essential for modern development workflows. Whether you’re syncing config files to a server, mirroring assets for a website, or backing up critical data, having a lightweight, scriptable tool gives you full control without relying on third-party services.

And because it’s built in Python, you can extend it endlessly: add email notifications, integrate with cloud APIs, or even turn it into a web service.

Your Turn

Grab the code above, run it, and tweak it for your own needs. Try syncing a folder of your project files, or automate a backup for your documents. Once you see it working, you’ll never go back to manual copying.

If you build something cool with this, share it on Dev.to or tag me in your post. And if you hit any bugs or have ideas for improvements, drop a comment—let’s keep building better tools together.

Ready to sync? Run python sync.py and watch your files move in real time.


If you found this helpful, consider buying me a coffee ☕ — it keeps these articles coming!

Also check out my AI tools collection: AI 次元世界 — free AI tools for developers.


💡 Related: **Content Creator Ultimate Bundle (Save 33%)* — $29.99*

Top comments (0)