# Monitor directory changes
<subtitle>Listen to file system change events in the sandbox directory. </subtitle>

You can use the `files.watch_dir()` method to listen for directory changes.

> Since events are tracked asynchronously, their delivery may be delayed. It is recommended not to collect or close listeners immediately after making changes.

```python
from ucloud_sandbox import Sandbox, FilesystemEventType

sandbox = Sandbox.create()
dirname = '/home/user'

# Monitor directory changes
handle = sandbox.files.watch_dir(dirname)
# Trigger file write event
sandbox.files.write(f"{dirname}/my-file", "hello")

# Retrieve the latest events since the last `get_new_events()` call
events = handle.get_new_events()
for event in events:
  print(event)
  if event.type == FilesystemEventType.WRITE:
    print(f"wrote to file {event.name}")
```

## Recursive listening

You can enable recursive listening using the `recursive` parameter.

> When creating new folders quickly (for example, deeply nested folder paths), events other than `CREATE` may not be fired. To avoid this behavior, create the required folder structure in advance.

```python
from ucloud_sandbox import Sandbox, FilesystemEventType

sandbox = Sandbox.create()
dirname = '/home/user'

# Monitor directory changes
handle = sandbox.files.watch_dir(dirname, recursive=True)
# Trigger file write event
sandbox.files.write(f"{dirname}/my-folder/my-file", "hello")

# Retrieve the latest events since the last `get_new_events()` call
events = handle.get_new_events()
for event in events:
  print(event)
  if event.type == FilesystemEventType.WRITE:
    print(f"wrote to file {event.name}")
```

## Contains entry information

You can use the `include_entry` parameter to include information about the affected files or directories in each event. When enabled, each event carries the entry's information—such as its path, type, and size—in the `entry` field.

> For delete events, the entry information may not be set because the path no longer exists. Templates containing entry information require envd version `v0.6.3` or higher - using the `include_entry` option on older sandboxes will throw an error.

```python
from ucloud_sandbox import Sandbox

sandbox = Sandbox.create()
dirname = '/home/user'

# Monitor directory changes
handle = sandbox.files.watch_dir(dirname, include_entry=True)
# Trigger file write event
sandbox.files.write(f"{dirname}/my-file", "hello")

# Retrieve the latest events since the last `get_new_events()` call
events = handle.get_new_events()
for event in events:
  print(event.type, event.name, event.entry.path if event.entry else None)
```

## Monitor network file system mounts

By default, paths on listening network file system mounts (NFS, CIFS, SMB, FUSE) are rejected. You can explicitly select enable using the `allow_network_mounts` parameter.

> Events on network mounts may be unreliable or not delivered at all, which is why explicit opt-in is required.
>
> Changes made from another client outside the sandbox (e.g. another machine writing to the same network share) are not propagated to the listener - only changes made from within the sandbox will be detected.

> Listening to network mounts requires envd version `v0.6.4` or higher template - using the `allow_network_mounts` option on older sandboxes will throw an error.

```python
from ucloud_sandbox import Sandbox

sandbox = Sandbox.create()
dirname = '/mnt/nfs-share/my-dir'

# Monitor directory changes on network mounts
handle = sandbox.files.watch_dir(dirname, allow_network_mounts=True)
# Trigger file write event
sandbox.files.write(f"{dirname}/my-file", "hello")

# Retrieve the latest events since the last `get_new_events()` call
events = handle.get_new_events()
for event in events:
  print(event.type, event.name)
```
