stanza.jupyter.core

Module Contents

Classes

NameDescription
ServerStatePersistent Jupyter server state stored on disk.
ServerStatusRuntime Jupyter server status with calculated uptime.
RuntimeInfoJupyter runtime information parsed from jpserver-{pid}.json.
SessionInfoActive Jupyter notebook session with log file metadata.
ConfigConfiguration for Jupyter server management.
_FileLockFile-based lock for preventing concurrent Jupyter server operations.

Functions

NameDescription
_read_stateRead the Jupyter server state from disk.
_write_stateWrite the Jupyter server state to disk atomically with secure permissions.
_clear_stateDelete the server state file and log files, ignoring errors.
_is_aliveCheck if a process with the given PID is running.
_open_logsOpen stdout and stderr log files, truncating if they exceed max size.
_discover_runtimeDiscover Jupyter runtime information by polling for jpserver-{pid}.json.
_shutdownGracefully shutdown Jupyter server via REST API.
_killTerminate Jupyter server process with SIGTERM.
_force_killForce kill Jupyter server process with SIGKILL.
_api_requestMake authenticated request to Jupyter API.
_setup_ipython_startupCopy auto-logging startup script to stanza’s IPython configuration directory.
startStart a Jupyter server in the background with auto-logging enabled.
stopStop the Jupyter server using escalating shutdown strategies.
statusGet the current Jupyter server status including uptime.
list_sessionsList active notebook sessions with log metadata.
kill_kernelKill kernel for notebook via Jupyter API.

Data

_config

API

1class stanza.jupyter.core.ServerState

Persistent Jupyter server state stored on disk.

Attributes: pid: Process ID of the Jupyter server url: Full URL with token for accessing JupyterLab started_at: ISO 8601 timestamp when server was started root_dir: Absolute path to the notebook root directory

1pid: int

Value: None

1url: str

Value: None

1started_at: str

Value: None

1root_dir: str

Value: None

1class stanza.jupyter.core.ServerStatus

Runtime Jupyter server status with calculated uptime.

Attributes: pid: Process ID of the running Jupyter server url: Full URL with token for accessing JupyterLab uptime_seconds: Number of seconds the server has been running root_dir: Absolute path to the notebook root directory

1pid: int

Value: None

1url: str

Value: None

1uptime_seconds: float

Value: None

1root_dir: str

Value: None

1class stanza.jupyter.core.RuntimeInfo

Jupyter runtime information parsed from jpserver-{pid}.json.

Attributes: url: JupyterLab URL with authentication token token: Authentication token for API requests port: Port number the server is listening on runtime_file: Path to the Jupyter runtime JSON file

1url: str

Value: None

1token: str

Value: None

1port: int

Value: None

1runtime_file: str

Value: None

1class stanza.jupyter.core.SessionInfo

Active Jupyter notebook session with log file metadata.

Attributes: notebook_path: Absolute path to the notebook file log_path: Absolute path to the notebook’s log file size_bytes: Size of the log file in bytes line_count: Number of lines in the log file

1notebook_path: str

Value: None

1log_path: str

Value: None

1size_bytes: int

Value: None

1line_count: int

Value: None

1class stanza.jupyter.core.Config

Configuration for Jupyter server management.

Attributes: state_dir: Directory for storing server state and logs log_max_size: Maximum log file size in bytes before truncation

1state_dir: pathlib.Path

Value: Path(...)

1log_max_size: int

Value: None

1state_file: pathlib.Path

Path to the server state JSON file.

1lock_file: pathlib.Path

Path to the file lock for preventing concurrent operations.

1stdout_log: pathlib.Path

Path to the Jupyter server stdout log.

1stderr_log: pathlib.Path

Path to the Jupyter server stderr log.

1ipython_dir: pathlib.Path

Path to stanza’s managed IPython configuration directory.

1ipython_startup_dir: pathlib.Path

Path to IPython startup scripts directory for auto-logging.

1stanza.jupyter.core._config

Value: Config(...)

1stanza.jupyter.core._read_state() -> stanza.jupyter.core.ServerState | None

Read the Jupyter server state from disk.

Returns:

ServerState if state file exists and is valid, None otherwise

1stanza.jupyter.core._write_state(state: stanza.jupyter.core.ServerState) -> None

Write the Jupyter server state to disk atomically with secure permissions.

Uses a temporary file and atomic rename to prevent corruption. Sets file permissions to 0o600 (owner read/write only) for security.

Parameters:

state
stanza.jupyter.core.ServerState

ServerState to persist to disk

1stanza.jupyter.core._clear_state() -> None

Delete the server state file and log files, ignoring errors.

1stanza.jupyter.core._is_alive(pid: int) -> bool

Check if a process with the given PID is running.

Parameters:

pid
int

Process ID to check

Returns:

True if process is running, False otherwise

1class stanza.jupyter.core._FileLock(lock_file: pathlib.Path, timeout: float = 5.0)

File-based lock for preventing concurrent Jupyter server operations.

Uses fcntl.flock for process-level locking to ensure only one stanza process can modify the Jupyter server state at a time.

Initialization

Initialize lock with the lock file path and acquisition timeout.

Parameters:

Parameters:

  • lock_file: Path to the lock file
  • timeout: Maximum seconds to wait for lock acquisition
1__enter__() -> stanza.jupyter.core._FileLock

Acquire exclusive lock, blocking until available or timeout.

Returns:

Self for context manager usage

Raises:

RuntimeError: If lock cannot be acquired within timeout period

1__exit__(
2 exc_type: typing.Any,
3 exc_val: typing.Any,
4 exc_tb: typing.Any
5) -> None

Release lock and close file descriptor.

1stanza.jupyter.core._open_logs(tail_bytes: int = 50000) -> tuple[typing.TextIO, typing.TextIO]

Open stdout and stderr log files, truncating if they exceed max size.

If a log file exceeds log_max_size, it is truncated to keep only the last tail_bytes with a marker indicating truncation occurred.

Parameters:

tail_bytes
intDefaults to 50000

Number of bytes to preserve when truncating logs

Returns:

Tuple of (stdout_file, stderr_file) opened in append mode

1stanza.jupyter.core._discover_runtime(
2 pid: int,
3 timeout: float = 10.0,
4 poll_interval: float = 0.2
5) -> stanza.jupyter.core.RuntimeInfo

Discover Jupyter runtime information by polling for jpserver-{pid}.json.

Waits for Jupyter to write its runtime file containing the server URL, token, and port. Constructs a JupyterLab URL with authentication token.

Parameters:

pid
int

Process ID of the Jupyter server

timeout
floatDefaults to 10.0

Maximum seconds to wait for runtime file

poll_interval
floatDefaults to 0.2

Seconds between file existence checks

Returns:

RuntimeInfo containing server URL, token, port, and runtime file path

Raises:

RuntimeError: If runtime file is not found within timeout period

1stanza.jupyter.core._shutdown(
2 state: stanza.jupyter.core.ServerState,
3 timeout: float = 5.0,
4 poll_interval: float = 0.2
5) -> None

Gracefully shutdown Jupyter server via REST API.

Sends a shutdown request to the Jupyter server using the authentication token, then polls until the process terminates or timeout is reached.

Parameters:

state
stanza.jupyter.core.ServerState

Server state containing URL and PID

timeout
floatDefaults to 5.0

Maximum seconds to wait for shutdown

poll_interval
floatDefaults to 0.2

Seconds between process aliveness checks

1stanza.jupyter.core._kill(
2 pid: int,
3 timeout: float = 5.0,
4 poll_interval: float = 0.2
5) -> None

Terminate Jupyter server process with SIGTERM.

Sends SIGTERM signal and waits for process to exit gracefully.

Parameters:

pid
int

Process ID to terminate

timeout
floatDefaults to 5.0

Maximum seconds to wait for termination

poll_interval
floatDefaults to 0.2

Seconds between process aliveness checks

1stanza.jupyter.core._force_kill(pid: int) -> None

Force kill Jupyter server process with SIGKILL.

Parameters:

pid
int

Process ID to force kill

1stanza.jupyter.core._api_request(
2 state: stanza.jupyter.core.ServerState, endpoint: str
3) -> typing.Any

Make authenticated request to Jupyter API.

Parameters:

state
stanza.jupyter.core.ServerState

Server state containing URL with token

endpoint
str

API endpoint path (e.g., “api/sessions”)

Returns:

JSON response from the API

Raises:

requests.HTTPError: If the request fails

1stanza.jupyter.core._setup_ipython_startup() -> None

Copy auto-logging startup script to stanza’s IPython configuration directory.

Raises:

RuntimeError: If the startup script cannot be found

1stanza.jupyter.core.start(
2 notebook_dir: pathlib.Path,
3 port: int = 8888,
4 startup_wait: float = 0.5
5) -> dict[str, typing.Any]

Start a Jupyter server in the background with auto-logging enabled.

Launches jupyter_server as a detached process, discovers its runtime information, and saves the state to disk. Configures IPYTHONDIR to enable automatic cell output logging to notebook_name.log files.

Parameters:

notebook_dir
pathlib.Path

Root directory for notebooks

port
intDefaults to 8888

Port number for the server (default: 8888)

startup_wait
floatDefaults to 0.5

Seconds to wait before checking if server started successfully

Returns:

Dictionary with keys: pid, url, started_at, root_dir

Raises:

RuntimeError: If server is already running or fails to start

1stanza.jupyter.core.stop() -> None

Stop the Jupyter server using escalating shutdown strategies.

Attempts graceful shutdown via REST API, then SIGTERM, then SIGKILL if necessary. Cleans up state files when complete. Safe to call even if no server is running.

1stanza.jupyter.core.status() -> dict[str, typing.Any] | None

Get the current Jupyter server status including uptime.

Returns:

Dictionary with keys: pid, url, uptime_seconds, root_dir. None if no server is running or state is stale.

1stanza.jupyter.core.list_sessions() -> list[dict[str, typing.Any]]

List active notebook sessions with log metadata.

Returns:

List of dictionaries, each containing: notebook_path, log_path, size_bytes, line_count. Empty list if no server is running.

1stanza.jupyter.core.kill_kernel(notebook_name: str) -> None

Kill kernel for notebook via Jupyter API.

Parameters:

notebook_name
str

Name of the notebook (case-insensitive substring match)

Raises:

RuntimeError: If no server is running, notebook not found, or API call fails