asyncinotify
asyncinotify is a simple, optionally-async Python inotify library, focusing on ease of use and modern Python features. It provides a Pythonic interface to Linux's inotify API, built on `ctypes` without external dependencies. The library is actively maintained, currently at version 4.4.4, and supports Python 3.6 and newer. It offers both asynchronous (async/await) and synchronous modes of operation for file system event monitoring.
Common errors
-
ModuleNotFoundError: No module named 'asyncinotify'
cause The 'asyncinotify' package is not installed in the Python environment.fixInstall the package using pip: 'pip install asyncinotify'. -
ImportError: cannot import name 'AsyncInotify' from 'asyncinotify'
cause The module 'asyncinotify' does not contain a class or function named 'AsyncInotify'.fixEnsure you are importing the correct class or function from 'asyncinotify'. Refer to the official documentation for the correct import statements. -
AttributeError: module 'asyncinotify' has no attribute 'Inotify'
cause The 'Inotify' class is not present in the 'asyncinotify' module, possibly due to a version mismatch or incorrect installation.fixVerify that you have installed the correct version of 'asyncinotify' that includes the 'Inotify' class. Check the module's documentation for the correct usage. -
OSError: [Errno 2] No such file or directory
cause This error typically occurs when the path provided to `Inotify.add_watch()` does not exist on the filesystem.fixEnsure that the directory or file you are trying to watch with `inotify.add_watch()` exists before creating the watch. -
UserWarning: inotify is a Linux-only API. You can package this library on other platforms, but not run it.
cause The `asyncinotify` library, by default, uses Linux's `inotify` API, which is not available on other operating systems like macOS or Windows. While recent FreeBSD versions (15+) also support inotify, this warning indicates an attempt to run the library on an unsupported platform.fixRun your application on a Linux-based operating system. If using FreeBSD 15+, the warning might still appear but the functionality should be available.
Warnings
- gotcha When a watched directory or file is moved, the `Event.path` property associated with subsequent events for that watch may become incorrect. The library does not automatically update the watch path. To correctly track moved paths, users must monitor the parent directory for `Mask.MOVE_SELF` events and re-add/update watches as needed.
- gotcha The `Inotify` instance, when iterated asynchronously (`async for event in inotify:`), will yield events indefinitely (or until the inotify handle is closed). This is expected for continuous monitoring, but users must include their own logic (e.g., a `break` condition or `asyncio.wait_for`) to stop the iteration if only a finite number of events are expected or if the application needs to terminate.
- deprecated The library currently supports Python 3.6 and newer. However, the maintainers have stated that in a future version, Python support may be restricted to non-End-of-Life (EOL) versions if supporting older versions becomes inconvenient. Users should consider upgrading to actively supported Python versions to ensure future compatibility.
Install
-
pip install asyncinotify
Imports
- Inotify
from asyncinotify import Inotify
- Mask
from asyncinotify import Mask
Quickstart
import asyncio
import os
import tempfile
from pathlib import Path
from asyncinotify import Inotify, Mask
async def main():
# Create a temporary directory for watching
with tempfile.TemporaryDirectory() as tmpdir_name:
watch_path = Path(tmpdir_name)
print(f"Watching directory: {watch_path}")
with Inotify() as inotify:
# Add a watch for various events
inotify.add_watch(
watch_path,
Mask.ACCESS | Mask.MODIFY | Mask.OPEN | Mask.CREATE |
Mask.DELETE | Mask.ATTRIB | Mask.CLOSE | Mask.MOVE | Mask.ONLYDIR
)
print("Watch added. Creating a file in the directory...")
# Create a file to trigger events
test_file = watch_path / "test_file.txt"
test_file.write_text("hello")
await asyncio.sleep(0.1) # Give a moment for events to register
test_file.unlink()
await asyncio.sleep(0.1) # Give a moment for events to register
print("File operations completed. Collecting events...")
# Collect a few events. In a real application, you'd process them in a loop.
events_collected = 0
async for event in inotify:
print(f"Event: {event}")
events_collected += 1
# Break after a few events or based on application logic
if events_collected >= 3: # Adjust based on expected events
break
print("Finished collecting events.")
asyncio.run(main())