Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rest service, disconnect log and enhanced notifications #40

Open
wants to merge 51 commits into
base: master
Choose a base branch
from

Conversation

samuraisam
Copy link
Owner

Version .50 includes:

  • rest service - a simplified way to interface with pyapns
  • enhanced notification protocol - so you get those fancy disconnection reasons
  • and a way to get at those fancy disconnection reasons: disconnection log which will tell you when disconnections happend and what notifications/tokens caused them
  • native python client to the new REST service using the requests library

Fixes: #31 #26 #14

Todo:

  • docs
  • python client implementation using kennethreitz/requests

I also pep8-ified (much as possible) the old XML-RPC server and APN protocol code.

Rest Interface:

  • GET /apps

    Returns a list of available apps

  • POST /apps/:app id/:environment {"cert": "/path/to/cert or cert file itself","timeout":15}

    Provisions an app. You send it a dictionary with keys for cert and timeout

  • POST /apps/:app id/:environment [{"payload":{"alert":"abc"},"token":"tok","identifier":"ident","expiry":1234}]

    Sends a notification. You send it a list of dictionaries each with payload, token, identifier, and expiry keys

  • GET /apps/:app id/:environment/feedback

    Returns feedback directly from APN

  • GET /apps/:app id/:environment/disconnections

    Returns a list of the most recent 5000 disconnections paired with the reason and notification that caused the disconnection

@samuraisam
Copy link
Owner Author

All I need to do now is finish up the docs and I feel comfortable releasing this. We are using this branch in production @ Lightt.

@troppoli
Copy link

I've used this a bit for testing on a local machine and so far it has worked well. If anyone has any tips on deployment up on AWS I'd love to hear what environment is working for you and what your config files look like.

On Jan 30, 2013, at 12:09 PM, Samuel Sutch wrote:

All I need to do now is finish up the docs and I feel comfortable releasing this. We are using this branch in production @ Lightt.


Reply to this email directly or view it on GitHub.

@samuraisam
Copy link
Owner Author

@trippoli what is your target environment? At lightt we just have our machines point directly at the twisted process. In larger installations they distribute 4 twisted processes behind nginx or haproxy.

@troppoli
Copy link

troppoli commented Feb 1, 2013

Our backend runs on Google App Engine…

My current dev environment is running pyapns and app engine locally. Things are working well. So I'm looking to spin up a single APNS server up on AWS and point our production AppEngine push queue at it.

I'm just inexperienced with AWS configuration. It seems like firing up a single APNS server on one of their python beanstalks would be pretty straightforward for someone familiar with the AWS stack. From my reading it would seem that it should be entirely possible to get things setup to pull a git repo and fire it up if the proper configs were in place.

I was just suspecting that someone who is already using pyapns has a working example of a config I could start from.

-s

On Jan 31, 2013, at 6:54 PM, Samuel Sutch wrote:

@trippoli what is your target environment? At lightt we just have our machines point directly at the twisted process. In larger installations they distribute 4 twisted processes behind nginx or haproxy, with 4 config files each.


Reply to this email directly or view it on GitHub.

@troppoli
Copy link

troppoli commented Feb 7, 2013

Here's the sort of thing that would have gotten me going. It's my notes from getting our instance up:

Notes for getting pyapns up on e2c

This assumes you have:
0. Gotten pyapns running on a local machine and have tested you communication with pyapns

  1. Setup an AWS account
  2. Have installed the AWS CLTs and verified them
    http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/SettingUp_CommandLine.html#tools-introduction
  3. Setup a test instance by following:
    http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html
    This example used ubuntu 12.04
  4. You must be able to connect via SSH to the instance to continue.
  5. Setup the instance

In the ubuntu shell:

sudo apt-get install git
git clone -b v50 git://github.com/samuraisam/pyapns.git
sudo apt-get install python-pip
apt-get update
sudo apt-get install build-essential
sudo apt-get install python-dev
sudo pip install -r requirements.txt
cd pyapns
sudo python setup.py install

  1. Create your custom config
    Now you have the environment setup, but there isn't a working configuration in place. So locally make a copy of the 'pyapns.tac' file and rename it to 'application.tac'. Also make a copy of example_conf.json, call it application_config.json. Next edit the application.tac file to have the proper location of the newly created application_config.json file.

config_file = '/home/ubuntu/pyapns/application_config.json'

Next edit the application_config.json with your info and make paths like the config file path.

zip the items into a file called 'config.zip'

  1. Upload your config

from a local shell:
scp -i /.pem config.zip ubuntu@:~/pyapns

  1. Unpack the config
    sudo apt-get install unzip
    unzip config.zip
  2. Fire it up nondemon so you can easily see what's going on.
    twistd -ny application.tac

Correct any trouble with paths, if you see errors like:
OpenSSL.SSL.Error: [('system library', 'fopen', 'No such file or directory'), ('BIO routines', 'FILE_CTRL', 'system lib'), ('SSL routines', 'SSL_CTX_use_certificate_file', 'system lib')]

..then you have path problems.

Fire it up in the debugger if needed and poke around:
twistd -by application.tac

(Pdb) import pyapns
(Pdb) b /home/ubuntu/pyapns/pyapns/server.py:67
Breakpoint 1 at /home/ubuntu/pyapns/pyapns/server.py:67

  1. run as a demon
    twistd -y application.tac

-- this creates the pid file you can view via
cat /home/ubuntu/pyapns/twistd.pid

kill -s sigint

to shut it down

  1. Secure the connection
    whitelist the adress that will be talking to pyapns

On Jan 31, 2013, at 7:14 PM, Steven Troppoli wrote:

Our backend runs on Google App Engine…

My current dev environment is running pyapns and app engine locally. Things are working well. So I'm looking to spin up a single APNS server up on AWS and point our production AppEngine push queue at it.

I'm just inexperienced with AWS configuration. It seems like firing up a single APNS server on one of their python beanstalks would be pretty straightforward for someone familiar with the AWS stack. From my reading it would seem that it should be entirely possible to get things setup to pull a git repo and fire it up if the proper configs were in place.

I was just suspecting that someone who is already using pyapns has a working example of a config I could start from.

-s

On Jan 31, 2013, at 6:54 PM, Samuel Sutch wrote:

@trippoli what is your target environment? At lightt we just have our machines point directly at the twisted process. In larger installations they distribute 4 twisted processes behind nginx or haproxy, with 4 config files each.


Reply to this email directly or view it on GitHub.

@samuraisam
Copy link
Owner Author

Good point, if it doesn't already do this a pull request would be much appreciated!

Samuel Sutch and others added 10 commits April 30, 2013 15:54
Clear disconnection events after getting them
Fix a bug: ClientError __init__() needs 3 arguments
Add an option: bind pyapns to a specified IP address
Add options to config log file
The `ensure_ascii` kwarg in `json.dumps()` must be `True` (the
default) so that the subsequent UTF-8 encoding works correctly.
Add requests to setup.py, fix UTF-8 crash.
@ghost
Copy link

ghost commented Oct 3, 2013

Running this branch in development and encountered the following

  • 1 app auto provisioned in sandbox mode
  • looking to use batch submission to pyapns - currently testing with 13-16 devices
  • pyapns service was running for a couple hours without any requests
  • using REST API, posted a batch of 13 notifications - received 201 from pyapns, but notifications were not delivered to APNS
  • subsequent batch of notifications delivered to APNS without an issue
  • the first batch appears to have been accepted by pyapns, did not attempt to retry to send the batch, and did not appear in a /disconnects request

How should the client code handle this case?

log information:
2013-10-03 16:24:54-0400 [HTTPChannel,612,10.1.1.242] APNSProtocol sendMessage msg=.....

2013-10-03 16:24:54-0400 [HTTPChannel,612,10.1.1.242] 10.1.1.242 - - [03/Oct/2013:20:24:54 +0000] "POST /apps//sandbox/notifications HTTP/1.1" 201 26 "-" ""
2013-10-03 16:24:54-0400 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSProtocol connectionLost
2013-10-03 16:24:54-0400 [APNSProtocol (TLSMemoryBIOProtocol),client] APNSClientFactory clientConnectionLost reason=[Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion.
]
2013-10-03 16:24:54-0400 [APNSProtocol (TLSMemoryBIOProtocol),client] <twisted.internet.tcp.Connector instance at 0x21a5cf8> will retry in 3 seconds
2013-10-03 16:24:54-0400 [APNSProtocol (TLSMemoryBIOProtocol),client] Stopping factory <pyapns.server.APNSClientFactory instance at 0x21a5b48>
2013-10-03 16:24:57-0400 [-] Starting factory <pyapns.server.APNSClientFactory instance at 0x21a5b48>
2013-10-03 16:24:57-0400 [-] APNSClientFactory startedConnecting
2013-10-03 16:24:57-0400 [Uninitialized] APNSProtocol connectionMade

After reviewing the closed issues, I think the above use case is similar to
#54 - we are looking to deploy pyapns for over 50 apps where the frequency of the notifications is usually over 1hr in between.

Bill Davis and others added 6 commits October 16, 2013 09:30
…ablished for over an hour

without any activity. Reconnect to APNS if the connection has been established for an hour
prior to writing.
Add call to stopTrying on the APNSClientFactory (ReconnectingClientFactory) in the timed
disconnect portion of the code.  If this call is not made, the reconnecting code will
reconnect to Apple and the connection is left unreferenced. This can cause an issue
with 'Too many open files'.
Fix for leaking file descriptor issue
@rdpfeffer
Copy link

Its unclear to me at this moment what the outstanding issues are in getting this branch merged back into master. Can anyone who's more familiar give an update?

@samuraisam
Copy link
Owner Author

Primarily documentation

@omenar
Copy link

omenar commented May 12, 2014

You need help with something? I would be more than happy to help documenting stuff :)

@samuraisam
Copy link
Owner Author

Yeah! I wish I had time to do this stuff:

If you look at the README in this branch vs master you can sort of tell where it's lacking.

Specifically we need docs for all of the REST endpoints, how this version differs from master, and how to upgrade from this version to the last.

@faizanaziz
Copy link

Hi... This stuff is really nice, do you know approximately how long a release would take?

@samuraisam
Copy link
Owner Author

If I had the time (or my time could be bought) it would take me no more than a day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants