Skip to content

Commit 94b4ed6

Browse files
author
himanshu
committed
added support for new filters
1 parent 0e7ddeb commit 94b4ed6

3 files changed

Lines changed: 190 additions & 19 deletions

File tree

README.md

Lines changed: 152 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,157 @@ pip install newsdataapi
2525

2626
## Documentation
2727

28-
Newsdataapi docs can be seen [here](https://newsdata.io/docs).
28+
Newsdataapi docs can be seen [here](https://newsdata.io/documentation).
29+
30+
<br />
31+
32+
### Latest News API
33+
34+
`GET /1/news`
35+
36+
```
37+
# To get latest news use our news_api method.
38+
39+
from newsdataapi import NewsDataApiClient
40+
41+
# API key authorization, Initialize the client with your API key
42+
43+
api = NewsDataApiClient(apikey='YOUR_API_KEY')
44+
response = api.news_api(q='entertainment')
45+
print(response)
46+
47+
# Latest news with page parameter
48+
49+
response = api.news_api(q='entertainment',page='nextPage_value')
50+
print(response)
51+
52+
# To scroll through all latest news
53+
54+
response = api.news_api(q='entertainment',page='nextPage_value',scroll=True)
55+
print(response)
56+
57+
```
58+
<br />
59+
60+
### News Archive API
61+
62+
`GET /1/archive`
63+
64+
```
65+
# To get archive news use our archive_api method.
66+
67+
from newsdataapi import NewsDataApiClient
68+
69+
# API key authorization, Initialize the client with your API key
70+
71+
api = NewsDataApiClient(apikey='YOUR_API_KEY')
72+
response = api.archive_api(q='olympic',from_date='2021-01-01',to_date='2021-06-06')
73+
print(response)
74+
75+
# Archive news with page parameter
76+
77+
response = api.archive_api(q='olympic',from_date='2021-01-01',to_date='2021-06-06',page='nextPage_value')
78+
print(response)
79+
80+
# To scroll through all archive news
81+
82+
response = api.archive_api(q='olympic',from_date='2021-01-01',to_date='2021-06-06',page='nextPage_value',scroll=True)
83+
print(response)
84+
85+
```
86+
<br />
87+
88+
89+
### News Sources API
90+
91+
`GET /1/sources`
92+
93+
```
94+
# To get sources use our sources_api method.
95+
96+
from newsdataapi import NewsDataApiClient
97+
98+
# API key authorization, Initialize the client with your API key
99+
100+
api = NewsDataApiClient(apikey="YOUR_API_KEY")
101+
response = api.sources_api()
102+
print(response)
103+
104+
```
105+
<br />
106+
107+
### Crypto News API
108+
109+
`GET /1/crypto`
110+
111+
```
112+
# To get crypto news use our crypto_api method.
113+
114+
from newsdataapi import NewsDataApiClient
115+
116+
# API key authorization, Initialize the client with your API key
117+
118+
api = NewsDataApiClient(apikey='YOUR_API_KEY')
119+
response = api.crypto_api(q='bitcoin')
120+
print(response)
121+
122+
# Crypto with page parameter
123+
124+
response = api.crypto_api(q='bitcoin',page='nextPage_value')
125+
print(response)
126+
127+
# To scroll through all crypto news
128+
129+
response = api.crypto_api(q='bitcoin',page='nextPage_value',scroll=True)
130+
print(response)
131+
132+
```
133+
<br />
134+
135+
### News API with Pagination
136+
137+
`GET /1/news`
138+
139+
```
140+
from newsdataapi import NewsDataApiClient
141+
142+
# API key authorization, Initialize the client with your API key
143+
144+
api = NewsDataApiClient(apikey="YOUR_API_KEY")
145+
response = api.news_api()
146+
147+
# You can go to next page by providing Page parameter
148+
149+
response = api.news_api(page = "nextPage value")
150+
151+
# You can paginate till last page by providing Page parameter in Loop
152+
153+
page=None
154+
while True:
155+
response = api.news_api(page = page)
156+
page = response.get('nextPage',None)
157+
if not page:
158+
break
159+
160+
```
161+
162+
<br />
163+
164+
### News API with Scrolling
165+
166+
```
167+
# Note: Scrolling through all result will counsume api as per your defined size. you can also define max_result to stop scrolling at desired result size.scroll is avaliable in news_archive,news_api and news_crypto, it will return all result when scrolling is compleated.
168+
169+
from newsdataapi import NewsDataApiClient
170+
171+
# API key authorization, Initialize the client with your API key
172+
173+
api = NewsDataApiClient(apikey="YOUR_API_KEY")
174+
175+
response = api.news_api(q='entertainment',page='nextPage_value',scroll=True,max_result=1000)
176+
print(response)
177+
178+
```
29179

30180
<br />
31181

@@ -40,4 +190,4 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
40190
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
41191
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
42192
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43-
```
193+
```

newsdataapi/constants.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@
1616
# Default request values
1717
DEFAULT_REQUEST_TIMEOUT = 300
1818
DEFAULT_MAX_RETRIES = 5
19-
DEFAULT_RETRY_DELAY = 30
19+
DEFAULT_RETRY_DELAY = 1800
20+
DEFAULT_RETRY_DELAY_TooManyRequests = 10
21+
DEFAULT_RETRY_DELAY_RateLimitExceeded = 900

newsdataapi/newsdataapi_client.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import requests,time
2+
from datetime import datetime
23
from newsdataapi import constants
34
from typing import Optional,Union
45
from urllib.parse import urlencode, quote
@@ -8,7 +9,7 @@ class NewsDataApiClient:
89

910
def __init__(
1011
self, apikey:str, session:bool= False, max_retries:int= constants.DEFAULT_MAX_RETRIES, retry_delay:int= constants.DEFAULT_RETRY_DELAY,
11-
proxies:Optional[dict]=None, request_timeout:int= constants.DEFAULT_REQUEST_TIMEOUT,max_result:int=10**10
12+
proxies:Optional[dict]=None, request_timeout:int= constants.DEFAULT_REQUEST_TIMEOUT,max_result:int=10**10, debug:Optional[bool]=False
1213
):
1314
"""Initializes newsdata client object for access Newsdata APIs."""
1415
self.apikey = apikey
@@ -19,6 +20,7 @@ def __init__(
1920
self.proxies = proxies
2021
self.request_timeout = request_timeout
2122
self.recursive_retry = max_retries
23+
self.is_debug = debug
2224

2325
def set_retries( self, max_retries:int, retry_delay:int)->None:
2426
""" API maximum retry and delay"""
@@ -36,7 +38,7 @@ def api_proxies( self, proxies:dict)->None:
3638
def __validate_parms(self,param:str,value:Union[list,int,str,bool])->dict:
3739
bool_params = {'full_content','image','video'}
3840
int_params = {'size','prioritydomain','timeframe'}
39-
string_params = {'q','qInTitle','country','category','language','domain','domainurl','excludedomain','timezone','page','from_date','to_date','apikey'}
41+
string_params = {'q','qInTitle','country','category','language','domain','domainurl','excludedomain','timezone','page','from_date','to_date','apikey','qInMeta'}
4042

4143
if param in string_params:
4244
if isinstance(value,list):
@@ -58,18 +60,35 @@ def __get_feeds(self,url:str)-> dict:
5860
if self.recursive_retry <= 0:
5961
raise NewsdataException('maximum retry limit reached.')
6062
response = self.request_method.get(url=url,proxies=self.proxies,timeout=self.request_timeout)
63+
if self.is_debug == True:
64+
headers = response.headers
65+
print(f'Debug | {datetime.utcnow().replace(microsecond=0)} | x_rate_limit_remaining: {headers.get("x_rate_limit_remaining")} | x_api_limit_remaining: {headers.get("x_api_limit_remaining")}')
6166
feeds_data:dict = response.json()
6267
if response.status_code != 200:
63-
if response.status_code == 500 or feeds_data.get('results',{}).get('code') == 'TooManyRequests' or feeds_data.get('results',{}).get('code') == 'RateLimitExceeded':
68+
if response.status_code == 500:
69+
if self.is_debug == True:
70+
print(f"Debug | {datetime.utcnow().replace(microsecond=0)} | Encountered 'ServerError' going to sleep for: {self.retry_delay} seconds.")
6471
time.sleep(self.retry_delay)
6572
self.recursive_retry-=1
6673
return self.__get_feeds(url=url)
67-
raise NewsdataException(response.json())
74+
elif feeds_data.get('results',{}).get('code') == 'TooManyRequests':
75+
if self.is_debug == True:
76+
print(f"Debug | {datetime.utcnow().replace(microsecond=0)} | Encountered 'TooManyRequests' going to sleep for: {constants.DEFAULT_RETRY_DELAY_TooManyRequests} seconds.")
77+
time.sleep(constants.DEFAULT_RETRY_DELAY_TooManyRequests)
78+
self.recursive_retry-=1
79+
return self.__get_feeds(url=url)
80+
elif feeds_data.get('results',{}).get('code') == 'RateLimitExceeded':
81+
if self.is_debug == True:
82+
print(f"Debug | {datetime.utcnow().replace(microsecond=0)} | Encountered 'RateLimitExceeded' going to sleep for: {constants.DEFAULT_RETRY_DELAY_RateLimitExceeded} seconds.")
83+
time.sleep(constants.DEFAULT_RETRY_DELAY_RateLimitExceeded)
84+
self.recursive_retry-=1
85+
return self.__get_feeds(url=url)
86+
else:
87+
raise NewsdataException(response.json())
6888
else:
6989
self.recursive_retry = self.max_retries
7090
return feeds_data
7191
except requests.exceptions.ConnectionError:
72-
time.sleep(self.retry_delay)
7392
if isinstance(self.request_method,requests.Session):
7493
self.request_method = requests.Session()
7594
self.recursive_retry-=1
@@ -88,12 +107,11 @@ def __get_feeds_all(self,url:str)-> dict:
88107
response = self.__get_feeds(url=f'{url}&page={data.get("nextPage")}' if data.get('results') else url)
89108
data['totalResults'] = response.get('totalResults')
90109
results = response.get('results')
91-
for feed in results:
92-
data['results'].append(feed)
93-
feeds_count+=1
94-
if feeds_count >= self.max_result:
95-
return data
110+
data['results'].extend(results)
96111
data['nextPage'] = response.get('nextPage')
112+
feeds_count+=len(results)
113+
if feeds_count >= self.max_result:
114+
return data
97115
time.sleep(0.5)
98116
return data
99117

@@ -102,7 +120,7 @@ def news_api(
102120
language:Optional[Union[str, list]]=None, domain:Optional[Union[str, list]]=None, timeframe:Optional[int]=None, size:Optional[int]=None,
103121
domainurl:Optional[Union[str, list]]=None, excludedomain:Optional[Union[str, list]]=None, timezone:Optional[str]=None, full_content:Optional[bool]=None,
104122
image:Optional[bool]=None, video:Optional[bool]=None, prioritydomain:Optional[int]=None, page:Optional[str]=None, scroll:Optional[bool]=False,
105-
max_result:Optional[int]=None
123+
max_result:Optional[int]=None, qInMeta:Optional[str]=None
106124
)->dict:
107125
"""
108126
Sending GET request to the news api.
@@ -111,7 +129,7 @@ def news_api(
111129
params = {
112130
'apikey':self.apikey,'q':q,'qInTitle':qInTitle,'country':country,'category':category,'language':language,'domain':domain,'timeframe':timeframe,'size':size,
113131
'domainurl':domainurl,'excludedomain':excludedomain,'timezone':timezone,'full_content':full_content,'image':image,'video':video,'prioritydomain':prioritydomain,
114-
'page':page,
132+
'page':page,'qInMeta':qInMeta
115133
}
116134

117135
URL_parameters = {}
@@ -132,7 +150,7 @@ def archive_api(
132150
language:Optional[Union[str, list]]=None, domain:Optional[Union[str, list]]=None, size:Optional[int]=None,domainurl:Optional[Union[str, list]]=None,
133151
excludedomain:Optional[Union[str, list]]=None, timezone:Optional[str]=None, full_content:Optional[bool]=None,image:Optional[bool]=None,
134152
video:Optional[bool]=None,prioritydomain:Optional[int]=None, page:Optional[str]=None, scroll:Optional[bool]=False, max_result:Optional[int]=None,
135-
from_date:Optional[str]=None, to_date:Optional[str]=None
153+
from_date:Optional[str]=None, to_date:Optional[str]=None, qInMeta:Optional[str]=None
136154
) -> dict:
137155
"""
138156
Sending GET request to the archive api
@@ -141,7 +159,7 @@ def archive_api(
141159
params = {
142160
'q':q,'qInTitle':qInTitle,'country':country,'category':category,'language':language,'domain':domain,'size':size,'domainurl':domainurl,'excludedomain':excludedomain,
143161
'timezone':timezone,'full_content':full_content,'image':image,'video':video,'prioritydomain':prioritydomain,'page':page,'from_date':from_date,'to_date':to_date,
144-
'apikey':self.apikey
162+
'apikey':self.apikey,'qInMeta':qInMeta
145163
}
146164
URL_parameters = {}
147165
for key,value in params.items():
@@ -177,7 +195,7 @@ def crypto_api(
177195
language:Optional[Union[str, list]]=None, domain:Optional[Union[str, list]]=None, timeframe:Optional[int]=None, size:Optional[int]=None,
178196
domainurl:Optional[Union[str, list]]=None, excludedomain:Optional[Union[str, list]]=None, timezone:Optional[str]=None, full_content:Optional[bool]=None,
179197
image:Optional[bool]=None, video:Optional[bool]=None, prioritydomain:Optional[int]=None, page:Optional[str]=None, scroll:Optional[bool]=False,
180-
max_result:Optional[int]=None
198+
max_result:Optional[int]=None, qInMeta:Optional[str]=None
181199
)->dict:
182200
"""
183201
Sending GET request to the crypto api
@@ -186,7 +204,8 @@ def crypto_api(
186204

187205
params = {
188206
'apikey':self.apikey,'q':q,'qInTitle':qInTitle,'country':country,'category':category,'language':language,'domain':domain,'size':size,'domainurl':domainurl,
189-
'excludedomain':excludedomain,'timezone':timezone,'full_content':full_content,'image':image,'video':video,'prioritydomain':prioritydomain,'page':page,'timeframe':timeframe
207+
'excludedomain':excludedomain,'timezone':timezone,'full_content':full_content,'image':image,'video':video,'prioritydomain':prioritydomain,'page':page,
208+
'timeframe':timeframe,'qInMeta':qInMeta
190209
}
191210

192211
URL_parameters = {}

0 commit comments

Comments
 (0)