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. |
create_task
¶
Schedule work with this scope's lifetime and context.
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 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
¶
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
¶
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.