pysepal.solara.session_manager.SessionManager#

class pysepal.solara.session_manager.SessionManager[source]#

A singleton session manager for solara-sepal applications.

This class manages the lifecycle of sessions across different Solara applications, providing a centralized way to handle session creation, retrieval, and cleanup for GEE interfaces, SepalClient and GDriveInterface.

Note: Do not instantiate this class directly. Use the @with_sepal_sessions decorator or the utility functions in pysepal.solara.utils instead.

Initialize the SessionManager singleton instance.

Methods

__init__

Initialize the SessionManager singleton instance.

cleanup_session

Close and forget the session for a scope, then tombstone the scope.

close_process_session

Close and release the process-wide session, if one exists.

create_session

Create -- or reuse -- the session for the current runtime.

get_drive_interface

Return the Drive interface for the current runtime.

get_gee_interface

Return the GEE interface for the current runtime.

get_scope_id

Get the current supported Solara/Voila runtime ID.

get_sepal_client

Get a SepalClient for the current runtime's session.

get_session_info

Return a scope's session status.

is_initialized

Check if the SessionManager has been initialized.

session_scope_ids

Return every scope currently holding a session.

sessions_overview

Return every session the process holds, including the process one.

SessionManager.__init__()[source]#

Initialize the SessionManager singleton instance.

SessionManager.cleanup_session(scope_id)[source]#

Close and forget the session for a scope, then tombstone the scope.

The tombstone is permanent until _reopen_scope lifts it – which only happens when setup_sessions runs again for this same scope_id, i.e. a genuine kernel restart, not a reconnect.

Parameters:

scope_id (str) – The scope to clean up.

Return type:

None

SessionManager.close_process_session()[source]#

Close and release the process-wide session, if one exists.

The process session’s lifetime is the process, so nothing closes it automatically – cleanup_session refuses the process scope. This is the explicit teardown for embedders and tests. No tombstone is written: the next accessor rebuilds.

Return type:

None

SessionManager.create_session(module_name='default')[source]#

Create – or reuse – the session for the current runtime.

Dispatches on runtime topology, never on credential probing: an app-launcher container builds one session per connection from that connection’s SEPAL headers, and every other runtime – a SEPAL sandbox, Voila, plain Jupyter, a script – shares one session for the process, built from a developer login when PYSEPAL_DEV_AUTH is armed and from the machine’s own credentials otherwise.

Parameters:

module_name (str) – The module name for the SepalClient.

Raises:
  • MissingSepalHeadersError – A per-connection runtime carries no valid SEPAL headers.

  • SessionScopeClosedError – The scope was already cleaned up.

  • EEClientError – For authentication-related errors.

Return type:

None

SessionManager.get_drive_interface()[source]#

Return the Drive interface for the current runtime.

Returns:

The interface, resolved exactly as get_gee_interface().

Raises:

SepalSessionError – A per-connection runtime has no session yet.

Return type:

GDriveInterface

SessionManager.get_gee_interface()[source]#

Return the GEE interface for the current runtime.

Returns:

An app-launcher connection reads the interface @with_sepal_sessions built for it. Every other runtime gets the process interface, built on first use.

Raises:

SepalSessionError – A per-connection runtime has no session yet.

Return type:

GEEInterface

SessionManager.get_scope_id()[source]#

Get the current supported Solara/Voila runtime ID.

Return type:

str

SessionManager.get_sepal_client(module_name=None, scope_id=None)[source]#

Get a SepalClient for the current runtime’s session.

One session holds one client per module name; without module_name you get the client of the route currently rendering.

Parameters:
  • module_name (str | None) – The module whose client to return. Defaults to the module of the most recently entered @with_sepal_sessions component.

  • scope_id (str | None) – Read this scope instead of resolving the current one.

Returns:

The client, or None when there is no session for the scope, no client for that module, no SEPAL identity in this process, or the scope is the reserved process one.

Return type:

SepalClient | None

SessionManager.get_session_info(scope_id=None)[source]#

Return a scope’s session status.

Never raises: a runtime with no resolvable per-connection scope reports the reserved process scope id without reading it – an unresolvable caller (a background export task, a callback on GEEInterface’s private loop) must not see the shared process/dev-auth session’s identity just because its own scope didn’t resolve. The same reserved scope passed explicitly is refused the same way, so scope_id can’t be used as a second door into that session – the rule get_sepal_client() already applies to its own scope_id parameter. A scope with no session reports a not-ready SessionInfo carrying only its scope id, so admin and debug UI render anywhere.

Parameters:

scope_id (str | None) – The scope to report on. If None, uses the current one.

Returns:

The scope’s session status.

Return type:

SessionInfo

classmethod SessionManager.is_initialized()[source]#

Check if the SessionManager has been initialized.

Return type:

bool

SessionManager.session_scope_ids()[source]#

Return every scope currently holding a session.

Returns:

A snapshot tuple. The private session dicts are never handed out; use sessions_overview() to read them all – get_session_info() refuses the reserved process scope, which this tuple can contain.

Return type:

Tuple[str, …]

SessionManager.sessions_overview()[source]#

Return every session the process holds, including the process one.

Reads each id from session_scope_ids() through _session_info_for(), not the guarded get_session_info(): an enumerated scope id was never caller-supplied, so the reserved-scope guard doesn’t apply here. Under PROCESS/DEV_AUTH topology the process session is the process’s only session – hiding it from this overview would make it lie about how many sessions exist.

Returns:

Every scope’s session status, unfiltered.

Return type:

SessionsOverview