Theme
Version
GitHub PyPI Discord
On this page

Hot reload

The citry.reload module, which watches component files and reloads them in place while you develop (see the hot reload guide).

View source

watch function

watch(engine: Citry, roots: Iterable[str | Path] | None = None, watcher: FileWatcher | None = None, on_reload: Callable[[set[Path], list[type[Component]]], None] | None = None) -> WatchHandle

Watch component files and reload them in place when they change.

For each changed file, the watcher calls Citry.invalidate_file(), so the next render reads the new template, JavaScript or CSS. The watcher runs on a background daemon thread, so watch() returns at once, and the watcher stops when your program exits. Call wait() on the returned handle to keep a script running.

A change to a file no component has loaded yet does nothing, because nothing is cached for it. A new component file or a change to Python code needs a restart, which your web framework's own reloader does.

Example

from citry.reload import watch
from myapp import engine

handle = watch(engine)
try:
    handle.wait()
except KeyboardInterrupt:
    handle.stop()

Parameters

Returns

WatchHandle: A [`WatchHandle`](/reference/hot-reload/#citry-reload-watchhandle). Call its `stop()` to

Raises

  • ValueError - When none of the directories to watch exists.
View source

WatchHandle class

A running watcher, returned by watch().

Call stop() to end it, or wait() to block until it stops. The citry watch command calls wait(), then stop() when you press Ctrl-C.

View source

running attribute

running: bool

Whether the watcher thread is still alive.

View source

wait function

wait() -> None

Block the calling thread until the watcher stops.

Polls with a short timeout so a KeyboardInterrupt on the main thread is delivered promptly rather than swallowed by an un-timed join.

View source

stop function

stop(timeout: float = _DEFAULT_STOP_TIMEOUT) -> None

Ask the watcher to stop and wait up to timeout for its thread.

View source

FileWatcher class

Bases: Protocol

The interface a file-watching backend implements.

Citry calls run() on a background thread. run() blocks and calls on_change with the set of changed paths for each batch of changes, until another thread calls stop(). A backend should group the burst of events one editor save produces into as few on_change calls as it can, and must return from run() soon after stop() is called.

Citry ships three backends: WatchfilesWatcher, WatchdogWatcher and PollingWatcher. To use your own, pass an object with these two methods as watcher= to watch() or reload_lifespan().

View source

run function

run(roots: Sequence[Path], on_change: Callable[[set[Path]], None]) -> None

Watch roots and call on_change per batch until stopped.

View source

stop function

stop() -> None

Ask run to return. Safe to call from another thread.

View source

WatchfilesWatcher class

Watch files with the watchfiles package, the recommended backend.

watchfiles listens to your operating system's file-change events. It needs the watcher-watchfiles extra (pip install "citry[watcher-watchfiles]"). Citry imports watchfiles only when the watcher starts, so you can create this class without the extra installed.

Parameters

  • force_polling bool - Check the directories on a timer instead of using operating system events, for example on a network drive that sends no events.
View source

run function

run(roots: Sequence[Path], on_change: Callable[[set[Path]], None]) -> None

Stream watchfiles change batches into on_change.

View source

stop function

stop() -> None

Signal the watchfiles loop (it watches self._stop).

View source

WatchdogWatcher class

Watch files with the watchdog package.

Use it in a project that already depends on watchdog; otherwise prefer WatchfilesWatcher. It needs the watcher-watchdog extra (pip install "citry[watcher-watchdog]"). Citry imports watchdog only when the watcher starts, so you can create this class without the extra installed.

watchdog reports one change at a time, so one save can make Citry drop the same file's cached work more than once. Dropping it again costs little.

View source

run function

run(roots: Sequence[Path], on_change: Callable[[set[Path]], None]) -> None

Drive watchdog filesystem events into on_change until stopped.

View source

stop function

stop() -> None

Stop the watchdog observer loop.

View source

PollingWatcher class

Watch files by checking their modification times on a timer.

It needs nothing installed, but it is slower than WatchfilesWatcher. Citry uses it when neither watchfiles nor watchdog is installed.

Parameters

  • interval float - The seconds between two checks.
View source

run function

run(roots: Sequence[Path], on_change: Callable[[set[Path]], None]) -> None

Re-scan roots every interval seconds and report mtime changes.

View source

stop function

stop() -> None

Break the scan loop after the current wait.

Citry version: 0.9.0