Content-Length: 995147 | pFad | http://github.com/Nasdaq/data-link-python/commit/e661698eb6db9b07416655ea4b6df6583b9fbfec

80 change connection from class to module · Nasdaq/data-link-python@e661698 · GitHub
Skip to content

Commit e661698

Browse files
author
Ren Ren
committed
change connection from class to module
1 parent 86c5665 commit e661698

16 files changed

+135
-141
lines changed

nasdaqdatalink/connection.py

Lines changed: 93 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -13,103 +13,97 @@
1313
AuthenticationError, ForbiddenError, InvalidRequestError,
1414
NotFoundError, ServiceUnavailableError)
1515

16-
17-
class Connection:
18-
@classmethod
19-
def request(cls, http_verb, url, **options):
20-
if 'headers' in options:
21-
headers = options['headers']
16+
def request(http_verb, url, **options):
17+
if 'headers' in options:
18+
headers = options['headers']
19+
else:
20+
headers = {}
21+
22+
accept_value = 'application/json'
23+
if ApiConfig.api_version:
24+
accept_value += ", application/vnd.data.nasdaq+json;version=%s" % ApiConfig.api_version
25+
26+
headers = Util.merge_to_dicts({'accept': accept_value,
27+
'request-source': 'python',
28+
'request-source-version': VERSION}, headers)
29+
if ApiConfig.api_key:
30+
headers = Util.merge_to_dicts({'x-api-token': ApiConfig.api_key}, headers)
31+
32+
options['headers'] = headers
33+
34+
abs_url = '%s/%s' % (ApiConfig.api_base, url)
35+
36+
return execute_request(http_verb, abs_url, **options)
37+
38+
def execute_request(http_verb, url, **options):
39+
session = get_session(url)
40+
41+
try:
42+
response = session.request(method=http_verb,
43+
url=url,
44+
verify=ApiConfig.verify_ssl,
45+
**options)
46+
if response.status_code < 200 or response.status_code >= 300:
47+
handle_api_error(response)
2248
else:
23-
headers = {}
24-
25-
accept_value = 'application/json'
26-
if ApiConfig.api_version:
27-
accept_value += ", application/vnd.data.nasdaq+json;version=%s" % ApiConfig.api_version
28-
29-
headers = Util.merge_to_dicts({'accept': accept_value,
30-
'request-source': 'python',
31-
'request-source-version': VERSION}, headers)
32-
if ApiConfig.api_key:
33-
headers = Util.merge_to_dicts({'x-api-token': ApiConfig.api_key}, headers)
34-
35-
options['headers'] = headers
36-
37-
abs_url = '%s/%s' % (ApiConfig.api_base, url)
38-
39-
return cls.execute_request(http_verb, abs_url, **options)
40-
41-
@classmethod
42-
def execute_request(cls, http_verb, url, **options):
43-
session = cls.get_session()
44-
45-
try:
46-
response = session.request(method=http_verb,
47-
url=url,
48-
verify=ApiConfig.verify_ssl,
49-
**options)
50-
if response.status_code < 200 or response.status_code >= 300:
51-
cls.handle_api_error(response)
52-
else:
53-
return response
54-
except requests.exceptions.RequestException as e:
55-
if e.response:
56-
cls.handle_api_error(e.response)
57-
raise e
58-
59-
@classmethod
60-
def get_session(cls):
61-
session = requests.Session()
62-
adapter = HTTPAdapter(max_retries=cls.get_retries())
63-
session.mount(ApiConfig.api_protocol, adapter)
64-
65-
return session
66-
67-
@classmethod
68-
def get_retries(cls):
69-
if not ApiConfig.use_retries:
70-
return Retry(total=0)
71-
72-
Retry.BACKOFF_MAX = ApiConfig.max_wait_between_retries
73-
retries = Retry(total=ApiConfig.number_of_retries,
74-
connect=ApiConfig.number_of_retries,
75-
read=ApiConfig.number_of_retries,
76-
status_forcelist=ApiConfig.retry_status_codes,
77-
backoff_factor=ApiConfig.retry_backoff_factor,
78-
raise_on_status=False)
79-
80-
return retries
81-
82-
@classmethod
83-
def parse(cls, response):
84-
try:
85-
return response.json()
86-
except ValueError:
87-
raise DataLinkError(http_status=response.status_code, http_body=response.text)
88-
89-
@classmethod
90-
def handle_api_error(cls, resp):
91-
error_body = cls.parse(resp)
92-
93-
# if our app does not form a proper data_link_error response
94-
# throw generic error
95-
if 'error' not in error_body:
96-
raise DataLinkError(http_status=resp.status_code, http_body=resp.text)
97-
98-
code = error_body['error']['code']
99-
message = error_body['error']['message']
100-
prog = re.compile('^QE([a-zA-Z])x')
101-
if prog.match(code):
102-
code_letter = prog.match(code).group(1)
103-
104-
d_klass = {
105-
'L': LimitExceededError,
106-
'M': InternalServerError,
107-
'A': AuthenticationError,
108-
'P': ForbiddenError,
109-
'S': InvalidRequestError,
110-
'C': NotFoundError,
111-
'X': ServiceUnavailableError
112-
}
113-
klass = d_klass.get(code_letter, DataLinkError)
114-
115-
raise klass(message, resp.status_code, resp.text, resp.headers, code)
49+
return response
50+
except requests.exceptions.RequestException as e:
51+
if e.response:
52+
handle_api_error(e.response)
53+
raise e
54+
55+
def get_retries():
56+
if not ApiConfig.use_retries:
57+
return Retry(total=0)
58+
59+
Retry.BACKOFF_MAX = ApiConfig.max_wait_between_retries
60+
retries = Retry(total=ApiConfig.number_of_retries,
61+
connect=ApiConfig.number_of_retries,
62+
read=ApiConfig.number_of_retries,
63+
status_forcelist=ApiConfig.retry_status_codes,
64+
backoff_factor=ApiConfig.retry_backoff_factor,
65+
raise_on_status=False)
66+
67+
return retries
68+
69+
session = requests.Session()
70+
71+
def get_session(url = ApiConfig.api_protocol):
72+
adapter = HTTPAdapter(max_retries=get_retries())
73+
session.mount(url, adapter)
74+
return session
75+
76+
def parse(response):
77+
try:
78+
return response.json()
79+
except ValueError:
80+
raise DataLinkError(http_status=response.status_code, http_body=response.text)
81+
82+
83+
84+
def handle_api_error(resp):
85+
error_body = parse(resp)
86+
87+
# if our app does not form a proper data_link_error response
88+
# throw generic error
89+
if 'error' not in error_body:
90+
raise DataLinkError(http_status=resp.status_code, http_body=resp.text)
91+
92+
code = error_body['error']['code']
93+
message = error_body['error']['message']
94+
prog = re.compile('^QE([a-zA-Z])x')
95+
if prog.match(code):
96+
code_letter = prog.match(code).group(1)
97+
98+
d_klass = {
99+
'L': LimitExceededError,
100+
'M': InternalServerError,
101+
'A': AuthenticationError,
102+
'P': ForbiddenError,
103+
'S': InvalidRequestError,
104+
'C': NotFoundError,
105+
'X': ServiceUnavailableError
106+
}
107+
klass = d_klass.get(code_letter, DataLinkError)
108+
109+
raise klass(message, resp.status_code, resp.text, resp.headers, code)

nasdaqdatalink/model/database.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import nasdaqdatalink.model.dataset
66
from nasdaqdatalink.api_config import ApiConfig
7-
from nasdaqdatalink.connection import Connection
7+
import nasdaqdatalink.connection as Connection
88
from nasdaqdatalink.errors.data_link_error import DataLinkError
99
from nasdaqdatalink.message import Message
1010
from nasdaqdatalink.operations.get import GetOperation

nasdaqdatalink/model/datatable.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from six.moves.urllib.request import urlopen
55

6-
from nasdaqdatalink.connection import Connection
6+
import nasdaqdatalink.connection as Connection
77
from nasdaqdatalink.errors.data_link_error import DataLinkError
88
from nasdaqdatalink.message import Message
99
from nasdaqdatalink.operations.get import GetOperation

nasdaqdatalink/operations/get.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from inflection import singularize
22

33
from .operation import Operation
4-
from nasdaqdatalink.connection import Connection
4+
import nasdaqdatalink.connection as Connection
55
from nasdaqdatalink.util import Util
66

77

nasdaqdatalink/operations/list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .operation import Operation
2-
from nasdaqdatalink.connection import Connection
2+
import nasdaqdatalink.connection as Connection
33
from nasdaqdatalink.util import Util
44
from nasdaqdatalink.model.paginated_list import PaginatedList
55
from nasdaqdatalink.utils.request_type_util import RequestType

test/test_connection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from nasdaqdatalink.connection import Connection
1+
import nasdaqdatalink.connection as Connection
22
from nasdaqdatalink.api_config import ApiConfig
33
from nasdaqdatalink.errors.data_link_error import (
44
DataLinkError, LimitExceededError, InternalServerError,
@@ -65,7 +65,7 @@ def test_non_data_link_error(self, request_method):
6565
DataLinkError, lambda: Connection.request(request_method, 'databases'))
6666

6767
@parameterized.expand(['GET', 'POST'])
68-
@patch('nasdaqdatalink.connection.Connection.execute_request')
68+
@patch('nasdaqdatalink.connection.execute_request')
6969
def test_build_request(self, request_method, mock):
7070
ApiConfig.api_key = 'api_token'
7171
ApiConfig.api_version = '2015-04-09'

test/test_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def tearDownClass(cls):
7777
httpretty.disable()
7878
httpretty.reset()
7979

80-
@patch('nasdaqdatalink.connection.Connection.request')
80+
@patch('nasdaqdatalink.connection.request')
8181
def test_data_calls_connection(self, mock):
8282
Data.all(params={'database_code': 'NSE', 'dataset_code': 'OIL'})
8383
expected = call('get', 'datasets/NSE/OIL/data', params={})

test/test_database.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from six.moves.urllib.parse import parse_qs, urlparse
88

99
from nasdaqdatalink.api_config import ApiConfig
10-
from nasdaqdatalink.connection import Connection
10+
import nasdaqdatalink.connection as Connection
1111
from nasdaqdatalink.errors.data_link_error import (InternalServerError, DataLinkError)
1212
from nasdaqdatalink.model.database import Database
1313
from test.factories.database import DatabaseFactory
@@ -34,7 +34,7 @@ def tearDownClass(cls):
3434
httpretty.disable()
3535
httpretty.reset()
3636

37-
@patch('nasdaqdatalink.connection.Connection.request')
37+
@patch('nasdaqdatalink.connection.request')
3838
def test_database_calls_connection(self, mock):
3939
database = Database('NSE')
4040
database.data_fields()
@@ -80,7 +80,7 @@ def tearDownClass(cls):
8080
httpretty.disable()
8181
httpretty.reset()
8282

83-
@patch('nasdaqdatalink.connection.Connection.request')
83+
@patch('nasdaqdatalink.connection.request')
8484
def test_databases_calls_connection(self, mock):
8585
Database.all()
8686
expected = call('get', 'databases', params={})

test/test_dataset.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def tearDownClass(cls):
3030
httpretty.disable()
3131
httpretty.reset()
3232

33-
@patch('nasdaqdatalink.connection.Connection.request')
33+
@patch('nasdaqdatalink.connection.request')
3434
def test_dataset_calls_connection(self, mock):
3535
d = Dataset('NSE/OIL')
3636
d.data_fields()
@@ -84,7 +84,7 @@ def tearDownClass(cls):
8484
httpretty.disable()
8585
httpretty.reset()
8686

87-
@patch('nasdaqdatalink.connection.Connection.request')
87+
@patch('nasdaqdatalink.connection.request')
8888
def test_datasets_calls_connection(self, mock):
8989
Dataset.all()
9090
expected = call('get', 'datasets', params={})

test/test_datatable.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,26 @@ def tearDownClass(cls):
3737
def tearDown(self):
3838
RequestType.USE_GET_REQUEST = True
3939

40-
@patch('nasdaqdatalink.connection.Connection.request')
40+
@patch('nasdaqdatalink.connection.request')
4141
def test_datatable_metadata_calls_connection(self, mock):
4242
Datatable('ZACKS/FC').data_fields()
4343
expected = call('get', 'datatables/ZACKS/FC/metadata', params={})
4444
self.assertEqual(mock.call_args, expected)
4545

46-
@patch('nasdaqdatalink.connection.Connection.request')
46+
@patch('nasdaqdatalink.connection.request')
4747
def test_datatable_data_calls_connection_with_no_params_for_get_request(self, mock):
4848
Datatable('ZACKS/FC').data()
4949
expected = call('get', 'datatables/ZACKS/FC', params={})
5050
self.assertEqual(mock.call_args, expected)
5151

52-
@patch('nasdaqdatalink.connection.Connection.request')
52+
@patch('nasdaqdatalink.connection.request')
5353
def test_datatable_data_calls_connection_with_no_params_for_post_request(self, mock):
5454
RequestType.USE_GET_REQUEST = False
5555
Datatable('ZACKS/FC').data()
5656
expected = call('post', 'datatables/ZACKS/FC', json={})
5757
self.assertEqual(mock.call_args, expected)
5858

59-
@patch('nasdaqdatalink.connection.Connection.request')
59+
@patch('nasdaqdatalink.connection.request')
6060
def test_datatable_calls_connection_with_params_for_get_request(self, mock):
6161
params = {'ticker': ['AAPL', 'MSFT'],
6262
'per_end_date': {'gte': '2015-01-01'},
@@ -76,7 +76,7 @@ def test_datatable_calls_connection_with_params_for_get_request(self, mock):
7676
expected = call('get', 'datatables/ZACKS/FC', params=expected_params)
7777
self.assertEqual(mock.call_args, expected)
7878

79-
@patch('nasdaqdatalink.connection.Connection.request')
79+
@patch('nasdaqdatalink.connection.request')
8080
def test_datatable_calls_connection_with_params_for_post_request(self, mock):
8181
RequestType.USE_GET_REQUEST = False
8282
params = {'ticker': ['AAPL', 'MSFT'],

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/Nasdaq/data-link-python/commit/e661698eb6db9b07416655ea4b6df6583b9fbfec

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy