Skip to content
This repository has been archived by the owner on Aug 29, 2019. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Russ P committed Nov 19, 2010
0 parents commit 0a51ea7
Show file tree
Hide file tree
Showing 40 changed files with 758 additions and 0 deletions.
111 changes: 111 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
About
-----

The AWeber API Python Library allows you to quickly get up and running with
integrating access to the AWeber API into your Python applications. This
egg requires the python-oauth2 to handle the authentication.

Installation
============

This egg can be installed by checking out the source::

$ sudo python setup.py install

Or from Pypi::

$ easy_install -U aweber_api

Usage
=====

To connect the AWeber API Python Libray, you simply include the main class,
AWeberAPI in your application, then create an instace of it with your
application's consumer key and secret::

from aweber import AWeberAPI
aweber = AWeberAPI(consumer_key, consumer_secret)
account = aweber.get_account(access_token, token_secret)

for list in account.lists:
print list.name


Getting request tokens / access tokens
++++++++++++++++++++++++++++++++++++++

You can also use the AWeberAPI object to handle retrieving request tokens::

from aweber import AWeberAPI
aweber = AWeberAPI(consumer_key, consumer_secret)
request_token, request_token_secret = aweber.get_request_token(callback_url)
print aweber.authorize_url

As well as access tokens::

from aweber import AWeberAPI
aweber = AWeberAPI(consumer_key, consumer_secret)
aweber.user.verifier = verifier
aweber.user.request_token = request_token
aweber.user.token_secret = request_token_secret
access_token, access_token_secret = aweber.get_access_token()


Full Pylons example
+++++++++++++++++++

Here is a simple Pylons example that uses the AWeber API Python Library to get
a request token, have it authorized, and then print some basic stats about the
web forms in that user's first list::

from pylons import session, request, tmpl_context as c
from pylons.controllers.util import redirect

from awebertest.lib.base import BaseController, render

from aweber_api import AWeberAPI

url = 'http://localhost:5000'
consumer_key = "vjckgsr5y4gfOa3PWnf"
consumer_secret = "u3sQ7vGGJBfds4q5dfgsTESi685c5x2wm6gZuIj"
class DemoController(BaseController):

def __before__(self):
self.aweber = AWeberAPI(consumer_key, consumer_secret)

def index(self):
token, secret = self.aweber.get_request_token(url+'/demo/get_access')
session['request_token_secret'] = secret
session.save()
redirect(self.aweber.authorize_url)

def get_access(self):
self.aweber.user.request_token = request.params['oauth_token']
self.aweber.user.token_secret = session['request_token_secret']
self.aweber.user.verifier = request.params['oauth_verifier']
session['token'], session['secret'] = self.aweber.get_access_token()
session.save()
redirect(url+'/demo/show')

def show(self):
c.account = self.aweber.get_account(session['token'], session['secret'])
return render('data.mako')


In `data.mako`::

<!DOCTYPE html>
<html lang="en">
<body>
<h1>Web Forms</h1>
% for list in c.account.lists:
<b>List Id:</b> ${list.id}, name: ${list.name}<br />
<b>Currently has:</b> ${len(list.web_forms)} web forms
<ul>
% for form in list.web_forms:
<li>Form Id: ${form.id}, name: ${form.name}</li>
% endfor
</ul>
% endfor
</body>
</html>
10 changes: 10 additions & 0 deletions aweber_api.egg-info/PKG-INFO
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Metadata-Version: 1.0
Name: aweber-api
Version: 1.0.0
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN
11 changes: 11 additions & 0 deletions aweber_api.egg-info/SOURCES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
setup.py
aweber_api/__init__.py
aweber_api/base.py
aweber_api/collection.py
aweber_api/entry.py
aweber_api/oauth.py
aweber_api/response.py
aweber_api.egg-info/PKG-INFO
aweber_api.egg-info/SOURCES.txt
aweber_api.egg-info/dependency_links.txt
aweber_api.egg-info/top_level.txt
1 change: 1 addition & 0 deletions aweber_api.egg-info/dependency_links.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions aweber_api.egg-info/top_level.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aweber_api
Binary file added aweber_api/.base.py.swp
Binary file not shown.
Binary file added aweber_api/.collection.py.swp
Binary file not shown.
Binary file added aweber_api/.entry.py.swp
Binary file not shown.
Binary file added aweber_api/.oauth.py.swp
Binary file not shown.
Binary file added aweber_api/.response.py.swp
Binary file not shown.
99 changes: 99 additions & 0 deletions aweber_api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from urlparse import parse_qs

from aweber_api.base import (AWeberBase, API_BASE, ACCESS_TOKEN_URL,
REQUEST_TOKEN_URL, AUTHORIZE_URL)
from aweber_api.collection import AWeberCollection
from aweber_api.entry import AWeberEntry
from aweber_api.oauth import OAuthAdapter
from aweber_api.response import AWeberResponse

class AWeberAPI(AWeberBase):
""" Base class for connecting to the AWeberAPI. Created with a consumer key
and secret, then used to either generate tokens for authorizing a user, or
can be provided tokens and used to access that user's resources. """

def __init__(self, consumer_key, consumer_secret):
self.adapter = OAuthAdapter(consumer_key, consumer_secret, API_BASE)
self.adapter.user = AWeberUser()

@property
def authorize_url(self):
"""
Returns the authorize url, potentially containing the request token
parameter
"""
if self.user.request_token:
return "{0}?oauth_token={1}".format(AUTHORIZE_URL,
self.user.request_token)
return AUTHORIZE_URL

def get_request_token(self, callback_url):
"""
Gets a new request token / token secret for the given callback URL
and the current consumer. Returns token / secret, and sets properties
on the AWeberUser object (self.user)
"""
data = { 'oauth_callback' : callback_url }
response = self.adapter.request('POST',
REQUEST_TOKEN_URL,
data)
self.user.request_token, self.user.token_secret = self.\
_parse_token_response(response)
return (self.user.request_token, self.user.token_secret)

def get_access_token(self):
"""
Gets an access token for the given request token / token secret /
verifier combination in the AWeberUser object at self.user
Updates the user object and returns the tokens
"""

data = { 'oauth_verifier' : self.user.verifier }
response = self.adapter.request('POST',
ACCESS_TOKEN_URL,
data)
self.user.access_token, self.user.token_secret = self.\
_parse_token_response(response)
return (self.user.access_token, self.user.token_secret)

def _parse_token_response(self, response):
if not type(response) == str:
raise TypeError('Expected response to be a string')

data = parse_qs(response)

if not 'oauth_token' in data and not 'oauth_token_secret' in data:
raise ValueError('OAuth parameters not returned')
return (data['oauth_token'][0], data['oauth_token_secret'][0])

def get_account(self, access_token=False, token_secret=False):
"""
Returns the AWeberEntry object for the account specified by the
access_token and token_secret currently in the self.user object.
Optionally, access_token and token_secret can be provided to replace
the properties in self.user.access_token and self.user.token_secret,
respectively.
"""
if access_token:
self.user.access_token = access_token
if token_secret:
self.user.token_secret = token_secret
url = '/accounts'
response = self.adapter.request('GET', url)
accounts = self._read_response(url, response)
return accounts[0]

class AWeberUser(object):
"""
Simple data storage object representing the user in the OAuth model. Has
properties for request_token, token_secret, access_token, and verifier.
"""

request_token = None
token_secret = None
access_token = None
verifier = None

def get_highest_priority_token(self):
return self.access_token or self.request_token

Binary file added aweber_api/__init__.pyc
Binary file not shown.
54 changes: 54 additions & 0 deletions aweber_api/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
API_BASE = 'https://api.aweber.com/1.0'
ACCESS_TOKEN_URL = 'https://auth.aweber.com/1.0/oauth/access_token'
REQUEST_TOKEN_URL = 'https://auth.aweber.com/1.0/oauth/request_token'
AUTHORIZE_URL = 'https://auth.aweber.com/1.0/oauth/authorize'

class AWeberBase(object):
"""
Provides functionality shared accross all AWeber objects
"""

collections_map = {
'account' : ['lists', 'vendor_accounts'],
'broadcast_campaign' : ['links', 'messages'],
'followup_campaign' : ['links', 'messages'],
'link' : ['clicks'],
'list' : ['campaigns', 'subscribers', 'web_forms',
'web_form_split_tests'],
'message' : ['opens', 'tracked_events'],
'subscriber' : [],
'web_form': [],
'web_form_split_test' : ['components']
}

@property
def user(self):
return self.adapter.user

def load_from_url(self, url):
"""
Gets an AWeberCollection or AWeberEntry from the given URL.
"""
response = self.adapter.request('GET', url)
return self._read_response(url, response)

def _method_for(self, type):
if not self.type == type:
raise AttributeError('Method does not exist')

def _read_response(self, url, response):
if 'entries' in response:
from aweber_api.collection import AWeberCollection
return AWeberCollection(url, response, self.adapter)
if 'id' in response:
from aweber_api.entry import AWeberEntry
return AWeberEntry(url, response, self.adapter)
raise TypeError('Unknown value returned')

def _parseNamedOperation(self, data):
from aweber_api.entry import AWeberEntry
entries = []
for item in data:
entries.append(AWeberEntry(item['self_link'].replace(API_BASE, ''),
item, self.adapter))
return entries
Binary file added aweber_api/base.pyc
Binary file not shown.
81 changes: 81 additions & 0 deletions aweber_api/collection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from math import floor
from urlparse import parse_qs
from aweber_api.response import AWeberResponse

class AWeberCollection(AWeberResponse):
"""
Represents a collection of similar objects. Encapsulates data that is
found at the base URI's for a given object type, ie:
/accounts
/accounts/XXX/lists
Parses the data from the response and provides basic sequence like
operations, such as iteration and indexing to access the entries that
are contained in this collection.
"""
page_size = 100

def __init__(self, url, data, adapter):
self._entry_data = {}
self._current = 0

AWeberResponse.__init__(self, url, data, adapter)
self._key_entries(self._data)

def get_by_id(self, id):
"""
Returns an entry from this collection, as found by its actual
AWeber id, not its offset. Will actually request the data from
the API.
"""
return self.load_from_url("{0}/{1}".format(self.url, id))

def _key_entries(self, response):
count = 0
for entry in response['entries']:
self._entry_data[count+response['start']] = entry
count += 1

def _load_page_for_offset(self, offset):
page = self._get_page_params(offset)
response = self.adapter.request('GET', self.url, page)
self._key_entries(response)

def _get_page_params(self, offset):
next_link = self._data['next_collection_link']
url, query = next_link.split('?')
query_parts = parse_qs(query)
self.page_size = int(query_parts['ws.size'][0])
page_number = int(floor(offset / self.page_size))
start = page_number * self.page_size
return { 'ws.start' : start, 'ws.size' : self.page_size }

def _create_entry(self, offset):
from aweber_api.entry import AWeberEntry
data = self._entry_data[offset]

url = "{0}/{1}".format(self.url, data['id'])
self._entries[offset] = AWeberEntry(url, data, self.adapter)

def __len__(self):
return self.total_size

def __iter__(self):
return self

def next(self):
if self._current < self.total_size:
self._current += 1
return self[self._current-1]
self._current = 0
raise StopIteration

def __getitem__(self, offset):
if offset < 0 or offset >= self._data['total_size']:
raise ValueError('Offset {0} does not exist'.format(offset))

if not offset in self._entries:
if not offset in self._entry_data:
self._load_page_for_offset(offset)
self._create_entry(offset)
return self._entries[offset]

Binary file added aweber_api/collection.pyc
Binary file not shown.
Loading

0 comments on commit 0a51ea7

Please sign in to comment.