Skip to content

Commit 7fb9f10

Browse files
committed
add AuthorizedSession support
1 parent 42ae5e4 commit 7fb9f10

File tree

8 files changed

+110
-22
lines changed

8 files changed

+110
-22
lines changed

nasdaqdatalink/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from .model.point_in_time import PointInTime
1111
from .model.data import Data
1212
from .model.merged_dataset import MergedDataset
13+
from .model.authorized_session import AuthorizedSession
1314
from .get import get
1415
from .bulkdownload import bulkdownload
1516
from .export_table import export_table

nasdaqdatalink/api_config.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ class ApiConfig:
1717
retry_status_codes = [429] + list(range(500, 512))
1818
verify_ssl = True
1919

20+
def read_key(self, filename):
21+
if not os.path.isfile(filename):
22+
raise_empty_file(filename)
23+
24+
with open(filename, 'r') as f:
25+
apikey = get_first_non_empty(f)
26+
27+
if not apikey:
28+
raise_empty_file(filename)
29+
30+
self.api_key = apikey
31+
2032

2133
def create_file(config_filename):
2234
# Create the file as well as the parent dir if needed.
@@ -102,3 +114,11 @@ def read_key(filename=None):
102114
read_key_from_environment_variable()
103115
elif config_file_exists(filename):
104116
read_key_from_file(filename)
117+
118+
119+
def get_config_from_kwargs(kwargs):
120+
params = getattr(kwargs, "params", None)
121+
result = getattr(params, "api_config", None)
122+
if result is None:
123+
result = ApiConfig
124+
return result

nasdaqdatalink/connection.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from .util import Util
1010
from .version import VERSION
11-
from .api_config import ApiConfig
11+
from .api_config import ApiConfig, get_config_from_kwargs
1212
from nasdaqdatalink.errors.data_link_error import (
1313
DataLinkError, LimitExceededError, InternalServerError,
1414
AuthenticationError, ForbiddenError, InvalidRequestError,
@@ -22,31 +22,36 @@ def request(cls, http_verb, url, **options):
2222
headers = options['headers']
2323
else:
2424
headers = {}
25+
api_config = get_config_from_kwargs(options)
2526

2627
accept_value = 'application/json'
27-
if ApiConfig.api_version:
28-
accept_value += ", application/vnd.data.nasdaq+json;version=%s" % ApiConfig.api_version
28+
if api_config.api_version:
29+
accept_value += ", application/vnd.data.nasdaq+json;version=%s" % api_config.api_version
2930

3031
headers = Util.merge_to_dicts({'accept': accept_value,
3132
'request-source': 'python',
3233
'request-source-version': VERSION}, headers)
33-
if ApiConfig.api_key:
34-
headers = Util.merge_to_dicts({'x-api-token': ApiConfig.api_key}, headers)
34+
if api_config.api_key:
35+
headers = Util.merge_to_dicts({'x-api-token': api_config.api_key}, headers)
3536

3637
options['headers'] = headers
3738

38-
abs_url = '%s/%s' % (ApiConfig.api_base, url)
39+
abs_url = '%s/%s' % (api_config.api_base, url)
3940

4041
return cls.execute_request(http_verb, abs_url, **options)
4142

4243
@classmethod
4344
def execute_request(cls, http_verb, url, **options):
44-
session = cls.get_session()
45+
params = getattr(options, 'params', None)
46+
session = getattr(params, 'session', None)
47+
if session is None:
48+
session = cls.get_session()
4549

50+
api_config = get_config_from_kwargs(options)
4651
try:
4752
response = session.request(method=http_verb,
4853
url=url,
49-
verify=ApiConfig.verify_ssl,
54+
verify=api_config.verify_ssl,
5055
**options)
5156
if response.status_code < 200 or response.status_code >= 300:
5257
cls.handle_api_error(response)

nasdaqdatalink/get_point_in_time.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from nasdaqdatalink.model.point_in_time import PointInTime
22
from nasdaqdatalink.errors.data_link_error import LimitExceededError
3-
from .api_config import ApiConfig
3+
from .api_config import get_config_from_kwargs
44
from .message import Message
55
from nasdaqdatalink.errors.data_link_error import InvalidRequestError
66
import warnings
@@ -23,6 +23,7 @@ def get_point_in_time(datatable_code, **options):
2323

2424
data = None
2525
page_count = 0
26+
api_config = get_config_from_kwargs(options)
2627
while True:
2728
next_options = copy.deepcopy(options)
2829
next_data = PointInTime(datatable_code, pit=pit_options).data(params=next_options)
@@ -32,10 +33,10 @@ def get_point_in_time(datatable_code, **options):
3233
else:
3334
data.extend(next_data)
3435

35-
if page_count >= ApiConfig.page_limit:
36+
if page_count >= api_config.page_limit:
3637
raise LimitExceededError(
3738
Message.WARN_DATA_LIMIT_EXCEEDED % (datatable_code,
38-
ApiConfig.api_key
39+
api_config.api_key
3940
)
4041
)
4142

nasdaqdatalink/get_table.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from nasdaqdatalink.model.datatable import Datatable
22
from nasdaqdatalink.errors.data_link_error import LimitExceededError
3-
from .api_config import ApiConfig
3+
from .api_config import get_config_from_kwargs
44
from .message import Message
55
import warnings
66
import copy
@@ -14,6 +14,8 @@ def get_table(datatable_code, **options):
1414

1515
data = None
1616
page_count = 0
17+
api_config = get_config_from_kwargs(options)
18+
1719
while True:
1820
next_options = copy.deepcopy(options)
1921
next_data = Datatable(datatable_code).data(params=next_options)
@@ -23,10 +25,10 @@ def get_table(datatable_code, **options):
2325
else:
2426
data.extend(next_data)
2527

26-
if page_count >= ApiConfig.page_limit:
28+
if page_count >= api_config.page_limit:
2729
raise LimitExceededError(
2830
Message.WARN_DATA_LIMIT_EXCEEDED % (datatable_code,
29-
ApiConfig.api_key
31+
api_config.api_key
3032
)
3133
)
3234

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from nasdaqdatalink.api_config import ApiConfig
2+
from nasdaqdatalink.get import get
3+
from nasdaqdatalink.bulkdownload import bulkdownload
4+
from nasdaqdatalink.export_table import export_table
5+
from nasdaqdatalink.get_table import get_table
6+
from nasdaqdatalink.get_point_in_time import get_point_in_time
7+
from urllib3.util.retry import Retry
8+
from requests.adapters import HTTPAdapter
9+
import requests
10+
import urllib
11+
12+
13+
def get_retries(api_config):
14+
if isinstance(api_config, ApiConfig):
15+
if not api_config.use_retries:
16+
return Retry(total=0)
17+
18+
Retry.BACKOFF_MAX = api_config.max_wait_between_retries
19+
retries = Retry(total=api_config.number_of_retries,
20+
connect=api_config.number_of_retries,
21+
read=api_config.number_of_retries,
22+
status_forcelist=api_config.retry_status_codes,
23+
backoff_factor=api_config.retry_backoff_factor,
24+
raise_on_status=False)
25+
return retries
26+
27+
28+
class AuthorizedSession:
29+
def __init__(self, api_config=ApiConfig) -> None:
30+
super(AuthorizedSession, self).__init__()
31+
self._api_config = api_config
32+
self._auth_session = requests.Session()
33+
retries = get_retries(self._api_config)
34+
adapter = HTTPAdapter(max_retries=retries)
35+
self._auth_session.mount(api_config.api_protocol, adapter)
36+
37+
proxies = urllib.request.getproxies()
38+
if proxies is not None:
39+
self._auth_session.proxies.update(proxies)
40+
41+
def get(self, dataset, **kwargs):
42+
get(dataset, session=self._auth_session, api_config=self._api_config, **kwargs)
43+
44+
def bulkdownload(self, database, **kwargs):
45+
bulkdownload(database, session=self._auth_session, api_config=self._api_config, **kwargs)
46+
47+
def export_table(self, datatable_code, **kwargs):
48+
export_table(datatable_code, session=self._auth_session,
49+
api_config=self._api_config, **kwargs)
50+
51+
def get_table(self, datatable_code, **options):
52+
get_table(datatable_code, session=self._auth_session,
53+
api_config=self._api_config, **options)
54+
55+
def get_point_in_time(self, datatable_code, **options):
56+
get_point_in_time(datatable_code, session=self._auth_session,
57+
api_config=self._api_config, **options)

nasdaqdatalink/model/database.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from six.moves.urllib.parse import urlencode, urlparse
44

55
import nasdaqdatalink.model.dataset
6-
from nasdaqdatalink.api_config import ApiConfig
6+
from nasdaqdatalink.api_config import get_config_from_kwargs
77
from nasdaqdatalink.connection import Connection
88
from nasdaqdatalink.errors.data_link_error import DataLinkError
99
from nasdaqdatalink.message import Message
@@ -21,15 +21,16 @@ def get_code_from_meta(cls, metadata):
2121
return metadata['database_code']
2222

2323
def bulk_download_url(self, **options):
24+
api_config = get_config_from_kwargs(options)
2425
url = self._bulk_download_path()
25-
url = ApiConfig.api_base + '/' + url
26+
url = api_config.api_base + '/' + url
2627

2728
if 'params' not in options:
2829
options['params'] = {}
29-
if ApiConfig.api_key:
30-
options['params']['api_key'] = ApiConfig.api_key
31-
if ApiConfig.api_version:
32-
options['params']['api_version'] = ApiConfig.api_version
30+
if api_config.api_key:
31+
options['params']['api_key'] = api_config.api_key
32+
if api_config.api_version:
33+
options['params']['api_version'] = api_config.api_version
3334

3435
if list(options.keys()):
3536
url += '?' + urlencode(options['params'])

nasdaqdatalink/utils/request_type_util.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from urllib.parse import urlencode
2-
from nasdaqdatalink.api_config import ApiConfig
2+
from nasdaqdatalink.api_config import get_config_from_kwargs
33

44

55
class RequestType(object):
@@ -13,7 +13,8 @@ class RequestType(object):
1313
@classmethod
1414
def get_request_type(cls, url, **params):
1515
query_string = urlencode(params['params'])
16-
request_url = '%s/%s/%s' % (ApiConfig.api_base, url, query_string)
16+
api_config = get_config_from_kwargs(params)
17+
request_url = '%s/%s/%s' % (api_config.api_base, url, query_string)
1718
if RequestType.USE_GET_REQUEST and (len(request_url) < cls.MAX_URL_LENGTH_FOR_GET):
1819
return 'get'
1920
else:

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy