Skip to content

Async runtime

PythonNative starts one standard asyncio event loop on a dedicated application thread. Component rendering, effects, event handlers, and async tasks run on that thread. UIKit and Android retain their own UI threads; native bridge calls marshal view operations there and queue events back to Python.

Ordinary asyncio networking, TaskGroup, timeouts, synchronization primitives, and third-party async libraries run on this loop. A synchronous Python callback can still delay other Python work, so use asyncio.to_thread for blocking I/O and cooperative async work for long operations.

Component effects and async event handlers have component lifetimes. Unmounting cancels their tasks. Use runtime.run_application_task() when work must survive the initiating component, and TaskScope for explicitly owned services. Native promises can register cancellation handlers; late results are ignored.

Headless tests can use run_blocking() and drain(). Don't call run_blocking() from the running application loop; await the operation instead.

runtime

Application execution on a standard asyncio event loop.

Mobile hosts start one application thread with :func:start. All Python rendering, callbacks, and tasks run there. Native hosts own their UI threads and marshal view operations themselves. Headless programs can instead drive an ordinary local loop with :func:run_blocking and :func:drain.

Classes:

Name Description
TaskScope

Own tasks until an application or component is disposed.

Functions:

Name Description
start

Start the application thread once and return its event loop.

get_loop

Return the application loop, or the caller's loop in headless mode.

run_async

Schedule work in the current component scope or the application scope.

run_application_task

Start work that should survive the component that requested it.

run_blocking

Wait for work from synchronous code; never block the application loop.

drain

Settle headless work or wait for application tasks from a test thread.

call_threadsafe

Enqueue a callback on the application event loop from any thread.

call_on_application_thread

Execute Python work on its owner thread, inline when already there.

resolve_future

Complete a future from any thread unless it was cancelled.

reject_future

Fail a future from any thread unless it was cancelled.

create_future

Create a future for completion by a native request.

TaskScope

TaskScope(name: str = 'application')

Own tasks until an application or component is disposed.

Closing a scope cancels its tasks and rejects new work. A task removes itself when it finishes, including when it fails or is cancelled.

Methods:

Name Description
create_task

Schedule work with this scope's lifetime and context.

close

Cancel owned work; calling this more than once is harmless.

Attributes:

Name Type Description
pending int

Number of unfinished tasks owned by this scope.

pending property

pending: int

Number of unfinished tasks owned by this scope.

create_task

create_task(
    awaitable: Awaitlike[T],
    *,
    report_errors: bool = False
) -> Any

Schedule work with this scope's lifetime and context.

close

close() -> None

Cancel owned work; calling this more than once is harmless.

start

start() -> AbstractEventLoop

Start the application thread once and return its event loop.

get_loop

get_loop() -> AbstractEventLoop

Return the application loop, or the caller's loop in headless mode.

run_async

run_async(awaitable: Awaitlike[T]) -> Any

Schedule work in the current component scope or the application scope.

Returns an asyncio task on the application thread and a concurrent future on other threads. Both handles support cancellation.

run_application_task

run_application_task(awaitable: Awaitlike[T]) -> Any

Start work that should survive the component that requested it.

invoke

invoke(
    callback: Callable[..., Any],
    *args: Any,
    scope: TaskScope | None = None
) -> Any

Invoke a callback and schedule an awaitable result in its owner's scope.

run_blocking

run_blocking(
    awaitable: Awaitlike[T], timeout: float | None = None
) -> T

Wait for work from synchronous code; never block the application loop.

drain

drain(
    timeout: float = 1.0,
    *,
    until: Callable[[], bool] | None = None
) -> bool

Settle headless work or wait for application tasks from a test thread.

Long-lived application tasks require an explicit until predicate. This uses public asyncio APIs and never inspects selector internals.

call_threadsafe

call_threadsafe(
    callback: Callable[..., Any], *args: Any
) -> None

Enqueue a callback on the application event loop from any thread.

call_on_application_thread

call_on_application_thread(fn: Callable[[], None]) -> None

Execute Python work on its owner thread, inline when already there.

resolve_future

resolve_future(future: Future[T], value: T) -> None

Complete a future from any thread unless it was cancelled.

reject_future

reject_future(
    future: Future[Any], error: BaseException
) -> None

Fail a future from any thread unless it was cancelled.

create_future

create_future() -> Future[Any]

Create a future for completion by a native request.