Skip to content
This repository has been archived by the owner on May 12, 2020. It is now read-only.

Commit

Permalink
Merge pull request #27 from avidas/master
Browse files Browse the repository at this point in the history
Merge xlevus's changes for allowing mutliple api objects in the same thread
  • Loading branch information
avidas committed Jan 8, 2014
2 parents 5b05f44 + 2e68ea7 commit 454b905
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
build/
dist/
MANIFEST

.*.sw*
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ export PAYPAL_CLIENT_ID=EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM
export PAYPAL_CLIENT_SECRET=EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM
```

Configure through a non-global Api object
```python
import paypalrestsdk
my_api = paypalrestsdk.Api({
'mode': 'sandbox',
'client_id': '...',
'client_secret': '...'})

payment = paypalrestsdk.Payment({...}, api=my_api)

```

### Create Payment

```python
Expand Down
1 change: 1 addition & 0 deletions paypalrestsdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,4 @@ def set_config(options=None, **config):
return __api__

configure = set_config

35 changes: 21 additions & 14 deletions paypalrestsdk/resource.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import uuid

import paypalrestsdk.util as util
import paypalrestsdk.api as api
from paypalrestsdk.api import default as default_api


# Base class for all REST service
class Resource(object):

convert_resources = {}

def __init__(self, attributes=None):
def __init__(self, attributes=None, api=None):
attributes = attributes or {}
self.__dict__['api'] = api or default_api()

super(Resource, self).__setattr__('__data__', {})
super(Resource, self).__setattr__('error', None)
super(Resource, self).__setattr__('headers', {})
Expand Down Expand Up @@ -54,14 +56,14 @@ def success(self):

# Merge new attributes
def merge(self, new_attributes):
for k in new_attributes:
self.__setattr__(k, new_attributes[k])
for k,v in new_attributes.items():
setattr(self, k, v)

# Convert the attribute values to configured class.
def convert(self, name, value):
if isinstance(value, dict):
cls = self.convert_resources.get(name, Resource)
return cls(value)
return cls(value, api=self.api)
elif isinstance(value, list):
new_list = []
for obj in value:
Expand Down Expand Up @@ -100,9 +102,11 @@ def parse_object(value):
class Find(Resource):

@classmethod
def find(cls, resource_id):
def find(cls, resource_id, api=None):
api = api or default_api()

url = util.join_url(cls.path, str(resource_id))
return cls(api.default().get(url))
return cls(api.get(url), api=api)


# == Example
Expand All @@ -111,12 +115,14 @@ class List(Resource):
list_class = Resource

@classmethod
def all(cls, params=None):
def all(cls, params=None, api=None):
api = api or default_api()

if params is None:
url = cls.path
else:
url = util.join_url_params(cls.path, params)
return cls.list_class(api.default().get(url))
return cls.list_class(api.get(url), api=api)


# == Example
Expand All @@ -125,7 +131,7 @@ def all(cls, params=None):
class Create(Resource):

def create(self):
new_attributes = api.default().post(self.path, self.to_dict(), self.http_headers())
new_attributes = self.api.post(self.path, self.to_dict(), self.http_headers())
self.error = None
self.merge(new_attributes)
return self.success()
Expand All @@ -137,7 +143,7 @@ class Delete(Resource):

def delete(self):
url = util.join_url(self.path, str(self['id']))
new_attributes = api.default().delete(url)
new_attributes = self.api.delete(url)
self.error = None
self.merge(new_attributes)
return self.success()
Expand All @@ -152,11 +158,12 @@ def post(self, name, attributes=None, cls=Resource):
attributes = attributes or {}
url = util.join_url(self.path, str(self['id']), name)
if not isinstance(attributes, Resource):
attributes = Resource(attributes)
new_attributes = api.default().post(url, attributes.to_dict(), attributes.http_headers())
attributes = Resource(attributes, api=self.api)
new_attributes = self.api.post(url, attributes.to_dict(), attributes.http_headers())
if isinstance(cls, Resource):
cls.error = None
cls.merge(new_attributes)
return self.success()
else:
return cls(new_attributes)
return cls(new_attributes, api=self.api)

63 changes: 60 additions & 3 deletions test/resource_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from test_helper import unittest
from paypalrestsdk.resource import Resource
from paypalrestsdk.resource import Resource, Find, List, Post

class TestResource(unittest.TestCase):
def test_getter(self):
Expand Down Expand Up @@ -70,12 +70,69 @@ def test_request_id(self):

def test_http_headers(self):
data = {
'name': 'testing',
'header': { 'My-Header': 'testing' } }
'name': 'testing',
'header': { 'My-Header': 'testing' } }
resource = Resource(data)
self.assertEqual(resource.header, {'My-Header': 'testing'})
self.assertEqual(resource.http_headers(), {'PayPal-Request-Id': resource.request_id, 'My-Header': 'testing'})

def test_passing_api(self):
"""
Check that api objects are passed on to new resources when given
"""
class DummyAPI(object):
post = lambda s,*a,**k: {}
get = lambda s,*a,**k: {}

api = DummyAPI()

# Conversion
resource = Resource({
'name': 'testing',
}, api=api)
self.assertEqual(resource.api, api)
convert_ret = resource.convert('test', {})
self.assertEqual(convert_ret.api, api)

class TestResource(Find, List, Post):
path = '/'

# Find
find = TestResource.find('resourceid', api=api)
self.assertEqual(find.api, api)

# List
list_ = TestResource.all(api=api)
self.assertEqual(list_.api, api)

# Post
post = TestResource({'id':'id'}, api=api)
post_ret = post.post('test')
self.assertEqual(post_ret.api, api)

def test_default_resource(self):
from paypalrestsdk import api
original = api.__api__

class DummyAPI(object):
post = lambda s,*a,**k: {}
get = lambda s,*a,**k: {}

# Make default api object a dummy api object
default = api.__api__ = DummyAPI()

resource = Resource({})
self.assertEqual(resource.api, default)

class TestResource(Find, List, Post):
path = '/'

# Find
find = TestResource.find('resourceid')
self.assertEqual(find.api, default)

# List
list_ = TestResource.all()
self.assertEqual(list_.api, default)

api.__api__ = original # Restore original api object

0 comments on commit 454b905

Please sign in to comment.