{"id":4182,"library":"pyapns-client","title":"pyapns-client: Apple Push Notifications (HTTP/2)","description":"pyapns-client is a Python library designed for sending Apple Push Notifications (APNs) to iOS, macOS, and Safari using the modern HTTP/2 Push provider API. It focuses on simplicity, flexibility, and speed, leveraging token-based authentication for enhanced security and avoiding certificate renewal hassles. The current version is 2.0.6, with a more recent async-enabled version (pyapns-client3) also available. This library is actively maintained, with the latest update for the 2.x series in June 2022.","status":"active","version":"2.0.6","language":"en","source_language":"en","source_url":"https://github.com/kukosk/pyapns_client","tags":["Apple Push Notifications","APNs","iOS","macOS","Safari","HTTP/2","Push Notifications","Mobile Development"],"install":[{"cmd":"pip install pyapns-client","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Used as the underlying HTTP client for APNs HTTP/2 communication.","package":"httpx","optional":false}],"imports":[{"symbol":"APNSClient","correct":"from pyapns_client import APNSClient"},{"symbol":"IOSPayloadAlert","correct":"from pyapns_client import IOSPayloadAlert"},{"symbol":"IOSPayload","correct":"from pyapns_client import IOSPayload"},{"symbol":"IOSNotification","correct":"from pyapns_client import IOSNotification"},{"symbol":"APNSDeviceException","correct":"from pyapns_client import APNSDeviceException"},{"symbol":"APNSServerException","correct":"from pyapns_client import APNSServerException"},{"symbol":"APNSProgrammingException","correct":"from pyapns_client import APNSProgrammingException"},{"symbol":"UnregisteredException","correct":"from pyapns_client import UnregisteredException"}],"quickstart":{"code":"import os\nfrom pyapns_client import APNSClient, IOSPayloadAlert, IOSPayload, IOSNotification, APNSDeviceException, APNSServerException, APNSProgrammingException, UnregisteredException\n\n# --- Environment Variables (Replace with your actual values or secure fetching) ---\n# APNS_MODE: APNSClient.MODE_DEV or APNSClient.MODE_PROD\n# APNS_AUTH_KEY_PATH: Path to your .p8 authentication key file\n# APNS_AUTH_KEY_ID: Your 10-character Key ID from Apple Developer portal\n# APNS_TEAM_ID: Your 10-character Team ID from Apple Developer portal\n# APNS_ROOT_CERT_PATH: Path to Apple's root certificate (e.g., AppleWWDRCA.pem or AAACertificateServices.pem)\n#                      Can be None if included in your system's trust store or not strictly required for token-based auth.\n\nAPNS_MODE = os.environ.get('APNS_MODE', APNSClient.MODE_DEV) # Use MODE_PROD for production\nAPNS_AUTH_KEY_PATH = os.environ.get('APNS_AUTH_KEY_PATH', 'path/to/AuthKey_YOURKEYID.p8')\nAPNS_AUTH_KEY_ID = os.environ.get('APNS_AUTH_KEY_ID', 'YOURKEYID')\nAPNS_TEAM_ID = os.environ.get('APNS_TEAM_ID', 'YOURTEAMID')\nAPNS_ROOT_CERT_PATH = os.environ.get('APNS_ROOT_CERT_PATH', None) # Or 'path/to/AAACertificateServices.pem'\n\ndevice_token = os.environ.get('DEVICE_TOKEN', 'a_sample_device_token_hex_string')\nAPP_BUNDLE_ID = os.environ.get('APP_BUNDLE_ID', 'com.example.yourapp')\n\nif APNS_ROOT_CERT_PATH and not os.path.exists(APNS_ROOT_CERT_PATH):\n    print(f\"Warning: APNS_ROOT_CERT_PATH '{APNS_ROOT_CERT_PATH}' not found. Set it correctly or None.\")\n\nif not os.path.exists(APNS_AUTH_KEY_PATH):\n    print(f\"Error: APNS_AUTH_KEY_PATH '{APNS_AUTH_KEY_PATH}' not found. Please provide a valid path to your .p8 key.\")\n    exit(1)\n\ntry:\n    # Initialize the client using token-based authentication\n    client = APNSClient(\n        mode=APNS_MODE,\n        auth_key_path=APNS_AUTH_KEY_PATH,\n        auth_key_id=APNS_AUTH_KEY_ID,\n        team_id=APNS_TEAM_ID,\n        root_cert_path=APNS_ROOT_CERT_PATH # Optional, depends on your trust store setup\n    )\n\n    # Create the notification payload\n    alert = IOSPayloadAlert(title='Hello from pyapns-client!', subtitle='New Message', body='This is a test push notification.')\n    payload = IOSPayload(alert=alert, badge=1, sound='default')\n\n    # Create the notification object\n    notification = IOSNotification(payload=payload, topic=APP_BUNDLE_ID)\n\n    print(f\"Attempting to push notification to device: {device_token}\")\n    # Send the notification\n    client.push(notification=notification, device_token=device_token)\n    print(\"Notification sent successfully!\")\n\nexcept UnregisteredException as e:\n    print(f\"Device is unregistered: {e.device_token}. Remove from DB. Timestamp: {e.timestamp_datetime}\")\nexcept APNSDeviceException as e:\n    print(f\"Device error for {e.device_token}: {e.reason}. Flag device as invalid.\")\nexcept APNSServerException as e:\n    print(f\"APNs server error: {e.reason}. Try again later.\")\nexcept APNSProgrammingException as e:\n    print(f\"Programming error: {e.reason}. Check your code and APNs settings.\")\nexcept Exception as e:\n    print(f\"An unexpected error occurred: {e}\")\n","lang":"python","description":"This quickstart demonstrates how to send a basic push notification using token-based authentication with `pyapns-client`. It leverages environment variables for sensitive credentials and includes essential error handling for common APNs responses. Ensure you replace placeholder values with your actual Apple Developer details and a valid device token. The `topic` parameter must match your application's bundle ID."},"warnings":[{"fix":"Upgrade your Python environment to 3.6 or newer. If on an older system, consider using a different APNs library or updating your infrastructure.","message":"This library requires Python 3.6 or higher. Older Python 2.x environments or Python 3.5 and below are not supported.","severity":"breaking","affected_versions":"<2.0.0 (and Python <3.6)"},{"fix":"Verify your app's bundle ID in Xcode or your Apple Developer account and ensure it's passed correctly as the `topic` argument.","message":"The `topic` parameter in `IOSNotification` *must* precisely match your application's bundle ID (e.g., 'com.example.yourapp'). A mismatch will result in push delivery failures.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure you are using an up-to-date APNs client library like `pyapns-client` that supports the HTTP/2 API and token-based authentication.","message":"This library (pyapns-client) uses Apple's HTTP/2 APNs API with token-based authentication. Apple deprecated the legacy binary API in late 2019. Using older APNs libraries that rely on the binary API or only certificate-based authentication (without JWT tokens) is highly discouraged and may cease to function.","severity":"deprecated","affected_versions":"Libraries using the binary API (not pyapns-client)"},{"fix":"Implement comprehensive `try-except` blocks for `UnregisteredException`, `APNSDeviceException`, `APNSServerException`, and `APNSProgrammingException` to manage device tokens (remove unregistered ones), retry server failures, and debug programming errors effectively.","message":"APNs responses require robust error handling. Device tokens can become invalid (e.g., app uninstalled), leading to `UnregisteredException`. Server issues (e.g., throttling) can cause `APNSServerException`. Incorrect payload or settings will raise `APNSProgrammingException`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Keep your notification payload as concise as possible. If sending large data, consider notifying the app to fetch content from your server instead of including it directly in the push payload.","message":"The APNs payload has size limits (4KB for most notifications, 5KB for VoIP). Exceeding this limit will result in delivery failure without a clear error from the client library.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}