11import requests
22from newsapi .newsapi_auth import NewsApiAuth
3+ from newsapi import const
34
45
56class NewsApiClient (object ):
67
7- def __init__ (self , api_key , api_url = 'https://newsapi.org/v2/' ):
8- self .url = api_url .rstrip ('/' )
8+ def __init__ (self , api_key ):
99 self .auth = NewsApiAuth (api_key = api_key )
1010
1111 def get_top_headlines (self , q = None , sources = None , language = None , country = None , category = None , page_size = None ,
1212 page = None ):
1313 """
14- Returns live top and breaking headlines for a country, specific category in a country, single source, or multiple sources..
14+ Returns live top and breaking headlines for a country, specific category in a country, single source, or multiple sources..
1515
1616 Optional parameters:
17- (str) q - return headlines w/ specified coin! Valid values are :
18- 'bitcoin', 'etheremum ', 'ripple ', 'bitcoin cash ', etc.
17+ (str) q - return headlines w/ specific keyword or phrase. For example :
18+ 'bitcoin', 'trump ', 'tesla ', 'ethereum ', etc.
1919
2020 (str) sources - return headlines of news sources! some Valid values are:
21- 'bbc-news', 'the-verge', 'abc-news', 'crypto coins news',
22- 'ary news','associated press','wired','aftenposten','australian financial review','axios',
23- 'bbc news','bild','blasting news','bloomberg','business insider','engadget','google news',
24- 'hacker news','info money,'recode','techcrunch','techradar','the next web','the verge' etc.
21+ 'bbc-news', 'the-verge', 'abc-news', 'crypto coins news',
22+ 'ary news','associated press','wired','aftenposten','australian financial review','axios',
23+ 'bbc news','bild','blasting news','bloomberg','business insider','engadget','google news',
24+ 'hacker news','info money,'recode','techcrunch','techradar','the next web','the verge' etc.
2525
26- (str) language - The 2-letter ISO-639-1 code of the language you want to get headlines for. Valid values are:
27- 'ar','de','en','es','fr','he','it','nl','no','pt','ru','se','ud','zh'
26+ (str) language - The 2-letter ISO-639-1 code of the language you want to get headlines for. Valid values are:
27+ 'ar','de','en','es','fr','he','it','nl','no','pt','ru','se','ud','zh'
2828
2929 (str) country - The 2-letter ISO 3166-1 code of the country you want to get headlines! Valid values are:
30- 'ae','ar','at','au','be','bg','br','ca','ch','cn','co','cu','cz','de','eg','fr','gb','gr', 'hk','hu','id','ie','il','in','it','jp','kr','lt','lv','ma','mx','my','ng','nl','no','nz','ph' 'pl','pt','ro','rs','ru','sa','se','sg','si','sk','th','tr','tw','ua','us'
30+ 'ae','ar','at','au','be','bg','br','ca','ch','cn','co','cu','cz','de','eg','fr','gb','gr',
31+ 'hk','hu','id','ie','il','in','it','jp','kr','lt','lv','ma','mx','my','ng','nl','no','nz',
32+ 'ph','pl','pt','ro','rs','ru','sa','se','sg','si','sk','th','tr','tw','ua','us'
3133
32- (str) category - The category you want to get headlines for! Valid values are:
33- 'business','entertainment','general','health','science','sports','technology'
34+ (str) category - The category you want to get headlines for! Valid values are:
35+ 'business','entertainment','general','health','science','sports','technology'
3436
35- (int) page_size - The number of results to return per page (request). 20 is the default, 100 is the maximum.
37+ (int) page_size - The number of results to return per page (request). 20 is the default, 100 is the maximum.
3638
37- (int) page - Use this to page through the results if the total results found is greater than the page size.
39+ (int) page - Use this to page through the results if the total results found is greater than the page size.
3840 """
3941
4042 # Define Payload
4143 payload = {}
42- payload ['q' ] = q
43- payload ['sources' ] = sources
44- payload ['language' ] = language
45- payload ['country' ] = country
46- payload ['category' ] = category
47- payload ['pageSize' ] = page_size
48- payload ['page' ] = page
44+
45+ # Keyword/Phrase
46+ if q is not None :
47+ if type (q ) == str :
48+ payload ['q' ] = q
49+ else :
50+ raise TypeError ('keyword/phrase q param should be a str' )
51+
52+ # Sources
53+ if (country is not None ) or (category is not None ):
54+ raise ValueError ('cannot mix country/category param with sources param.' )
55+ else :
56+ if type (sources ) == str :
57+ payload ['sources' ] = sources
58+ else :
59+ raise TypeError ('sources param should be a str' )
60+
61+ # Language
62+ if language is not None :
63+ if type (language ) == str :
64+ if language in const .languages :
65+ payload ['language' ] = language
66+ else :
67+ raise ValueError ('invalid language' )
68+ else :
69+ raise TypeError ('language param should be a string' )
70+
71+ # Country
72+ if country is not None :
73+ if type (country ) == str :
74+ if country in const .countries :
75+ payload ['country' ] = country
76+ else :
77+ raise ValueError ('invalid country' )
78+ else :
79+ raise TypeError ('country param should be a string' )
80+
81+ # Category
82+ if category is not None :
83+ if type (category ) == str :
84+ if category in const .categories :
85+ payload ['category' ] = category
86+ else :
87+ raise ValueError ('invalid category' )
88+ else :
89+ raise TypeError ('category param should be a string' )
90+
91+ # Page Size
92+ if page_size is not None :
93+ if type (page_size ) == int :
94+ if page_size >= 0 and page_size <= 100 :
95+ payload ['pageSize' ] = page_size
96+ else :
97+ raise ValueError ('page_size param should be an int between 1 and 100' )
98+ else :
99+ raise TypeError ('page_size param should be an int' )
100+
101+ # Page
102+ if page is not None :
103+ if type (page ) == int :
104+ if page > 0 :
105+ payload ['page' ] = page
106+ else :
107+ raise ValueError ('page param should be an int greater than 0' )
108+ else :
109+ raise TypeError ('page param should be an int' )
49110
50111 # Send Request
51- r = requests .get (self .url + '/top-headlines' , auth = self .auth , timeout = 30 , params = payload )
112+ r = requests .get (const .TOP_HEADLINES_URL , auth = self .auth , timeout = 30 , params = payload )
113+
114+ # Check Status of Request
115+ if r .status_code != requests .codes .ok :
116+ raise NewsAPIException (r .json ())
117+
52118 return r .json ()
53119
54- def get_everything (self , q = None , sources = None , domains = None , from_parameter = None , to = None , language = None ,
120+ def get_everything (self , q = None , sources = None , domains = None , from_param = None , to_param = None , language = None ,
55121 sort_by = None , page = None , page_size = None ):
56- """
122+ """
57123 Search through millions of articles from over 5,000 large and small news sources and blogs.
58124
59125 Optional parameters:
60126 (str) q - return headlines w/ specified coin! Valid values are:
61- 'bitcoin', 'etheremum ', 'ripple ', 'bitcoin cash ', etc.
127+ 'bitcoin', 'trump ', 'tesla ', 'ethereum ', etc
62128
63129 (str) sources - return headlines of news sources! some Valid values are:
64130 'bbc-news', 'the-verge', 'abc-news', 'crypto coins news',
65131 'ary news','associated press','wired','aftenposten','australian financial review','axios',
66132 'bbc news','bild','blasting news','bloomberg','business insider','engadget','google news',
67133 'hacker news','info money,'recode','techcrunch','techradar','the next web','the verge' etc.
68134
69- (str) domains - A comma-seperated string of domains (eg bbc.co.uk, techcrunch.com, engadget.com) to restrict the search to.
70- (str) from_parameter - A date and optional time for the oldest article allowed.(e.g. 2018-03-05 or 2018-03-05T03:46:15)
135+ (str) domains - A comma-seperated string of domains (eg bbc.co.uk, techcrunch.com, engadget.com) to restrict the search to.
136+
137+ (str) from_parameter - A date and optional time for the oldest article allowed.
138+ (e.g. 2018-03-05 or 2018-03-05T03:46:15)
71139
72140 (str) to - A date and optional time for the newest article allowed.
73141
@@ -78,37 +146,131 @@ def get_everything(self, q=None, sources=None, domains=None, from_parameter=None
78146 'relevancy'
79147
80148 (int) page_size - The number of results to return per page (request). 20 is the default, 100 is the maximum.
81- (int) page - Use this to page through the results if the total results found is greater than the page size.
149+
150+ (int) page - Use this to page through the results if the total results found is greater than the page size.
82151 """
83152
84153 # Define Payload
85154 payload = {}
86- payload ['q' ] = q
87- payload ['sources' ] = sources
88- payload ['domains' ] = domains
89- payload ['from' ] = from_parameter
90- payload ['to' ] = to
91- payload ['language' ] = language
92- payload ['sortBy' ] = sort_by
93- payload ['page' ] = page
94- payload ['pageSize' ] = page_size
155+
156+ # Keyword/Phrase
157+ if q is not None :
158+ if type (q ) == str :
159+ payload ['q' ] = q
160+ else :
161+ raise TypeError ('keyword/phrase q param should be a str' )
162+
163+ # Sources
164+ if (country is not None ) or (category is not None ):
165+ raise ValueError ('cannot mix country or category param with sources param.' )
166+ else :
167+ if type (sources ) == str :
168+ payload ['sources' ] = sources
169+ else :
170+ raise TypeError ('sources param should be a str' )
171+
172+ # Domains To Search
173+ if domains is not None :
174+ if type (domains ) == str :
175+ payload ['domains' ] = domains
176+ else :
177+ raise TypeError ('domains param should be a string' )
178+
179+ # Search From This Date ...
180+ if from_param is not None :
181+ if type (from_param ) == str :
182+ if (len (from_param )) >= 10 :
183+ for i in range (len (from_param )):
184+ if (i == 4 and from_param [i ] != '-' ) or (i == 7 and from_param [i ] != '-' ):
185+ raise ValueError ('from_param should be in the format of YYYY-MM-DD' )
186+ else :
187+ payload ['from' ] = from_param
188+ else :
189+ raise ValueError ('from_param should be in the format of YYYY-MM-DD' )
190+ else :
191+ raist TypeError ('from_param should be a string' )
192+
193+ # ... To This Date
194+ if to_param is not None :
195+ if type (to_param ) == str :
196+ if (len (to_param )) >= 10 :
197+ for i in range (len (to_param )):
198+ if (i == 4 and to_param [i ] != '-' ) or (i == 7 and to_param [i ] != '-' ):
199+ raise ValueError ('to_param should be in the format of YYYY-MM-DD' )
200+ else :
201+ payload ['to' ] = to_param
202+ else :
203+ raise ValueError ('to_param should be in the format of YYYY-MM-DD' )
204+ else :
205+ raist TypeError ('to_param should be a string' )
206+
207+
208+ # Language
209+ if language is not None :
210+ if type (language ) == str :
211+ if language is not in const .languages :
212+ raise ValueError ('invalid language' )
213+ else :
214+ payload ['language' ] = language
215+ else :
216+ raise TypeError ('language param should be a string' )
217+
218+
219+ # Sort Method
220+ if sort_by is not None :
221+ if type (sort_by ) == str :
222+ if sort_by in const .sort_method :
223+ payload ['sortBy' ] = sort_by
224+ else :
225+ raise ValueError ('invalid sort' )
226+ else :
227+ raise TypeError ('sort_by param should be a string' )
228+
229+ # Page Size
230+ if page_size is not None :
231+ if type (page_size ) == int :
232+ if page_size >= 0 and page_size <= 100 :
233+ payload ['pageSize' ] = page_size
234+ else :
235+ raise ValueError ('page_size param should be an int between 1 and 100' )
236+ else :
237+ raise TypeError ('page_size param should be an int' )
238+
239+ # Page
240+ if page is not None :
241+ if type (page ) == int :
242+ if page > 0 :
243+ payload ['page' ] = page
244+ else :
245+ raise ValueError ('page param should be an int greater than 0' )
246+ else :
247+ raise TypeError ('page param should be an int' )
248+
95249
96250 # Send Request
97- r = requests .get (self .url + '/everything' , auth = self .auth , timeout = 30 , params = payload )
251+ r = requests .get (const .EVERYTHING_URL , auth = self .auth , timeout = 30 , params = payload )
252+
253+ #Check Status of Request
254+ if r .status_code != requests .codes .ok :
255+ raise NewsAPIException (r .json ())
256+
98257 return r .json ()
99258
100259 def get_sources (self , category = None , language = None , country = None ):
101-
102- """
260+ """
103261 Returns the subset of news publishers that top headlines...
104262
105263 Optional parameters:
264+ (str) category - The category you want to get headlines for! Valid values are:
265+ 'business','entertainment','general','health','science','sports','technology'
106266
107267 (str) language - The 2-letter ISO-639-1 code of the language you want to get headlines for. Valid values are:
108268 'ar','de','en','es','fr','he','it','nl','no','pt','ru','se','ud','zh'
109269
110270 (str) country - The 2-letter ISO 3166-1 code of the country you want to get headlines! Valid values are:
111- 'ae','ar','at','au','be','bg','br','ca','ch','cn','co','cu','cz','de','eg','fr','gb','gr', 'hk','hu','id','ie','il','in','it','jp','kr','lt','lv','ma','mx','my','ng','nl','no','nz','ph' 'pl','pt','ro','rs','ru','sa','se','sg','si','sk','th','tr','tw','ua','us'
271+ 'ae','ar','at','au','be','bg','br','ca','ch','cn','co','cu','cz','de','eg','fr','gb','gr',
272+ 'hk','hu','id','ie','il','in','it','jp','kr','lt','lv','ma','mx','my','ng','nl','no','nz',
273+ 'ph','pl','pt','ro','rs','ru','sa','se','sg','si','sk','th','tr','tw','ua','us'
112274
113275 (str) category - The category you want to get headlines for! Valid values are:
114276 'business','entertainment','general','health','science','sports','technology'
@@ -117,13 +279,43 @@ def get_sources(self, category=None, language=None, country=None):
117279
118280 # Define Payload
119281 payload = {}
120- payload ['category' ] = category
121- payload ['language' ] = language
122- payload ['country' ] = country
282+
283+ # Language
284+ if language is not None :
285+ if type (language ) == str :
286+ if language in const .languages :
287+ payload ['language' ] = language
288+ else :
289+ raise ValueError ('invalid language' )
290+ else :
291+ raise TypeError ('language param should be a string' )
292+
293+ # Country
294+ if country is not None :
295+ if type (country ) == str :
296+ if country in const .countries :
297+ payload ['country' ] = country
298+ else :
299+ raise ValueError ('invalid country' )
300+ else :
301+ raise TypeError ('country param should be a string' )
302+
303+ # Category
304+ if category is not None :
305+ if type (category ) == str :
306+ if category in const .categories :
307+ payload ['category' ] = category
308+ else :
309+ raise ValueError ('invalid category' )
310+ else :
311+ raise TypeError ('category param should be a string' )
123312
124313 # Send Request
125- r = requests .get (self .url + '/sources' , auth = self .auth , timeout = 30 , params = payload )
126- return r .json ()
314+ r = requests .get (const .SOURCES_URL , auth = self .auth , timeout = 30 , params = payload )
127315
316+ # Check Status of Request
317+ if r .status_code != requests .codes .ok :
318+ raise NewsAPIException (r .json ())
128319
320+ return r .json ()
129321
0 commit comments