Notifications¶
Notifications schedules local
notifications and reports when they arrive or get tapped. Enable it with
use = ["notifications"] under [plugins] and notifications = true under
[permissions]. See the Notifications guide.
Local notifications: schedule them, and hear when they arrive or get tapped.
Enable it in pythonnative.toml:
[plugins]
use = ["notifications"]
[permissions]
notifications = true
[plugins.notifications]
android_icon = "assets/notification.png" # optional; defaults to the app's icon
Call await Notifications.request_permission() before scheduling on either
platform. Android delayed notifications use OS-owned, inexact alarms and survive
ordinary process death. Power management may defer delivery, and reboot,
force-stop, and app removal clear them.
Events that arrive before Python subscribes wait in native code, so a tap that
launches the app reaches the first on_response subscriber, and
last_response() answers during the first render.
Example
from pythonnative.notifications import Notifications, NotificationResponse
def open_entry(response: NotificationResponse) -> None:
navigate_to(response.data["entry"])
if launch := Notifications.last_response():
open_entry(launch)
Notifications.on_response(open_entry)
async def remind() -> None:
if await Notifications.request_permission():
await Notifications.schedule(
"Reminder",
"Time for a walk!",
delay_seconds=60,
identifier="walk",
data={"entry": 42},
)
Classes:
| Name | Description |
|---|---|
ReceivedNotification |
A notification that arrived while the app was in the foreground. |
NotificationResponse |
The user's interaction with a notification. |
Notifications |
Local notification interface. |
ReceivedNotification
dataclass
¶
ReceivedNotification(
identifier: str,
title: str = "",
body: str = "",
data: Dict[str, Any] = dict(),
)
A notification that arrived while the app was in the foreground.
Attributes:
| Name | Type | Description |
|---|---|---|
identifier |
str
|
The identifier it was scheduled with. A remote push has one the system or the push service chose. |
title |
str
|
The title. |
body |
str
|
The body text. |
data |
Dict[str, Any]
|
The |
NotificationResponse
dataclass
¶
NotificationResponse(
identifier: str,
title: str = "",
body: str = "",
data: Dict[str, Any] = dict(),
action: str = "default",
)
The user's interaction with a notification.
Attributes:
| Name | Type | Description |
|---|---|---|
identifier |
str
|
The identifier it was scheduled with. A remote push has one the system or the push service chose. |
title |
str
|
The title. Empty for an Android push tapped while the app was in the background, because the system doesn't hand it to the app. |
body |
str
|
The body text, with the same limit as |
data |
Dict[str, Any]
|
The |
action |
str
|
|
Notifications
¶
Local notification interface.
Raises:
| Type | Description |
|---|---|
NativeModuleError
|
If the native module fails, or with the code
|
Methods:
| Name | Description |
|---|---|
request_permission |
Request notification permission from the user. |
schedule |
Schedule a local notification, replacing a pending one with the same identifier. |
cancel |
Cancel a notification by identifier, pending or delivered (a no-op when there's none). |
cancel_all |
Cancel every pending notification and remove every delivered one. |
set_badge |
Set the number on the app icon, where |
on_received |
Call |
on_response |
Call |
last_response |
Return the tap that launched the app from cold, if one did. |
request_permission
async
staticmethod
¶
request_permission() -> bool
Request notification permission from the user.
Android 13 (API 33) and up show the POST_NOTIFICATIONS prompt if
the user hasn't decided. Below that, this reports whether notifications
are enabled for the app, without prompting.
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
declined (always |
schedule
async
staticmethod
¶
schedule(
title: str,
body: str = "",
*,
delay_seconds: float = 0,
identifier: str = "default",
data: Optional[Mapping[str, Any]] = None,
badge: Optional[int] = None,
sound: bool = True
) -> bool
Schedule a local notification, replacing a pending one with the same identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Notification title. |
required |
body
|
str
|
Notification body text. |
''
|
delay_seconds
|
float
|
Seconds from now until delivery. |
0
|
identifier
|
str
|
Stable ID that
|
'default'
|
data
|
Optional[Mapping[str, Any]]
|
JSON-compatible values handed back in
|
None
|
badge
|
Optional[int]
|
On iOS, the number to put on the app icon when it arrives. On Android, the count launchers that show one may use. |
None
|
sound
|
bool
|
Whether to play the default notification sound. |
True
|
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
isn't granted (so nothing was scheduled). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
cancel
async
staticmethod
¶
cancel(identifier: str = 'default') -> None
Cancel a notification by identifier, pending or delivered (a no-op when there's none).
cancel_all
async
staticmethod
¶
Cancel every pending notification and remove every delivered one.
set_badge
async
staticmethod
¶
set_badge(count: int) -> None
Set the number on the app icon, where 0 clears it.
iOS only: Android has no API that sets a launcher badge. Pass badge
to schedule there.
Raises:
| Type | Description |
|---|---|
NativeModuleError
|
With the code |
ValueError
|
If |
on_received
staticmethod
¶
on_received(
callback: Callable[[ReceivedNotification], None],
) -> Callable[[], None]
Call callback for each notification that arrives while the app is in the foreground.
The notification still appears, as a banner on iOS and in the shade on Android. In the background the system shows it without telling the app. Arrivals from before the first subscriber are delivered to it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
Callable[[ReceivedNotification], None]
|
Receives a
|
required |
Returns:
| Type | Description |
|---|---|
Callable[[], None]
|
A zero-argument function that unsubscribes. |
on_response
staticmethod
¶
on_response(
callback: Callable[[NotificationResponse], None],
) -> Callable[[], None]
Call callback each time the user taps a notification.
Taps from before the first subscriber are delivered to it, including
the one that launched the app, unless
last_response
already returned that tap. So read last_response first and then
subscribe, and each tap is handled once.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
Callable[[NotificationResponse], None]
|
Receives a
|
required |
Returns:
| Type | Description |
|---|---|
Callable[[], None]
|
A zero-argument function that unsubscribes. |
last_response
staticmethod
¶
last_response() -> Optional[NotificationResponse]
Return the tap that launched the app from cold, if one did.
It keeps returning that tap for the life of the process, so a screen
can read it during its first render. Later taps go to
on_response.
Returns:
| Type | Description |
|---|---|
Optional[NotificationResponse]
|
The launching tap, or |