-
Notifications
You must be signed in to change notification settings - Fork 2
/
nytimesarticle.py
115 lines (88 loc) · 3.5 KB
/
nytimesarticle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import requests
API_ROOT = 'http://api.nytimes.com/svc/search/v2/articlesearch.'
API_SIGNUP_PAGE = 'http://developer.nytimes.com/docs/reference/keys'
class NoAPIKeyException(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class articleAPI(object):
def __init__(self, key = None):
"""
Initializes the articleAPI class with a developer key. Raises an exception if a key is not given.
Request a key at http://developer.nytimes.com/docs/reference/keys
:param key: New York Times Developer Key
"""
self.key = key
self.response_format = 'json'
if self.key is None:
raise NoAPIKeyException('Warning: Missing API Key. Please visit ' + API_SIGNUP_PAGE + ' to register for a key.')
def _utf8_encode(self, d):
"""
Ensures all values are encoded in UTF-8 and converts them to lowercase
"""
for k, v in d.items():
if isinstance(v, str):
d[k] = v.encode('utf8').lower()
if isinstance(v, list):
for index,item in enumerate(v):
item = item.encode('utf8').lower()
v[index] = item
if isinstance(v, dict):
d[k] = self._utf8_encode(v)
return d
def _bool_encode(self, d):
"""
Converts bool values to lowercase strings
"""
for k, v in d.items():
if isinstance(v, bool):
d[k] = str(v).lower()
return d
def _options(self, **kwargs):
"""
Formats search parameters/values for use with API
:param \*\*kwargs: search parameters/values
"""
def _format_fq(d):
for k,v in d.items():
if isinstance(v, list):
d[k] = ' '.join(map(lambda x: '"' + x + '"', v))
else:
d[k] = '"' + v + '"'
values = []
for k,v in d.items():
value = '%s:(%s)' % (k,v)
values.append(value)
values = ' AND '.join(values)
return values
kwargs = self._utf8_encode(kwargs)
kwargs = self._bool_encode(kwargs)
values = ''
for k, v in kwargs.items():
if k is 'fq' and isinstance(v, dict):
v = _format_fq(v)
elif isinstance(v, list):
v = ','.join(v)
values += '%s=%s&' % (k, v)
return values
def search(self,
response_format = None,
key = None,
**kwargs):
"""
Calls the API and returns a dictionary of the search results
:param response_format: the format that the API uses for its response,
includes JSON (.json) and JSONP (.jsonp).
Defaults to '.json'.
:param key: a developer key. Defaults to key given when the articleAPI class was initialized.
"""
if response_format is None:
response_format = self.response_format
if key is None:
key = self.key
url = '%s%s?%sapi-key=%s' % (
API_ROOT, response_format, self._options(**kwargs), key
)
r = requests.get(url)
return r.json()