Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

lucent_watcher-0.0.1.tar.gz (14.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

lucent_watcher-0.0.1-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

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

Hashes for lucent_watcher-0.0.1.tar.gz
Algorithm Hash digest
SHA256 1d98a4a08a739eb68e88fed529b4f77e6dd64220f696b9eeeb7b33f0b37ad17c
MD5 5bc5ec49668e5bcd7e971b0bb8d18907
BLAKE2b-256 c613c7bd3a19705ac38554099d566b0e6aa46714823fd0176c9c24a58f4a8131

See more details on using hashes here.

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

Hashes for lucent_watcher-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a029e6f2625de0ae21f27f9370db1d145e70a85d27b3edb878e20da5d4a8c685
MD5 c0f272dbcd4de3f0ce983ac26a3f15ad
BLAKE2b-256 a70aa3a81d5a94121f470ff21dbc49c72bfb710c1d5d1102cbc024272f8b6b61

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page