apnsclient Package¶
Apple Push Notification service client. Only public API is documented here to limit visual clutter. Refer to the sources if you want to extend this library. Check Getting Started for usage examples.
apnsclient
Package¶
-
class
apnsclient.transport.
Session
(pool='apnsclient.backends.stdio', connect_timeout=10, write_buffer_size=2048, write_timeout=20, read_buffer_size=2048, read_timeout=20, read_tail_timeout=3, **pool_options)¶ The front-end to the underlying connection pool. The purpose of this class is to hide the transport implementation that is being used for networking. Default implementation uses built-in python sockets and
select
for asynchronous IO.Arguments: - pool (str, type or object): networking layer implementation.
- connect_timeout (float): timeout for new connections.
- write_buffer_size (int): chunk size for sending the message.
- write_timeout (float): maximum time to send single chunk in seconds.
- read_buffer_size (int): feedback buffer size for reading.
- read_timeout (float): timeout for reading single feedback block.
- read_tail_timeout (float): timeout for reading status frame after message is sent.
- pool_options (kwargs): passed as-is to the pool class on instantiation.
-
get_connection
(address='push_sanbox', certificate=None, **cert_params)¶ Obtain cached connection to APNs.
Session caches connection descriptors, that remain open after use. Caching saves SSL handshaking time. Handshaking is lazy, it will be performed on first message send.
You can provide APNs address as
(hostname, port)
tuple or as one of the strings:- push_sanbox –
("gateway.sandbox.push.apple.com", 2195)
, the default. - push_production –
("gateway.push.apple.com", 2195)
- feedback_sandbox –
("feedback.sandbox.push.apple.com", 2196)
- feedback_production –
("feedback.push.apple.com", 2196)
Arguments: - address (str or tuple): target address.
- certificate (
BaseCertificate
): provider’s certificate instance. - cert_params (kwargs):
BaseCertificate
arguments, used ifcertificate
instance is not given.
- push_sanbox –
-
new_connection
(address='feedback_sandbox', certificate=None, **cert_params)¶ Obtain new connection to APNs. This method will not re-use existing connection from the pool. The connection will be closed after use.
Unlike
get_connection()
this method does not cache the connection. Use it to fetch feedback from APNs and then close when you are done.Arguments: - address (str or tuple): target address.
- certificate (
BaseCertificate
): provider’s certificate instance. - cert_params (kwargs):
BaseCertificate
arguments, used ifcertificate
instance is not given.
-
outdate
(delta)¶ Close open unused connections in the pool that are left untouched for more than
delta
time.You may call this method in a separate thread or run it in some periodic task. If you don’t, then all connections will remain open until session is shut down. It might be an issue if you care about your open server connections.
Arguments: delta ( timedelta
): maximum age of unused connection.
-
shutdown
()¶ Shutdown all connections in the pool. This method does will not close connections being use at the calling time.
-
class
apnsclient.apns.
APNs
(connection)¶ APNs client.
Arguments: - connection (
Connection
): the connection to talk to.
-
feedback
()¶ Fetch feedback from APNs.
The method returns generator of
(token, datetime)
pairs, denoting the timestamp when APNs has detected the device token is not available anymore, probably because application was uninstalled. You have to stop sending notifications to that device token unless it has been re-registered since reported timestamp.Unlike sending the message, you should fetch the feedback using non-cached connection. Once whole feedback has been read, this method will automatically close the connection.
Note
If the client fails to connect to APNs, probably because your network is down, then this method will raise the related exception. However, if connection is successfully established, but later on the IO fails, then this method will simply stop iterating. The rest of the failed tokens will be delivered during the next feedback session.
Example:
session = Session() # get non-cached connection, free from possible garbage con = session.new_connection("feedback_production", cert_string=db_certificate) service = APNs(con) try: # on any IO failure after successfull connection this generator # will simply stop iterating. you will pick the rest of the tokens # during next feedback session. for token, when in service.feedback(): # every time a devices sends you a token, you should store # {token: given_token, last_update: datetime.datetime.now()} last_update = get_last_update_of_token(token) if last_update < when: # the token wasn't updated after the failure has # been reported, so the token is invalid and you should # stop sending messages to it. remove_token(token) except: print "Check your network, I could not connect to APNs"
Returns: generator over (binary, datetime)
-
send
(message)¶ Send the message.
The method will block until the whole message is sent. The method returns
Result
object, which you can examine for possible errors and retry attempts.Note
If the client fails to connect to APNs, probably because your network is down, then this method will raise the related exception. However, if connection is successfully established, but later on the IO fails, then this method will prepare a retry message with the rest of the failed tokens.
Example:
# if you use cached connections, then store this session instance # somewhere global, such that it will not be garbage collected # after message is sent. session = Session() # get a cached connection, avoiding unnecessary SSL handshake con = session.get_connection("push_production", cert_string=db_certificate) message = Message(["token 1", "token 2"], alert="Message") service = APNs(con) try: result = service.send(message) except: print "Check your network, I could not connect to APNs" else: for token, (reason, explanation) in result.failed.items(): delete_token(token) # stop using that token for reason, explanation in result.errors: pass # handle generic errors if result.needs_retry(): # extract failed tokens as new message message = message.retry() # re-schedule task with the new message after some delay
Returns: Result
object with operation results.
- connection (
-
class
apnsclient.apns.
Message
(tokens, alert=None, badge=None, sound=None, content_available=None, expiry=None, payload=None, priority=10, extra=None, **extra_kwargs)¶ The push notification to one or more device tokens.
Read more about the payload.
Note
In order to stay future compatible this class doesn’t transform provided arguments in any way. It is your responsibility to provide correct values and ensure the payload does not exceed the limit of 256 bytes. You can also generate whole payload yourself and provide it via
payload
argument. The payload will be parsed to init default fields like alert and badge. However if parsing fails, then these standard fields will become unavailable. If raw payload is provided, then other data fields like alert or sound are not allowed.Arguments: - tokens (str or list): set of device tokens where to the message will be sent.
- alert (str or dict): the message; read APNs manual for recognized dict keys.
- badge (int or str): badge number over the application icon or special value such as “increment”.
- sound (str): sound file to play on arrival.
- content_available (int): set to 1 to indicate new content is available.
- expiry (int, datetime or timedelta): timestamp when message will expire.
- payload (dict or str): JSON-compatible dictionary with the
- complete message payload. If supplied, it is given instead of all the other, more specific parameters.
- priority (int): priority of the message, defaults to 10
- extra (dict): extra payload key-value pairs.
- extra_kwargs (kwargs): extra payload key-value paris, will be merged with
extra
.
-
__getstate__
()¶ Returns
dict
with__init__
arguments.If you use
pickle
, then simply pickle/unpickle the message object. If you use something else, like JSON, then:# obtain state dict from message state = message.__getstate__() # send/store the state # recover state and restore message message_copy = Message(**state)
Note
The message keeps
expiry
internally as a timestamp (integer). So, if values of all other arguments are JSON serializable, then the returned state must be JSON serializable. If you getTypeError
when you instantiateMessage
from JSON recovered state, then make sure the keys arestr
, notunicode
.Returns: kwargs for Message constructor.
-
tokens
¶ List target device tokens.
-
class
apnsclient.apns.
Result
(message, failure=None)¶ Result of send operation.
-
errors
¶ Returns list of
(reason, explanation)
pairs denoting severe errors, not related to failed tokens. The reason is an integer code as described in APNs tutorial.- The following codes are considered to be errors:
(1, "Processing error")
(3, "Missing topic")
(4, "Missing payload")
(6, "Invalid topic size")
(7, "Invalid payload size")
(None, "Unknown")
, usually some kind of IO failure.
-
failed
¶ Reports failed tokens as
{token : (reason, explanation)}
mapping.Current APNs protocols bails out on first failed device token, so the returned dict will contain at most 1 entry. Future extensions may upgrade to multiple failures in a batch. The reason is the integer code as described in APNs tutorial.
- The following codes are considered to be token failures:
(2, "Missing device token")
(5, "Invalid token size")
(8, "Invalid token")
-
needs_retry
()¶ Returns True if there are tokens that should be retried.
Note
In most cases if
needs_retry
is true, then the reason of incomplete batch is to be found inerrors
andfailed
properties. However, Apple added recently a special code 10 - Shutdown, which indicates server went into a maintenance mode before the batch completed. This response is not really an error, so the before mentioned properties will be empty, whileneeds_retry
will be true.
-