PyObjC FSEvents Framework

12.1 · active · verified Tue Apr 14

This library provides Python wrappers for the macOS FSEvents framework, allowing applications to monitor file system events efficiently. It is part of the larger PyObjC project, which bridges Python and the Objective-C runtime on macOS. The project follows macOS SDK updates closely, often releasing new versions with each major OS release, and is currently at version 12.1.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `pyobjc-framework-fsevents` to monitor a specified directory for file system events. It sets up an `FSEventStream` with a Python callback function and schedules it on the current thread's `CFRunLoop`. It will monitor for 30 seconds or until a `KeyboardInterrupt` occurs. Remember that `pyobjc-framework-fsevents` is macOS-specific.

import objc
from FSEvents import (
    FSEventStreamCreate,
    FSEventStreamScheduleWithRunLoop,
    FSEventStreamStart,
    FSEventStreamStop,
    FSEventStreamRelease,
    kFSEventStreamEventFlagNone,
    kFSEventStreamEventFlagFileEvents,
    kFSEventStreamCreateFlagUseCFTypes
)
from Foundation import CFRunLoopGetCurrent, CFRunLoopRunInMode, kCFRunLoopDefaultMode, CFRunLoopStop

def my_callback(streamRef, clientCallBackInfo, numEvents, eventPaths, eventFlags, eventIds):
    print(f"Detected {numEvents} events:")
    for i in range(numEvents):
        path = eventPaths[i]
        flags = eventFlags[i]
        print(f"  Path: {path}, Flags: {flags}")


path_to_monitor = "./temp_monitor_dir" # Change to a directory you want to monitor
import os
if not os.path.exists(path_to_monitor):
    os.makedirs(path_to_monitor)


cb = objc.selector(my_callback, signature='v@iiii@*Q')

stream = FSEventStreamCreate(
    None, # allocator
    cb, # callback
    None, # context
    [path_to_monitor], # pathsToWatch (array of CFStringRef)
    0, # sinceWhen
    1.0, # latency
    kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamEventFlagFileEvents # flags
)

if stream is None:
    print("Failed to create FSEventStream")
else:
    print(f"Monitoring '{path_to_monitor}' for file system events. Press Ctrl+C to stop...")
    runLoop = CFRunLoopGetCurrent()
    FSEventStreamScheduleWithRunLoop(stream, runLoop, kCFRunLoopDefaultMode)
    FSEventStreamStart(stream)

    try:
        # Run the run loop for a short period, or forever for continuous monitoring
        # For this example, we'll run for a fixed time or until stopped by user
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 30.0, False) # Run for 30 seconds
    except KeyboardInterrupt:
        print("\nStopping monitoring...")
    finally:
        FSEventStreamStop(stream)
        FSEventStreamRelease(stream)
        CFRunLoopStop(runLoop)
        print("FSEventStream stopped and released.")


# Clean up the temporary directory if created by this script
# if os.path.exists(path_to_monitor):
#     os.rmdir(path_to_monitor)

view raw JSON →