• Stars
    star
    173
  • Rank 220,124 (Top 5 %)
  • Language
    Python
  • License
    Apache License 2.0
  • Created over 4 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A pythonic, asynchronous, inotify interface

Minotaur: A pythonic, asynchronous, inotify interface

PyPI version

Examples

Minotaur provides the Inotify class which is to be used as a context manager, from within which, one may iterate over inotify events:

    with Inotify() as n:
        n.add_watch('.', Mask.CREATE | Mask.DELETE | Mask.MOVE)
        for evt in n:
            print(evt)

The asynchronous interface works almost identically. The inotify object must be created in nonblocking mode, and then the mere addition of the async keyword to the iteration over events is all that's required:

    with Inotify(blocking=False) as n:
        n.add_watch('.', Mask.CREATE | Mask.DELETE | Mask.MOVE)
        async for evt in n:
            print(evt)

Example output would look like this:

Event(wd=1, mask=<Mask.CREATE: 256>, cookie=0, name=PosixPath('foo'))
Event(wd=1, mask=<Mask.CREATE: 256>, cookie=0, name=PosixPath('bar'))
Event(wd=1, mask=<Mask.MOVED_FROM: 64>, cookie=129399, name=PosixPath('foo'))
Event(wd=1, mask=<Mask.MOVED_TO: 128>, cookie=129399, name=PosixPath('baz'))
Event(wd=1, mask=<Mask.DELETE: 512>, cookie=0, name=PosixPath('bar'))
Event(wd=1, mask=<Mask.DELETE: 512>, cookie=0, name=PosixPath('baz'))

There is also a command-line tool demonstrating the features

$ python -m minotaur --help

usage: minotaur [-h] [--async | --sync] [--fancy] [--mask MASK] dir [dir ...]

Minotaur: A pythonic, asynchronous, inotify interface.

A summary of inotify watch flags:
 - ACCESS: File was accessed
 - ATTRIB: Metaata changed, eg. permissions
 - CLOSE_WRITE: File for writing was closed
 - CLOSE_NOWRITE: File or dir not opened for writing was closed
 - CREATE: File/dir was created
 - DELETE: File or dir was deleted
 - DELETE_SELF: Watched file/dir was itself deleted
 - MODIFY: File was modified
 - MOVE_SELF: Watched file/dir was itself moved
 - MOVED_FROM: Generated for dir containing old filename when a file is renamed
 - MOVED_TO: Generated for dir containing new filename when a file is renamed
 - OPEN: File or dir was opened
 - MOVE: MOVED_FROM | MOVED_TO
 - CLOSE: IN_CLOSE_WRITE | IN_CLOSE_NOWRITE
 - DONT_FOLLOW: Don't dereference pathname if it is a symbolic link
 - EXCL_UNLINK: Don't generate events after files have been unlinked
 - ONESHOT: Only generate one event for this watch
 - ONLYDIR: Watch pathname only if it is a dir
 - MASK_CREATE: Only watch path if it isn't already being watched

positional arguments:
  dir                   Watch for events in given dir

optional arguments:
  -h, --help            show this help message and exit
  --async, -a           Use asyncio event loop
  --sync, -s            Use synchronous interface
  --fancy, -f           Use fancy interface
  --mask MASK, -m MASK  Events to watch for

What is different about Minotaur?

  1. C interface provides basic wrapper to syscalls and constants. In future, if performance becomes a problem, more functionality can be gradually moved there.

  2. Pythonic. IntFlags is used for watch types. Context-managers take care of fd lifetime, close() method is idempotent. Raw read() and readall() methods work comparably to python standard io objects. Full support for mypy, including typeshed for C interface. Iterator and async-iterator protocols supported.

  3. Makes no assumptions about the name encoding of filesystems, ie. with os.fsencode() and os.fsdecode()

  4. Async interface supports multiple concurrent waiters. Waiting tasks are woken in a first-come, first-serve manner.

  5. Users can choose between different levels of support:

    1. Raw syscall interface
    2. Low-level inotify object, which takes care of path encoding, reading of raw inotify data, parsing of binary events in to python objects, and provides both synchronous and async interface. But is still low-level because it does no special handling of watches or combining of related events (eg.MOVE_FROM / MOVE_TO).
    3. Fancy high-level interfaces, in pure python, built on top of low-level interface.

What is missing

There is no attempt to abstract file-notification functionality offered by other operating systems in to a cross-platform interface.

There are no tests.

Development

You should use the provided pre-commit hooks to make sure code type-checks and is PEP-8 formatted:

ln -sf ../../pre-commit.sh .git/hooks/pre-commit

Why another one?

There are several other python inotify packages. So why does this one exist? Well, this can perhaps be explained best by referring to some of the others:

  1. PyInotify: suffers from numerous bugs. The fd closes aren't idempotent, this can lead to closing unrelated file descriptors. This would be less of an issue if the fd had a clear ownership and lifetime, or used context managers. In other words, it's difficult to use safely.

  2. PyInotify: Assumes utf-8 filesystem encoding. No asyncio interface.

  3. inotify_simple: Nicely subclasses FileIO, but that precludes asyncio since FileIO is meant for blocking I/O on files and cannot be easily adapted for other purposes.

  4. python_inotify: No asyncio interface and, it would need to be added in the C code, or if added in python code would duplicate the C code and work differently, thus being a new API.

  5. python-inotify: It's packaged by RedHat but, similarly to python_inotify the read() syscall is done in the C extension so it doesn't support asyncio, and can't easily be adapted to do so without changing the interface or duplicating functionality.

  6. asyncinotify: Easily the best of the bunch. The main downside is that it doesn't provide a synchronous interface or low-level interfaces.

The others seem to be parts of larger projects, or systems.

More Repositories

1

ccid-utils

A USB smartcard driver including GSM SIM and EMV credit/debit card development platforms
C
77
star
2

scaraOS

A 32bit multiboot OS kernel for IA32 (PC/AT) systems.
C
30
star
3

resynth

A network packet synthesis language
Rust
26
star
4

cola

Cache Oblivious Lookahead Arrays
C
25
star
5

punani-strike

A desert strike clone, in 3d
C
11
star
6

firestorm

Firestorm is an experimental 'next generation' intrusion detection system
C
10
star
7

project-mayhem

Streamate/Webcam mayhem native client
C
7
star
8

ashttpd

Fast(er|est) HTTP daemon originally used as async-sendfile testbed
C
6
star
9

xpdt

eXPeditious Data Transfer
Python
4
star
10

primula

A simple circuit simulator
Python
4
star
11

pylr

A compiler-compiler for lexers, LL and LALR grammars, written in python
Python
4
star
12

kapital

A python/cairo monopoly client and bot
Python
3
star
13

funky

Alternative client for PowerGrid on BrettSpielWelt
Python
3
star
14

pyelf

Python wrapper for libelf
Python
3
star
15

chanirc

experimental irc client with inline web image display etc..
Python
3
star
16

giannitedesco.github.com

tech blog/pages
HTML
3
star
17

acgtools

A driver for ACG HF MultiISO RFID reader
Python
3
star
18

ondawagon

Userland driver for ZTE/Onda 3G USB dongles sold by vodafone
C
3
star
19

wabs

Reverse engineered Worms Armageddon bot.
C
2
star
20

spu-kit

A SNES SPU emulator
C
2
star
21

libmc

C library for fuxxing with minecraft worlds
C
2
star
22

blackbloc

toy 3d game engine in opengl
C
2
star
23

krsite

Korean language learning website
HTML
2
star
24

eric

E.R.I.C: Efficient Redstone Instruction Computer - emulator and assembler
C
2
star
25

autober

An application specific language with a compiler for generating BER decoders in C
Python
2
star
26

ircnukes

An online zero-sum game which blends strategic thinking and unthinking brutality set in the current, possibly terminal, era of human existence
Python
2
star
27

bmo

Burrows-Wheeler, move to front, Elias omega coding based lossless compression
C
1
star
28

giannitedesco

1
star
29

gordon

vocabulary flash-cards for Korean/English (or any language pair, really), in gtk
Python
1
star
30

hieros

A legacy-free x86-64 kernel
C
1
star
31

plinn

Partition Like It's 1999
Python
1
star