Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cleanup and PyPi packaging. Here's a full list:
* Converted README.md to ReST, since that's what PyPi uses for their detail pages. * Created a top-level wepay module, containing api and exceptions. This is to facilitate the packaging process. * ReSTified all docstrings so Sphinx docs can be generated. * Added a setup.py file. * Added a VERSION const to wepay.__init__.py. PyPi wants this. Feel free to change the value. * Moved WePayError into its own module. * Eliminated a few unsafe default kwarg values in WePay class. Dicts can be accidentally manipulated if left as default.
- Loading branch information
Greg Taylor
committed
Nov 7, 2011
1 parent
be71f4e
commit b631097
Showing
9 changed files
with
249 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
*.pyc | ||
*.swp | ||
*.tmp | ||
*~ | ||
build | ||
dist | ||
MANIFEST | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
include README.md | ||
include wepay-example.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
WePay Python SDK | ||
================ | ||
|
||
WePay's API allows you to easily add payments into your application. | ||
|
||
For full documentation, see `WePay's developer documentation`_ | ||
|
||
.. _WePay's developer documentation: https://www.wepay.com/developer | ||
|
||
Usage | ||
----- | ||
These examples use the simple web.py application framework. | ||
|
||
Setup | ||
^^^^^ | ||
|
||
Import the module:: | ||
|
||
from wepay import WePay | ||
|
||
Instantiate | ||
^^^^^^^^^^^ | ||
|
||
Create a new ``WePay`` instance. With no arguments, it will use the production | ||
version of WePay (www.wepay.com). If called with ``production=False`` then | ||
it will use the staging version (stage.wepay.com) for testing.:: | ||
|
||
wepay = WePay() | ||
|
||
If your user has already authorized your application and you still have the | ||
access token, you can instantiate the SDK with the optional ``access_token`` | ||
parameter. Afterwards, ``wepay.call()`` will use the given token for the | ||
authorization header.:: | ||
|
||
wepay = WePay(access_token=USERS_ACCESS_TOKEN) | ||
|
||
Get authorized | ||
^^^^^^^^^^^^^^ | ||
|
||
Create an authorization url and redirect the user to it. The first parameter | ||
is where the user will be redirected back to after they finish authorization. | ||
The second is your ``CLIENT_ID`` which is provided by WePay.:: | ||
|
||
auth_url = wepay.get_authorization_url(web.ctx.homedomain + '/callback', CLIENT_ID) | ||
web.redirect(auth_url) | ||
|
||
Handle the callback | ||
^^^^^^^^^^^^^^^^^^^ | ||
|
||
In your method for handling the redirect back to your site (in this case, | ||
``/callback``), you will need to load the GET param ``code`` and then call | ||
``get_token`` with it. ``CLIENT_SECRET`` is provided by WePay. The first | ||
parameter of ``get_token`` should be the exact same string that was used | ||
in ``get_authorization_url``.:: | ||
|
||
code = web.input(code='')['code'] | ||
# make sure the first arg is exactly the same as the first arg | ||
# of get_authorization_url | ||
wepay.get_token(web.ctx.homedomain + '/callback', CLIENT_ID, CLIENT_SECRET, code) | ||
|
||
The ``get_token`` method will automatically load the access token into the | ||
``WePay`` instance so that all future API calls will use that token for | ||
authorization. It also returns the entire response from the | ||
``/v2/oauth2/token`` call if you need any additional data like the WePay ID. | ||
|
||
Make some calls | ||
^^^^^^^^^^^^^^^ | ||
|
||
You are now ready to do anything on behalf of your user. Let's start by making | ||
a new account.:: | ||
|
||
create_response = wepay.call('/account/create', { | ||
'name': 'kitty expenses fund', | ||
'description': 'all the money for my kitty' | ||
}) | ||
|
||
Now let's set a picture!:: | ||
|
||
wepay.call('/account/modify', { | ||
'account_id': create_response['account_id'], | ||
'image_uri': 'http://www.placekitten.com/500/500' | ||
}) | ||
|
||
Redirect them to their account page to see it.:: | ||
|
||
web.redirect(create_response['account_uri']) | ||
|
||
Try it! | ||
^^^^^^^ | ||
|
||
These examples are put together into a working web app in | ||
``wepay-example.py``. If you already have web.py installed, you can run it | ||
by simply doing ``python wepay-example.py``. If you open the app in your | ||
browser you should be redirected to WePay to authorize the app. After you | ||
authorize, you should get redirected around a bit and end up on your new | ||
account page with a kitty picture. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from distutils.core import setup | ||
import wepay | ||
|
||
long_description = open('README.rst').read() | ||
|
||
version_str = '%s.%s.%s' % ( | ||
wepay.VERSION[0], | ||
wepay.VERSION[1], | ||
wepay.VERSION[2] | ||
) | ||
|
||
setup( | ||
name='wepay', | ||
version=version_str, | ||
packages=['wepay'], | ||
description='A Python SDK for our WePay API.', | ||
long_description=long_description, | ||
author='Bryce Culhane', | ||
author_email='bryce.culhane@gmail.com', | ||
license='BSD License', | ||
url='https://github.com/wepay/Python-SDK', | ||
platforms=["any"], | ||
classifiers=[ | ||
'Development Status :: 4 - Beta', | ||
'Intended Audience :: Developers', | ||
'License :: OSI Approved :: BSD License', | ||
'Natural Language :: English', | ||
'Operating System :: OS Independent', | ||
'Programming Language :: Python', | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from api import WePay | ||
|
||
# Major, minor, revision | ||
VERSION = (0, 1, 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import urllib,urllib2,json | ||
from wepay.exceptions import WePayError | ||
|
||
class WePay(object): | ||
""" | ||
A client for the WePay API. | ||
""" | ||
|
||
def __init__(self, production=True, access_token=None): | ||
""" | ||
:param bool production: When ``False``, the ``stage.wepay.com`` API | ||
server will be used instead of the default production. | ||
:param str access_token: The access token associated with your | ||
application. | ||
""" | ||
self.access_token = access_token | ||
if production: | ||
self.wepay_url = "https://www.wepay.com/v2" | ||
else: | ||
self.wepay_url = "https://stage.wepay.com/v2" | ||
|
||
def call(self, uri, params=None, token=None): | ||
""" | ||
Calls wepay.com/v2/``uri`` with ``params`` and returns the JSON | ||
response as a python dict. The optional token parameter will override | ||
the instance's access_token if it is set. | ||
:param str uri: The URI on the API endpoint to call. | ||
:param dict params: The parameters to pass to the URI. | ||
:param str token: Optional override for this ``WePay`` object's access | ||
token. | ||
""" | ||
if not params: | ||
params = {} | ||
|
||
headers = {'Content-Type' : 'application/json'} | ||
url = self.wepay_url + uri | ||
|
||
if self.access_token or token: | ||
headers['Authorization'] = 'Bearer ' + (token if token else self.access_token) | ||
|
||
params = json.dumps(params) | ||
|
||
request = urllib2.Request(url, params, headers) | ||
try: | ||
response = urllib2.urlopen(request).read() | ||
return json.loads(response) | ||
except urllib2.HTTPError as e: | ||
response = json.loads(e.read()) | ||
raise WePayError(response['error'], response['error_description']) | ||
|
||
def get_authorization_url(self, redirect_uri, client_id, options=None, | ||
scope=None): | ||
""" | ||
Returns a URL to send the user to in order to get authorization. | ||
After getting authorization the user will return to redirect_uri. | ||
Optionally, scope can be set to limit permissions, and the options | ||
dict can be loaded with any combination of state, user_name | ||
or user_email. | ||
:param str redirect_uri: The URI to redirect to after a authorization. | ||
:param str client_id: The client ID issued by WePay to your app. | ||
:keyword dict options: Allows for passing additional values to the | ||
authorize call, aside from scope, redirect_uri, and etc. | ||
:keyword str scope: A comma-separated string of permissions. | ||
""" | ||
if not options: | ||
options = {} | ||
if not scope: | ||
scope = "manage_accounts,collect_payments,view_balance,view_user,refund_payments" | ||
|
||
options['scope'] = scope | ||
options['redirect_uri'] = redirect_uri | ||
options['client_id'] = client_id | ||
|
||
return self.wepay_url + '/oauth2/authorize?' + urllib.urlencode(options) | ||
|
||
def get_token(self, redirect_uri, client_id, client_secret, code): | ||
""" | ||
Calls wepay.com/v2/oauth2/token to get an access token. Sets the | ||
access_token for the WePay instance and returns the entire response | ||
as a dict. Should only be called after the user returns from being | ||
sent to get_authorization_url. | ||
:param str redirect_uri: The same URI specified in the | ||
:py:meth:`get_authorization_url` call that preceeded this. | ||
:param str client_id: The client ID issued by WePay to your app. | ||
:param str client_secret: The client secret issued by WePay | ||
to your app. | ||
:param str code: The code returned by :py:meth:`get_authorization_url`. | ||
""" | ||
params = { | ||
'redirect_uri': redirect_uri, | ||
'client_id': client_id, | ||
'client_secret': client_secret, | ||
'code': code, | ||
} | ||
response = self.call('/oauth2/token', params) | ||
self.access_token = response['access_token'] | ||
return response |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class WePayError(Exception): | ||
""" | ||
Raised when an error comes back in the API response from WePay. | ||
""" | ||
def __init__(self, error_type, message): | ||
Exception.__init__(self, message) | ||
self.type = error_type |