From 14b4325c19b899d7143587232559270a080d9b48 Mon Sep 17 00:00:00 2001 From: Henk Kraal Date: Tue, 26 Jul 2016 12:32:16 +0200 Subject: [PATCH 1/6] Return a dictionary --- pycrest/eve.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/pycrest/eve.py b/pycrest/eve.py index b27c508..6ac03e2 100644 --- a/pycrest/eve.py +++ b/pycrest/eve.py @@ -220,12 +220,17 @@ def get(self, resource, params={}): self._session.headers.items()), frozenset( prms.items())) expires = self._get_expires(res) + response = {'result': ret, + 'status_code': res.status_code, + 'expires': expires, + 'timestamp': time.time() + expires} + if expires > 0: self.cache.put( key, { - 'expires': time.time() + expires, 'payload': ret}) + 'expires': time.time() + expires, 'payload': response}) - return ret + return response #post is not idempotent so there should be no caching def post(self, resource, data={}): @@ -406,12 +411,15 @@ def get(self, resource, params={}): self.refresh() return super(self.__class__, self).get(resource, params) + class APIObject(object): def __init__(self, parent, connection): self._dict = {} self.connection = connection for k, v in parent.items(): + if k == 'result': + v = parent[k] if isinstance(v, dict): self._dict[k] = APIObject(v, connection) elif isinstance(v, list): @@ -431,11 +439,14 @@ def _wrap_list(self, list_): return new def __getattr__(self, item): + # Try to get the property from the dictionary first if item in self._dict: return self._dict[item] - raise AttributeError(item) + if isinstance(self._dict['result'], APIObject): + return self._dict['result'].__getattr__(item) + raise AttributeError(item) def __call__(self, **kwargs): """carries out a CREST request From 237ebe3bddc578cca1e30cfe44dc3fed3359aa8a Mon Sep 17 00:00:00 2001 From: Henk Kraal Date: Tue, 26 Jul 2016 16:21:17 +0200 Subject: [PATCH 2/6] Comment when we do wierd stuff --- pycrest/eve.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pycrest/eve.py b/pycrest/eve.py index 6ac03e2..575864c 100644 --- a/pycrest/eve.py +++ b/pycrest/eve.py @@ -418,6 +418,7 @@ def __init__(self, parent, connection): self._dict = {} self.connection = connection for k, v in parent.items(): + # If we don't "pull in" 'result' it will cause the creation of an unwanted APIObject if k == 'result': v = parent[k] if isinstance(v, dict): From 267ec5f62007f30e38e07575d843e455f1288322 Mon Sep 17 00:00:00 2001 From: Henk Kraal Date: Tue, 26 Jul 2016 16:49:57 +0200 Subject: [PATCH 3/6] check if "result" exists --- pycrest/eve.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pycrest/eve.py b/pycrest/eve.py index 575864c..0e007e6 100644 --- a/pycrest/eve.py +++ b/pycrest/eve.py @@ -444,8 +444,9 @@ def __getattr__(self, item): if item in self._dict: return self._dict[item] - if isinstance(self._dict['result'], APIObject): - return self._dict['result'].__getattr__(item) + if 'result' in self._dict: + if isinstance(self._dict['result'], APIObject): + return self._dict['result'].__getattr__(item) raise AttributeError(item) From 1840fd17c8401131eafcd028fc9caaf4b073b6a1 Mon Sep 17 00:00:00 2001 From: Henk Kraal Date: Tue, 26 Jul 2016 17:06:30 +0200 Subject: [PATCH 4/6] include endpoint version --- pycrest/eve.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pycrest/eve.py b/pycrest/eve.py index 0e007e6..7bb9f80 100644 --- a/pycrest/eve.py +++ b/pycrest/eve.py @@ -221,9 +221,10 @@ def get(self, resource, params={}): prms.items())) expires = self._get_expires(res) response = {'result': ret, + 'endpoint_version': res.headers['content-type'].split(';')[0], 'status_code': res.status_code, - 'expires': expires, - 'timestamp': time.time() + expires} + 'expires_in': expires, + 'expires_at': time.time() + expires} if expires > 0: self.cache.put( From 10918f6d082c4cfb744ca28c0a0d6333db1ec737 Mon Sep 17 00:00:00 2001 From: Henk Kraal Date: Wed, 27 Jul 2016 09:41:51 +0200 Subject: [PATCH 5/6] Add test to demonstrate the lack of namespace issues --- tests/test_pull_37.py | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/test_pull_37.py diff --git a/tests/test_pull_37.py b/tests/test_pull_37.py new file mode 100644 index 0000000..30a80af --- /dev/null +++ b/tests/test_pull_37.py @@ -0,0 +1,63 @@ +''' +Created on Jun 27, 2016 + +@author: henk +''' +from pycrest.eve import EVE, APIObject +import httmock +import unittest + +@httmock.urlmatch( + scheme="https", + netloc=r"(api-sisi\.test)?(crest-tq\.)?eveonline\.com$", + path=r"^/?$") +def root_mock(url, request): + return httmock.response( + status_code=200, + content='''{ + "marketData": { + "href": "https://crest-tq.eveonline.com/market/prices/" + }}''', headers={"content-type": "application/vnd.ccp.eve.Api-v5+json; charset=utf-8"}) + + +@httmock.urlmatch( + scheme="https", + netloc=r"(api-sisi\.test)?(crest-tq\.)?eveonline\.com$", + path=r"^/market/prices/?$") +def market_prices_mock(url, request): + return httmock.response( + status_code=200, + content='{"result": "10213", "items": [], "status_code": 500, "pa' + 'geCount_str": "1", "totalCount": 10213}', + headers={"content-type": "application/vnd.ccp.eve.Api-v5+json; charset=utf-8"}) + + +all_httmocks = [ + root_mock, + market_prices_mock] + + +class TestEVE(unittest.TestCase): + + def setUp(self): + self.api = EVE() + + def test_root(self): + with httmock.HTTMock(*all_httmocks): + res = self.api() + self.assertTrue(isinstance(res, APIObject)) + self.assertEqual(res.endpoint_version, 'application/vnd.ccp.eve.Api-v5+json') + self.assertEqual(res.status_code, 200) + + def test_market_price(self): + with httmock.HTTMock(*all_httmocks): + res = self.api().marketData() + self.assertEqual(res.status_code, 200) + self.assertEqual(res.result.status_code, 500) + self.assertEqual(res.result.result, '10213') + + + + +if __name__ == "__main__": + unittest.main() From 756b40c44e6b45245c174d311b8995e06d88b4f7 Mon Sep 17 00:00:00 2001 From: Henk Kraal Date: Wed, 27 Jul 2016 19:26:54 +0200 Subject: [PATCH 6/6] pervese unittest --- tests/test_pull_37.py | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/tests/test_pull_37.py b/tests/test_pull_37.py index 30a80af..dd2d8a5 100644 --- a/tests/test_pull_37.py +++ b/tests/test_pull_37.py @@ -17,6 +17,9 @@ def root_mock(url, request): content='''{ "marketData": { "href": "https://crest-tq.eveonline.com/market/prices/" + }, + "perverse": { + "href": "https://crest-tq.eveonline.com/perverse/" }}''', headers={"content-type": "application/vnd.ccp.eve.Api-v5+json; charset=utf-8"}) @@ -31,10 +34,33 @@ def market_prices_mock(url, request): 'geCount_str": "1", "totalCount": 10213}', headers={"content-type": "application/vnd.ccp.eve.Api-v5+json; charset=utf-8"}) +@httmock.urlmatch( + scheme="https", + netloc=r"(api-sisi\.test)?(crest-tq\.)?eveonline\.com$", + path=r"^/perverse/?$") +def perverse_mock(url, request): + return httmock.response( + status_code=200, + content='''{ + "result": { + "result": "10213", + "status_code": 500 + }, + "items": [], + "status_code": { + "result": "10214", + "status_code": 501 + }, + "pageCount_str": "1", + "totalCount": 10213 +}''', + headers={"content-type": "application/vnd.ccp.eve.Api-v5+json; charset=utf-8"}) + all_httmocks = [ root_mock, - market_prices_mock] + market_prices_mock, + perverse_mock] class TestEVE(unittest.TestCase): @@ -56,8 +82,19 @@ def test_market_price(self): self.assertEqual(res.result.status_code, 500) self.assertEqual(res.result.result, '10213') - - + def test_perverse(self): + with httmock.HTTMock(*all_httmocks): + res = self.api().perverse() + self.assertEqual(res.status_code, 200) + self.assertEqual(res.pageCount_str, '1') + self.assertEqual(res.result.pageCount_str, '1') + self.assertEqual(res.totalCount, 10213) + self.assertEqual(res.result.totalCount, 10213) + self.assertEqual(res.items, []) + self.assertEqual(res.result.items, []) + self.assertEqual(res.result.status_code.status_code, 501) + self.assertEqual(res.result.status_code.result, '10214') + self.assertEqual(res.result.result.result, '10213') if __name__ == "__main__": unittest.main()