maestral.daemon

This module defines functions to start and stop the sync daemon and retrieve proxy objects for a running daemon.

Module Contents

maestral.daemon.set_executable(executable: str, *argv: str)None[source]

Sets the path of the Python executable to use when starting the daemon. By default sys.executable is used. Can be used when embedding the daemon.

Parameters
  • executable – Path to custom Python executable.

  • argv – Any command line arguments to be injected before the daemon startup command. By default, “-OO” will be used.

class maestral.daemon.Stop[source]

Bases: enum.Enum

Enumeration of daemon exit results

Ok = 0[source]
Killed = 1[source]
NotRunning = 2[source]
Failed = 3[source]
class maestral.daemon.Start[source]

Bases: enum.Enum

Enumeration of daemon start results

Ok = 0[source]
AlreadyRunning = 1[source]
Failed = 2[source]
class maestral.daemon.Lock(name: str, lock_path: Optional[str] = None)[source]

A inter-process and inter-thread lock

This internally uses fasteners.InterProcessLock but provides non-blocking acquire. It also guarantees thread-safety when using the singleton() class method to create / retrieve a lock instance.

classmethod singleton(cls, name: str, lock_path: Optional[str] = None)maestral.daemon.Lock[source]

Retrieve an existing lock object with a given ‘name’ or create a new one. Use this method for thread-safe locks.

Parameters
  • name – Name of lock file.

  • lock_path – Directory for lock files. Defaults to the temporary directory returned by tempfile.gettempdir() if not given.

acquire(self)bool[source]

Attempts to acquire the given lock.

Returns

Whether or not the acquisition succeeded.

release(self)None[source]

Release the previously acquired lock.

locked(self)bool[source]

Checks if the lock is currently held by any thread or process.

locking_pid(self) → Optional[int][source]

Returns the PID of the process which currently holds the lock or None. This should work on macOS, OpenBSD and Linux but may fail on some platforms. Always use locked() to check if the lock is held by any process.

Returns

The PID of the process which currently holds the lock or None.

maestral.daemon.maestral_lock(config_name: str)maestral.daemon.Lock[source]

Returns an inter-process and inter-thread lock for Maestral. This is a wrapper around Lock which fills out the appropriate lockfile name and directory for the given config name.

maestral.daemon.sockpath_for_config(config_name: str)str[source]

Returns the unix socket location to be used for the config. This should default to the apps runtime directory + ‘CONFIG_NAME.sock’.

maestral.daemon.lockpath_for_config(config_name: str)str[source]

Returns the lock file location to be used for the config. This should default to the apps runtime directory + ‘CONFIG_NAME.lock’.

maestral.daemon.get_maestral_pid(config_name: str) → Optional[int][source]

Returns Maestral’s PID if the daemon is running, None otherwise.

Parameters

config_name – The name of the Maestral configuration.

Returns

The daemon’s PID.

maestral.daemon.is_running(config_name: str)bool[source]

Checks if a daemon is currently running.

Parameters

config_name – The name of the Maestral configuration.

Returns

Whether the daemon is running.

maestral.daemon.start_maestral_daemon(config_name: str = 'maestral', log_to_stdout: bool = False, start_sync: bool = False)None[source]

Starts the Maestral daemon with event loop in the current thread. Startup is race free: there will never be two daemons running for the same config.

Wraps main.Maestral as Pyro daemon object, creates a new instance and starts an asyncio event loop to listen for requests on a unix domain socket. This call will block until the event loop shuts down. When this function is called from the main thread on macOS, the asyncio event loop uses Cocoa’s CFRunLoop to process event. This allows integration with Cocoa frameworks which use callbacks to process use input such as clicked notifications, etc, and potentially allows showing a GUI.

Parameters
  • config_name – The name of the Maestral configuration to use.

  • log_to_stdout – If True, write logs to stdout.

  • start_sync – If True, start syncing once the daemon has started. If the start_sync call fails, an error will be logged but not raised.

Raises

RuntimeError – if a daemon for the given config_name is already running.

maestral.daemon.start_maestral_daemon_process(config_name: str = 'maestral', start_sync: bool = False, timeout: int = 5)maestral.daemon.Start[source]

Starts the Maestral daemon in a new process by calling start_maestral_daemon(). Startup is race free: there will never be two daemons running for the same config. This function will use sys.executable as a Python executable to start the daemon. Use set_executable() to use a custom executable instead.

Parameters
  • config_name – The name of the Maestral configuration to use.

  • start_sync – If True, start syncing once the daemon has started.

  • timeout – Time in sec to wait for daemon to start.

Returns

Start.Ok if successful, Start.AlreadyRunning if the daemon was already running or Start.Failed if startup failed. It is possible that Start.Ok may be returned instead of Start.AlreadyRunning in case of a race but the daemon is nevertheless started only once.

maestral.daemon.stop_maestral_daemon_process(config_name: str = 'maestral', timeout: float = 10)maestral.daemon.Stop[source]

Stops a maestral daemon process by finding its PID and shutting it down.

This function first tries to shut down Maestral gracefully. If this fails and we know its PID, it will send SIGTERM. If that fails as well, it will send SIGKILL to the process.

Parameters
  • config_name – The name of the Maestral configuration to use.

  • timeout – Number of sec to wait for daemon to shut down before killing it.

Returns

Stop.Ok if successful, Stop.Killed if killed, Stop.NotRunning if the daemon was not running and Stop.Failed if killing the process failed because we could not retrieve its PID.

class maestral.daemon.MaestralProxy(config_name: str = 'maestral', fallback: bool = False)[source]

A Proxy to the Maestral daemon

All methods and properties of Maestral’s public API are accessible and calls / access will be forwarded to the corresponding Maestral instance. This class can be used as a context manager to close the connection to the daemon on exit.

Example

Use MaestralProxy as a context manager:

>>> with MaestralProxy() as m:
...     print(m.status)

Use MaestralProxy directly:

>>> m = MaestralProxy()
>>> print(m.status)
>>> m._disconnect()
Variables

_is_fallback – Whether we are using an actual Maestral instance as fallback instead of a Proxy.

Parameters
  • config_name – The name of the Maestral configuration to use.

  • fallback – If True, a new instance of Maestral will created in the current process when the daemon is not running.

Raises

CommunicationError – if the daemon is running but cannot be reached or if the daemon is not running and fallback is False.