Skip to content

Hosts

An application surface host owns a Reconciler, schedules Python work, and forwards lifecycle, viewport, and back events. Its logical tree includes screens, overlays, and mounted list rows. Native containers present those children without creating a separate Python host for every screen or row.

The host also publishes navigation restoration state through the Host module as it changes. The platform saves the latest copy without calling into Python and hands it back in the next create event as restored_state. Viewport metrics (size, insets, keyboard height, color scheme, scale, and font scale) arrive on the layout and resume events. The host implements the HostNavigator interface used by navigation and headless tests.

The bundled Android (PNScreenFragment) and iOS (PNViewController) templates create a host through the Host native module's create event and never need to be edited by app code; one NativeScreenHost class serves both platforms because every platform-specific step goes over the bridge. The browser preview uses the same class: its page is a bridge peer that speaks the Host module protocol over a WebSocket (see WebTransport).

Application surface hosts connecting renderers to the reconciler.

On every bridge platform (iOS, Android, and the browser preview) the renderer creates an application host through the bridge (callback("host", screen_id, "create", {...})), which lands in NativeScreenHost. Screens, overlays, and mounted list rows remain in that host's logical tree. Tests use the headless base ScreenHost with a fake backend, created through create_screen.

Modules:

Name Description
base

Platform-independent application surface host.

native

On-device application surface hosting, shared by iOS and Android.

Classes:

Name Description
ScreenHost

Base screen host; see the module docstring.

Functions:

Name Description
import_component

Import a root component by module path or dotted attribute path.

host_class

The host class for the current runtime.

create_screen

Create an application surface host for a root component.

live_hosts

Every screen host currently mounted by the native runtime.

ScreenHost

ScreenHost(
    native_instance: Any,
    component_path: str,
    component: Any,
)

Base screen host; see the module docstring.

Attributes:

Name Type Description
native_instance

The platform object owning this screen (an integer screen id on the bridge platforms).

component_path

Import path of the root component.

args Dict[str, Any]

Launch arguments (set_args), including the serialized navigation state under "pn_nav" for pushed screens.

reconciler Any

The mounted reconciler, or None before on_create / after on_destroy.

is_focused

Whether the screen is presented (on_resume / on_pause).

Methods:

Name Description
initial_navigation_state

Return the serialized navigation state from args["pn_nav"], or None for the first screen.

cache_navigation_state

Publish a restorable immutable navigation snapshot to the native host.

set_screen_options

Apply header options (title and friends) to the native chrome.

add_focus_listener

Subscribe to focus changes (on_resume / on_pause); returns an unsubscribe callable.

on_create

Mount the root component (idempotent across native view recreation).

on_resume

Mark the screen focused and notify focus listeners.

on_pause

Mark the screen unfocused and notify focus listeners.

on_destroy

Tear down: unmount (running effect cleanups), release native views.

on_back_pressed

Offer the system back action to use_back_handler subscribers.

set_args

Record launch arguments (a dict or a JSON string).

set_focused

Update is_focused and notify focus listeners when the value changes.

set_viewport_size

Forward a viewport-size change (in points) to the reconciler.

request_render

Request a render pass (queued if one is in progress).

flush_scheduled_render

Run a render deferred by _schedule_render_async (platform UI turn).

show_redbox

Mount the dev error overlay over this screen (from any thread).

clear_redbox

Dismiss the host-owned error overlay without touching the surface.

reload

Reload changed_modules (and their dependents) and refresh this tree.

refresh

Refresh the mounted tree against already-reloaded modules.

initial_navigation_state

initial_navigation_state() -> Optional[Dict[str, Any]]

Return the serialized navigation state from args["pn_nav"], or None for the first screen.

cache_navigation_state

cache_navigation_state(state: Dict[str, Any]) -> None

Publish a restorable immutable navigation snapshot to the native host.

set_screen_options

set_screen_options(options: Dict[str, Any]) -> None

Apply header options (title and friends) to the native chrome.

add_focus_listener

add_focus_listener(
    callback: Callable[[bool], None],
) -> Callable[[], None]

Subscribe to focus changes (on_resume / on_pause); returns an unsubscribe callable.

on_create

on_create() -> None

Mount the root component (idempotent across native view recreation).

Android destroys and recreates a fragment's view when the user pops back to it and calls on_create again; the Python host persists, so an already-mounted tree is simply re-attached.

on_resume

on_resume() -> None

Mark the screen focused and notify focus listeners.

on_pause

on_pause() -> None

Mark the screen unfocused and notify focus listeners.

on_destroy

on_destroy() -> None

Tear down: unmount (running effect cleanups), release native views.

on_back_pressed

on_back_pressed() -> bool

Offer the system back action to use_back_handler subscribers.

Returns True when a handler consumed the event, in which case the platform must not pop the screen.

set_args

set_args(args: Any) -> None

Record launch arguments (a dict or a JSON string).

set_focused

set_focused(focused: bool) -> None

Update is_focused and notify focus listeners when the value changes.

set_viewport_size

set_viewport_size(width: float, height: float) -> None

Forward a viewport-size change (in points) to the reconciler.

request_render

request_render() -> None

Request a render pass (queued if one is in progress).

flush_scheduled_render

flush_scheduled_render() -> None

Run a render deferred by _schedule_render_async (platform UI turn).

show_redbox

show_redbox(
    exc: BaseException, phase: str = "render"
) -> None

Mount the dev error overlay over this screen (from any thread).

clear_redbox

clear_redbox(reattach: bool = True) -> None

Dismiss the host-owned error overlay without touching the surface.

reload

reload(
    changed_modules: Optional[Sequence[str]] = None,
) -> str

Reload changed_modules (and their dependents) and refresh this tree.

A convenience for a single host (tests, scripts). The dev client reloads modules once per process and then calls refresh on every live host; see pythonnative.hot_reload.apply_reload.

Returns:

Type Description
str

"fast_refresh", "remount", "error", or "none"

str

(nothing was reloaded).

refresh

refresh(
    reloaded_modules: Sequence[str],
    *,
    force_remount: bool = False
) -> str

Refresh the mounted tree against already-reloaded modules.

Tries Fast Refresh first (swap component functions in place so hook state survives) and falls back to a full remount.

Returns:

Type Description
str

"fast_refresh", "remount", or "error" (the error

str

is shown in the RedBox in dev mode, re-raised otherwise).

import_component

import_component(component_path: str) -> Any

Import a root component by module path or dotted attribute path.

"app.main" imports the module and returns its App attribute; "app.main.RootScreen" returns the named attribute. Errors raised inside a resolvable module (a missing third-party dependency, a syntax error) propagate unchanged so the real cause stays visible.

Raises:

Type Description
ImportError

When neither form resolves.

host_class

host_class() -> Type[ScreenHost]

The host class for the current runtime.

create_screen

create_screen(
    component_path: str,
    native_instance: Any = None,
    args_json: Optional[str] = None,
) -> ScreenHost

Create an application surface host for a root component.

Parameters:

Name Type Description Default
component_path str

"app.main" (the module's App is used) or a dotted path like "app.main.RootScreen". Imported lazily so the dev server can reload it.

required
native_instance Any

The platform object owning the surface (the integer host id on the bridge platforms).

None
args_json Optional[str]

Optional JSON launch arguments, including cached navigation restoration state.

None

Returns:

Type Description
ScreenHost

A host ready for on_create and the other lifecycle calls.

live_hosts

live_hosts() -> Sequence[ScreenHost]

Every screen host currently mounted by the native runtime.

Returns an empty sequence off the bridge platforms; tests hold their own host references.

Shared host logic

Platform-independent application surface host.

A host mounts one logical application tree, publishes native lifecycle and viewport changes, schedules Python work on the application thread, and caches navigation restoration state. Logical screen containers present the tree's screen roots through native navigation controllers and fragments.

Classes:

Name Description
ScreenHost

Base screen host; see the module docstring.

Functions:

Name Description
import_component

Import a root component by module path or dotted attribute path.

ScreenHost

ScreenHost(
    native_instance: Any,
    component_path: str,
    component: Any,
)

Base screen host; see the module docstring.

Attributes:

Name Type Description
native_instance

The platform object owning this screen (an integer screen id on the bridge platforms).

component_path

Import path of the root component.

args Dict[str, Any]

Launch arguments (set_args), including the serialized navigation state under "pn_nav" for pushed screens.

reconciler Any

The mounted reconciler, or None before on_create / after on_destroy.

is_focused

Whether the screen is presented (on_resume / on_pause).

Methods:

Name Description
initial_navigation_state

Return the serialized navigation state from args["pn_nav"], or None for the first screen.

cache_navigation_state

Publish a restorable immutable navigation snapshot to the native host.

set_screen_options

Apply header options (title and friends) to the native chrome.

add_focus_listener

Subscribe to focus changes (on_resume / on_pause); returns an unsubscribe callable.

on_create

Mount the root component (idempotent across native view recreation).

on_resume

Mark the screen focused and notify focus listeners.

on_pause

Mark the screen unfocused and notify focus listeners.

on_destroy

Tear down: unmount (running effect cleanups), release native views.

on_back_pressed

Offer the system back action to use_back_handler subscribers.

set_args

Record launch arguments (a dict or a JSON string).

set_focused

Update is_focused and notify focus listeners when the value changes.

set_viewport_size

Forward a viewport-size change (in points) to the reconciler.

request_render

Request a render pass (queued if one is in progress).

flush_scheduled_render

Run a render deferred by _schedule_render_async (platform UI turn).

show_redbox

Mount the dev error overlay over this screen (from any thread).

clear_redbox

Dismiss the host-owned error overlay without touching the surface.

reload

Reload changed_modules (and their dependents) and refresh this tree.

refresh

Refresh the mounted tree against already-reloaded modules.

initial_navigation_state

initial_navigation_state() -> Optional[Dict[str, Any]]

Return the serialized navigation state from args["pn_nav"], or None for the first screen.

cache_navigation_state

cache_navigation_state(state: Dict[str, Any]) -> None

Publish a restorable immutable navigation snapshot to the native host.

set_screen_options

set_screen_options(options: Dict[str, Any]) -> None

Apply header options (title and friends) to the native chrome.

add_focus_listener

add_focus_listener(
    callback: Callable[[bool], None],
) -> Callable[[], None]

Subscribe to focus changes (on_resume / on_pause); returns an unsubscribe callable.

on_create

on_create() -> None

Mount the root component (idempotent across native view recreation).

Android destroys and recreates a fragment's view when the user pops back to it and calls on_create again; the Python host persists, so an already-mounted tree is simply re-attached.

on_resume

on_resume() -> None

Mark the screen focused and notify focus listeners.

on_pause

on_pause() -> None

Mark the screen unfocused and notify focus listeners.

on_destroy

on_destroy() -> None

Tear down: unmount (running effect cleanups), release native views.

on_back_pressed

on_back_pressed() -> bool

Offer the system back action to use_back_handler subscribers.

Returns True when a handler consumed the event, in which case the platform must not pop the screen.

set_args

set_args(args: Any) -> None

Record launch arguments (a dict or a JSON string).

set_focused

set_focused(focused: bool) -> None

Update is_focused and notify focus listeners when the value changes.

set_viewport_size

set_viewport_size(width: float, height: float) -> None

Forward a viewport-size change (in points) to the reconciler.

request_render

request_render() -> None

Request a render pass (queued if one is in progress).

flush_scheduled_render

flush_scheduled_render() -> None

Run a render deferred by _schedule_render_async (platform UI turn).

show_redbox

show_redbox(
    exc: BaseException, phase: str = "render"
) -> None

Mount the dev error overlay over this screen (from any thread).

clear_redbox

clear_redbox(reattach: bool = True) -> None

Dismiss the host-owned error overlay without touching the surface.

reload

reload(
    changed_modules: Optional[Sequence[str]] = None,
) -> str

Reload changed_modules (and their dependents) and refresh this tree.

A convenience for a single host (tests, scripts). The dev client reloads modules once per process and then calls refresh on every live host; see pythonnative.hot_reload.apply_reload.

Returns:

Type Description
str

"fast_refresh", "remount", "error", or "none"

str

(nothing was reloaded).

refresh

refresh(
    reloaded_modules: Sequence[str],
    *,
    force_remount: bool = False
) -> str

Refresh the mounted tree against already-reloaded modules.

Tries Fast Refresh first (swap component functions in place so hook state survives) and falls back to a full remount.

Returns:

Type Description
str

"fast_refresh", "remount", or "error" (the error

str

is shown in the RedBox in dev mode, re-raised otherwise).

import_component

import_component(component_path: str) -> Any

Import a root component by module path or dotted attribute path.

"app.main" imports the module and returns its App attribute; "app.main.RootScreen" returns the named attribute. Errors raised inside a resolvable module (a missing third-party dependency, a syntax error) propagate unchanged so the real cause stays visible.

Raises:

Type Description
ImportError

When neither form resolves.

flush_hosts

flush_hosts(hosts: Sequence[ScreenHost]) -> None

Run deferred renders for hosts (platform UI-thread drains call this).

Platform hosts

On-device application surface hosting, shared by iOS and Android.

Native hosts send asynchronous lifecycle, viewport, and back events keyed by surface host ID. Python attaches the application root and publishes cached restoration state through the Host module. Navigation owns logical Screen children in that same application tree.

Classes:

Name Description
NativeScreenHost

Screen host addressed by an integer screen_id on the bridge.

Functions:

Name Description
host_for_screen

Return the host registered for screen_id (None if unknown).

live_hosts

Every host currently registered, in creation order.

dispatch_host_event

Route callback("host", screen_id, event, payload) to a host.

NativeScreenHost

NativeScreenHost(
    screen_id: int, component_path: str, component: Any
)

Bases: ScreenHost

Screen host addressed by an integer screen_id on the bridge.

Methods:

Name Description
on_destroy

Forget the screen id, then tear down the tree.

apply_metrics

Publish the metrics carried by a host event and resize the viewport.

cache_navigation_state

Cache navigation before the platform's synchronous state-saving callback.

on_destroy

on_destroy() -> None

Forget the screen id, then tear down the tree.

apply_metrics

apply_metrics(payload: Any) -> None

Publish the metrics carried by a host event and resize the viewport.

cache_navigation_state

cache_navigation_state(state: Dict[str, Any]) -> None

Cache navigation before the platform's synchronous state-saving callback.

host_for_screen

host_for_screen(
    screen_id: int,
) -> Optional["NativeScreenHost"]

Return the host registered for screen_id (None if unknown).

live_hosts

live_hosts() -> Sequence['NativeScreenHost']

Every host currently registered, in creation order.

dispatch_host_event

dispatch_host_event(
    screen_id: int, event: str, payload: Any
) -> Optional[str]

Route callback("host", screen_id, event, payload) to a host.

Events (payloads are what PNViewController and PNScreenFragment send):

  • create {"path", "args", "restored_state", ...metrics}: import the component, create the host, and mount. path is the dotted component path (None means the app entry module) and args a JSON string. Returns {"root": tag}.
  • start / resume / pause / stop / destroy: lifecycle. resume and layout carry metrics.
  • layout {width, height, insets, keyboard_height, color_scheme, scale, font_scale, screen_width, screen_height}.
  • appearance {"color_scheme"}.
  • back_pressed: pops a handled screen, otherwise asks native to finish it (Host.finish).
  • reload: remount after the development error overlay.
  • flush: run deferred renders now.

Native delivers every event asynchronously and ignores the return value; only tests read create's {"root": tag}.

Next steps