APNs2 Python Library
raw JSON → 0.7.2 verified Tue Apr 14 auth: no python
apns2 is a Python library for interacting with the Apple Push Notification Service (APNs) using the HTTP/2 protocol. It supports both certificate-based and token-based authentication. The current version is 0.7.2, with development showing sporadic updates, often addressing dependency compatibility and APNs specification changes.
pip install apns2 Common errors
error ModuleNotFoundError: No module named 'apns2' ↓
cause The 'apns2' module is not installed in the Python environment.
fix
Install the 'apns2' module using pip: 'pip install apns2'.
error AttributeError: 'APNsClient' object has no attribute 'send_notification' ↓
cause The 'APNsClient' class does not have a method named 'send_notification'.
fix
Use the correct method 'send_notification' provided by the 'APNsClient' class.
error ImportError: cannot import name 'APNsClient' from 'apns2' ↓
cause The 'APNsClient' class is not available in the 'apns2' module.
fix
Ensure you are using the correct import statement: 'from apns2.client import APNsClient'.
error TypeError: __init__() missing 1 required positional argument: 'credentials' ↓
cause The 'APNsClient' constructor requires a 'credentials' argument that was not provided.
fix
Provide the necessary 'credentials' argument when initializing 'APNsClient'.
error ValueError: Invalid device token ↓
cause The device token provided is not valid.
fix
Verify that the device token is correct and properly formatted.
Warnings
breaking The library has a strict dependency on `PyJWT<2.0.0`. Installing or having other packages that require `PyJWT` version 2.0.0 or higher will lead to compatibility issues and runtime errors. ↓
fix Ensure your environment or `requirements.txt` explicitly specifies `PyJWT<2.0.0`. If other libraries demand `PyJWT>=2.0.0`, consider using a dedicated virtual environment or finding an alternative for APNs if upgrading `apns2` is not an option.
breaking As of version 0.6.0, `apns2` officially dropped support for Python 2.7 and Python 3.4. Users on these Python versions must either upgrade their Python environment or use an older version of `apns2`. ↓
fix Upgrade your Python interpreter to Python 3.5 or newer.
deprecated Apple officially deprecated the legacy binary APNs protocol (certificate-based authentication) on March 31, 2021, in favor of the HTTP/2 API with token-based authentication. While `apns2` supports both, new implementations and existing ones should migrate to token-based authentication. ↓
fix Switch to token-based authentication using `TokenCredentials` as shown in the quickstart example. This requires an authentication key (.p8 file), Key ID, and Team ID from your Apple Developer account.
gotcha The default JWT token lifetime (`DEFAULT_TOKEN_LIFETIME`) was changed from 3600 seconds (1 hour) to 2700 seconds (45 minutes) in version 0.7.2. This aligns with Apple's recommendation to refresh tokens frequently (typically within one hour) to avoid `ExpiredProviderToken` errors. Additionally, in versions prior to 0.7.2, custom JWT lifetimes passed to `TokenCredentials` might have been ignored. ↓
fix Ensure your token generation logic and client configurations are aware of the shorter default lifetime. If you rely on custom JWT lifetimes, upgrade to 0.7.2 or newer to ensure they are respected.
gotcha Since version 0.7.0, `apns2` attempts to infer the `apns-push-type` header from the push topic or payload. While an option to override this header exists, automatic inference might lead to unexpected behavior if specific push types are required without explicit setting. ↓
fix If precise control over the `apns-push-type` header is needed, explicitly set it in your `Payload` or `Notification` object when sending.
Imports
- APNsClient
from apns2.client import APNsClient - Payload
from apns2.payload import Payload - TokenCredentials
from apns2.credentials import TokenCredentials
Quickstart
import os
from apns2.client import APNsClient
from apns2.payload import Payload
from apns2.credentials import TokenCredentials
# Environment variables for token-based authentication
# Set these in your environment or replace with actual values for testing
AUTH_KEY_PATH = os.environ.get('APNS_AUTH_KEY_PATH', 'path/to/AuthKey_ABCDEFG.p8')
AUTH_KEY_ID = os.environ.get('APNS_AUTH_KEY_ID', 'ABCDEFG')
TEAM_ID = os.environ.get('APNS_TEAM_ID', 'XXXXXXXXXX')
DEVICE_TOKEN = os.environ.get('APNS_DEVICE_TOKEN', 'your_device_token_here')
APP_BUNDLE_ID = os.environ.get('APNS_APP_BUNDLE_ID', 'com.example.YourApp')
if AUTH_KEY_PATH == 'path/to/AuthKey_ABCDEFG.p8' or \
AUTH_KEY_ID == 'ABCDEFG' or \
TEAM_ID == 'XXXXXXXXXX' or \
DEVICE_TOKEN == 'your_device_token_here' or \
APP_BUNDLE_ID == 'com.example.YourApp':
print("WARNING: Please configure APNS_AUTH_KEY_PATH, APNS_AUTH_KEY_ID, APNS_TEAM_ID, APNS_DEVICE_TOKEN, and APNS_APP_BUNDLE_ID environment variables or replace placeholders in the script.")
# Exit or use dummy values for demonstration if actual push is not intended
# For a runnable example without valid credentials, one might comment out the actual send_notification call
# For this registry, we will print a warning and allow it to run potentially failing.
try:
# Initialize TokenCredentials
credentials = TokenCredentials(
auth_key_path=AUTH_KEY_PATH,
auth_key_id=AUTH_KEY_ID,
team_id=TEAM_ID
)
# Initialize APNsClient with token credentials
# For development (sandbox) environment, use_sandbox=True
client = APNsClient(credentials=credentials, use_sandbox=True) # Set to False for production
# Create a push notification payload
payload = Payload(alert="Hello from apns2!", sound="default", badge=1)
# Send the notification
response = client.send_notification(DEVICE_TOKEN, payload, APP_BUNDLE_ID)
print(f"APNs Response Status: {response.status}")
print(f"APNs Response Reason: {response.reason}")
if response.apns_id: # Optional, depending on library version/response structure
print(f"APNs ID: {response.apns_id}")
except Exception as e:
print(f"An error occurred: {e}")