A universal Apple Push Notification Service (APNS) provider.
Features:
- REST interface so you can start sending notifications with any language immediately
- Native Python API included
- Scalable, fast and easy to distribute behind a proxy
- Multi-application and dual environment support
- Disconnection log interface which provides reasons for recent connection issues
- Supports the full suite of APN gateway functionality
Install and start the daemon:
$ sudo easy_install pyapns
$ wget https://raw.github.com/samuraisam/pyapns/master/pyapns.tac
$ twistd -ny pyapns.tac
Provision an app and send a notification:
$ curl -d '{"certificate":"/path/to/certificate.pem"}' \
http://localhost:8088/apps/com.example.app/sandbox
$ curl -d '{"token": "le_token", \
"payload": {"aps": {"alert": "Hello!"}}, \
"identifier": "xxx", "expiry": 0}' \
http://localhost:8088/apps/com.example.app/sandbox/notifications
pyapns is a daemon that is installed on a server and designed to take the pain out of sending push notifications to Apple devices. Typically your applications you will have a thread that maintains an SSL socket to Apple. This can be error-prone, hard to maintain and plainly a burden your app servers should not have to deal with.
Additionally, pyapns provides several features you just wouldn't get with other solutions such as the disconnection log which remembers which notifications and tokens caused disconnections with Apple - thus allowing your application layer to make decisions about whether or not th continue sending those types of notifications. This also works great as a debugging layer.
pyapns supports sending notifications to multiple applications each with multiple environments. This is handy so you don't have to push around your APN certificates, just keep them all local to your pyapns installation.
The rest interface is by default hosted on port 8088
and provides all of the functionality you'll need. Here are some basic things you need to know about how it works:
- All functionality is underneath the
/apps
top level path - Functionality specific to individual apps is available underneath the
/apps/{app id}/{environment}
path whereapp id
is the provisioned app id andenvironment
is the Apple environment (either "sandbox" or "production") - You can get a list of provisioned apps:
GET /apps
- Objects all have a
type
attribute that tells you which kind of object it is - Successful responses will have a top level object with a
response
andcode
keys - Unsuccessful responses will have a top level object with an
error
andcode
keys
Before sending notifications to devices, you must first upload your certificate file to the server so pyapns can successfully make a connection to the APN gateway. The certificates must be a PEM encoded file. This stackoverflow answer contains an easy way to accomplish that.
You can upload the PEM and provision the app multiple ways:
-
Send the PEM file directly when provisioning the apps. Just read the whole PEM file into memory and include it as the
certificate
key:$ curl -d '{"certificate": "$(cat /path/to/cert.pem)"}' $HOST:$PORT/apps/com.example.myid/production
-
Upload the PEM file ahead of time to the same server as the pyapns daemon and provide the path to the certificate as the
certificate
key:$ curl -d '{"certificate": "/path/to/cert.pem"}' $HOST:$PORT/apps/com.example.myid/production
Notice above that we are including in the URL the app id desired as well as the environment desired. They are the last and 2nd-to-last elements of the path, respectively. So for this url the app id is com.example.myid and the environment is production. Any time you access functionality specific to these apps you'll be accessing it as a subpath of this full path.
- GET /apps
-
Returns a list of all provisioned apps
Example Response
{ "response": [ { "type": "app", "certificate": "/path/to/cert.pem", "timeout": 15, "app_id": "my.app.id", "environment": "sandbox" } ], "code": 200 }
Returns information about a provisioned app
{
"response": {
"type": "app",
"certificate": "/path/to/cert.pem",
"timeout": 15,
"app_id": "my.app.id",
"environment": "sandbox"
},
"code": 200
}
Creates a newly provisioned app. You can POST multiple times to the same URL and it will merely re-provision the app, taking into account the new certificate and timeout. There may be more config values to provision in the future.
{
"certificate": "certificate or path to certificate",
"timeout": 15
}
{
"response": {
"type": "app",
"certificate": "/path/to/cert.pem",
"timeout": 15,
"app_id": "my.app.id",
"environment": "sandbox"
},
"code": 201
}
To install in production, you will want a few things that aren't covered in the quickstart above:
- Automated provisioning of apps. This is supported when the pyapns server is started up.
- Install python-epoll and ujson for dramatically improved performance
- (optional) start multiple instances behind a reverse proxy like HAProxy or Nginx