Extension module for lucent that monitors file system events related to a Codex.
Project description
Lucent Watcher
lucent_watcher is an extension module for lucent that monitors filesystem events relevant to a Codex.
A watcher monitors directories and triggers callbacks when files matching specific Conventions are created, deleted, or moved.
Requirements
- Python >= 3.9
Note: The new type annotation syntax was introduced in Python 3.9 (PEP 585), and while there is no plan for removal at the moment, using modern annotations is more future-proof.
Installation
Use your preferred package installer:
pip install lucent-watcher
uv add lucent-watcher
poetry add lucent-watcher
To try it quickly, lucent-watcher provides an example configuration for testing purposes:
from lucent_watcher.lucent_watcher_example import main
main()
Step-by-Step Explanation
1. Define directories to monitor
Start by creating a list of directories that the Watcher should monitor.
dirs = [Path("D:/monitor_me")]
You can also dynamically build paths using your Conventions:
project_root = Path(
codex.convs.project_root.format(
{"project": "myAwesomeProject"}
)
)
dirs.append(project_root)
Recursive Monitoring
Directory monitoring is recursive. Therefore, adding subfolders explicitly is unnecessary and duplicate child directories will be ignored
# This path will be ignored if `"D:/monitor_me"` is already monitored.
dirs.append(Path("D:/monitor_me/subfolder"))
2. Create the Watcher
Once directories are defined, create a Watcher. The Codex passed as argument determines which file patterns specifically need to be monitored. Files that do not match known conventions are ignored.
watcher = Watcher(
codex=codex,
watch_dirs=dirs
)
3. Create a WatcherProtocol
A WatcherProtocol defines what event to watch and what to execute when an event occurs. This example will run a custom callback when a Maya file is created.
def created_asset_maya_file(
path: Path,
convention: Convention,
fields: dict[str, str]
):
print("Asset Maya file created")
print(f"- Path : {path}")
print(f"- Convention : {convention}")
print(f"- Fields : {fields}")
protocol = WatcherProtocol(
codex.convs.asset_maya_file,
on_created=created_asset_maya_file
)
watcher.register(protocol)
Supported Events
A WatcherProtocol can handle three types of events:
- Creation
- Deletion
- Move / Rename
Note that the "on_moved" callback has more arguments, because it needs to handle both the source and destination.
def deleted_asset_maya_file(
path: Path,
convention: Convention,
fields: dict[str, str]
):
print(f"The file {path.name} was deleted")
def moved_asset_maya_file(
src: Path,
dst: Path,
src_convention: Convention,
dst_convention: Convention,
src_fields: dict[str, str],
dst_fields: dict[str, str],
):
print(f"The file {src.name} was moved to {dst}")
protocol = WatcherProtocol(
codex.convs.asset_maya_file,
on_created=created_asset_maya_file,
on_deleted=deleted_asset_maya_file,
on_moved=moved_asset_maya_file,
)
watcher.register(protocol)
Note: Moving/renaming files
Conceptually, moving a file is equivalent to deleting it and creating it elsewhere.
If the "on_moved" callback is not defined, the "on_created" and "on_deleted" callbacks will be triggered instead.
Define on_moved when:
- You need precise control over rename/move operations
- You want to avoid duplicate logic from create/delete events
6. Start the Watcher
We are all set! Finally, start the watcher to begin monitoring directories.
watcher.start()
This begins the file monitoring loop, the watcher will continue running until the program exits. You may also set blocking=False if your watcher runs in a gui or something.
Full code
"""
This script demonstrates how to set up a Lucent Watcher service.
"""
import logging
from pathlib import Path
from lucent.lucent_example_config import Convention, codex
from lucent_watcher import Watcher, WatcherProtocol
def main():
# Directories to monitor
dirs = [Path("D:/monitor_me")]
project_root = Path(codex.convs.project_root.format({"project": "myAwesomeProject"}))
dirs.append(project_root)
# Watcher
watcher = Watcher(codex=codex, watch_dirs=dirs)
# Callbacks
def created_asset_maya_file(path: Path, convention: Convention, fields: dict[str, str]):
print("Asset Maya file created")
print(f"- Path : {path}")
print(f"- Convention : {convention}")
print(f"- Fields : {fields}")
def deleted_asset_maya_file(path: Path, convention: Convention, fields: dict[str, str]):
print(f"The file {path.name} was deleted")
def moved_asset_maya_file(
src: Path,
dst: Path,
src_convention: Convention,
dst_convention: Convention,
src_fields: dict[str, str],
dst_fields: dict[str, str],
):
print(f"The file {src.name} was moved to {dst}")
print(f"{src_convention.name} -> {dst_convention.name}")
print(src_fields)
print(dst_fields)
# WatcherProtocols
protocol = WatcherProtocol(
codex.convs.asset_maya_file,
on_created=created_asset_maya_file,
on_deleted=deleted_asset_maya_file,
on_moved=moved_asset_maya_file,
)
watcher.register(protocol)
# Start Watcher
watcher.start()
def _main():
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)-4s %(message)s",
datefmt="%Y-%m-%dT%H:%M:%S",
)
main()
if __name__ == "__main__":
_main()
Acknowledgements
- Big Company: while being a personal project, Lucent was tested and improved there, so shoutout to the team!
- Lucidity team: The years I've spent working with Lucidity were a great inspiration for Lucent.
- The VFX/Animation community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lucent_watcher-0.0.1.tar.gz.
File metadata
- Download URL: lucent_watcher-0.0.1.tar.gz
- Upload date:
- Size: 14.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d98a4a08a739eb68e88fed529b4f77e6dd64220f696b9eeeb7b33f0b37ad17c
|
|
| MD5 |
5bc5ec49668e5bcd7e971b0bb8d18907
|
|
| BLAKE2b-256 |
c613c7bd3a19705ac38554099d566b0e6aa46714823fd0176c9c24a58f4a8131
|
File details
Details for the file lucent_watcher-0.0.1-py3-none-any.whl.
File metadata
- Download URL: lucent_watcher-0.0.1-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a029e6f2625de0ae21f27f9370db1d145e70a85d27b3edb878e20da5d4a8c685
|
|
| MD5 |
c0f272dbcd4de3f0ce983ac26a3f15ad
|
|
| BLAKE2b-256 |
a70aa3a81d5a94121f470ff21dbc49c72bfb710c1d5d1102cbc024272f8b6b61
|