Skip to content

Commit 290dca6

Browse files
authored
Merge pull request #9 from bytesview/new_updates
added feature to execute raw_query
2 parents 5b11654 + ee94a49 commit 290dca6

2 files changed

Lines changed: 62 additions & 51 deletions

File tree

newsdataapi/newsdataapi_client.py

Lines changed: 61 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
from newsdataapi import constants
44
from typing import Optional,Union
55
from datetime import datetime,timezone
6-
from urllib.parse import urlencode, quote
76
from newsdataapi.helpers import FileHandler
87
from requests.exceptions import RequestException
8+
from urllib.parse import urlencode, quote,urlparse,parse_qs
99
from newsdataapi.newsdataapi_exception import NewsdataException
1010

1111
class NewsDataApiClient(FileHandler):
@@ -42,29 +42,61 @@ def api_proxies( self, proxies:dict)->None:
4242
""" Configure Proxie dictionary """
4343
self.proxies = proxies
4444

45-
def __validate_parms(self,param:str,value:Union[list,int,str,bool])->dict:
45+
def __validate_parms(self,user_param:dict)->dict:
4646
bool_params = {'full_content','image','video','removeduplicate'}
4747
int_params = {'size'}
4848
string_params = {
4949
'q','qInTitle','country','category','language','domain','domainurl','excludedomain','timezone','page',
5050
'from_date','to_date','apikey','qInMeta','prioritydomain','timeframe','tag','sentiment','region','coin',
5151
'excludefield'
5252
}
53+
54+
def validate_url(url:str)-> str:
55+
valid_fn_parms = {k.lower() for k in user_param.keys()}
56+
parsed_url = urlparse(url)
57+
if parsed_url.netloc:
58+
q_string = parse_qs(parsed_url.query)
59+
else:
60+
q_string = parse_qs(url)
61+
62+
valid_q_string = {}
63+
for k,v in q_string.items():
64+
k = k.strip().strip('%').strip('?').lower()
65+
if k in valid_fn_parms:
66+
valid_q_string[k] = v[0]
67+
else:
68+
raise TypeError(f'Provided parameter is invalid: {k}')
69+
70+
if not valid_q_string.get('apikey'):
71+
valid_q_string['apikey'] = self.apikey
5372

54-
if param in string_params:
55-
if isinstance(value,list):
56-
value = ','.join(value)
73+
return valid_q_string
74+
75+
if user_param.get('raw_query'):
76+
value = user_param['raw_query']
5777
if not isinstance(value,str):
58-
raise TypeError(f'{param} should be of type string.')
59-
elif param in bool_params:
60-
if not isinstance(value,bool):
61-
raise TypeError(f'{param} should be of type bool.')
62-
value = 1 if value == True else 0
63-
elif param in int_params:
64-
if not isinstance(value,int):
65-
raise TypeError(f'{param} should be of type int.')
78+
raise TypeError('raw_query should be of type string.')
79+
return validate_url(url=value)
6680

67-
return {param:value}
81+
valid_parms = {}
82+
for param,value in user_param.items():
83+
if not value:continue
84+
if param in string_params:
85+
if isinstance(value,list):
86+
value = ','.join(value)
87+
if not isinstance(value,str):
88+
raise TypeError(f'{param} should be of type string.')
89+
elif param in bool_params:
90+
if not isinstance(value,bool):
91+
raise TypeError(f'{param} should be of type bool.')
92+
value = 1 if value == True else 0
93+
elif param in int_params:
94+
if not isinstance(value,int):
95+
raise TypeError(f'{param} should be of type int.')
96+
97+
valid_parms[param] = value
98+
99+
return valid_parms
68100

69101
def __get_feeds(self,url:str,retry_count:int=None)-> dict:
70102
try:
@@ -157,7 +189,7 @@ def news_api(
157189
domainurl:Optional[Union[str, list]]=None, excludedomain:Optional[Union[str, list]]=None, timezone:Optional[str]=None, full_content:Optional[bool]=None,
158190
image:Optional[bool]=None, video:Optional[bool]=None, prioritydomain:Optional[str]=None, page:Optional[str]=None, scroll:Optional[bool]=False,
159191
max_result:Optional[int]=None, qInMeta:Optional[str]=None, tag:Optional[Union[str,list]]=None, sentiment:Optional[str]=None,
160-
region:Optional[Union[str,list]]=None,excludefield:Optional[Union[str,list]]=None,removeduplicate:Optional[bool]=None
192+
region:Optional[Union[str,list]]=None,excludefield:Optional[Union[str,list]]=None,removeduplicate:Optional[bool]=None,raw_query:Optional[str]=None
161193
)->dict:
162194
"""
163195
Sending GET request to the news api.
@@ -167,13 +199,9 @@ def news_api(
167199
params = {
168200
'apikey':self.apikey,'q':q,'qInTitle':qInTitle,'country':country,'category':category,'language':language,'domain':domain,'timeframe':str(timeframe) if timeframe else timeframe,
169201
'size':size,'domainurl':domainurl,'excludedomain':excludedomain,'timezone':timezone,'full_content':full_content,'image':image,'video':video,'prioritydomain':prioritydomain,
170-
'page':page,'qInMeta':qInMeta,'tag':tag, 'sentiment':sentiment, 'region':region,'excludefield':excludefield,'removeduplicate':removeduplicate
202+
'page':page,'qInMeta':qInMeta,'tag':tag, 'sentiment':sentiment, 'region':region,'excludefield':excludefield,'removeduplicate':removeduplicate,'raw_query':raw_query
171203
}
172-
URL_parameters = {}
173-
for key,value in params.items():
174-
if value is not None:
175-
URL_parameters.update(self.__validate_parms(param=key,value=value))
176-
204+
URL_parameters = self.__validate_parms(user_param=params)
177205
URL_parameters_encoded = urlencode(URL_parameters, quote_via=quote)
178206
if scroll == True:
179207
return self.__get_feeds_all(url=f'{constants.LATEST_URL}?{URL_parameters_encoded}',max_result=max_result)
@@ -186,7 +214,7 @@ def latest_api(
186214
domainurl:Optional[Union[str, list]]=None, excludedomain:Optional[Union[str, list]]=None, timezone:Optional[str]=None, full_content:Optional[bool]=None,
187215
image:Optional[bool]=None, video:Optional[bool]=None, prioritydomain:Optional[str]=None, page:Optional[str]=None, scroll:Optional[bool]=False,
188216
max_result:Optional[int]=None, qInMeta:Optional[str]=None, tag:Optional[Union[str,list]]=None, sentiment:Optional[str]=None,
189-
region:Optional[Union[str,list]]=None,excludefield:Optional[Union[str,list]]=None,removeduplicate:Optional[bool]=None
217+
region:Optional[Union[str,list]]=None,excludefield:Optional[Union[str,list]]=None,removeduplicate:Optional[bool]=None,raw_query:Optional[str]=None
190218
)->dict:
191219
"""
192220
Sending GET request to the latest api.
@@ -195,13 +223,9 @@ def latest_api(
195223
params = {
196224
'apikey':self.apikey,'q':q,'qInTitle':qInTitle,'country':country,'category':category,'language':language,'domain':domain,'timeframe':str(timeframe) if timeframe else timeframe,
197225
'size':size,'domainurl':domainurl,'excludedomain':excludedomain,'timezone':timezone,'full_content':full_content,'image':image,'video':video,'prioritydomain':prioritydomain,
198-
'page':page,'qInMeta':qInMeta,'tag':tag, 'sentiment':sentiment, 'region':region,'excludefield':excludefield,'removeduplicate':removeduplicate
226+
'page':page,'qInMeta':qInMeta,'tag':tag, 'sentiment':sentiment, 'region':region,'excludefield':excludefield,'removeduplicate':removeduplicate,'raw_query':raw_query
199227
}
200-
URL_parameters = {}
201-
for key,value in params.items():
202-
if value is not None:
203-
URL_parameters.update(self.__validate_parms(param=key,value=value))
204-
228+
URL_parameters = self.__validate_parms(user_param=params)
205229
URL_parameters_encoded = urlencode(URL_parameters, quote_via=quote)
206230
if scroll == True:
207231
return self.__get_feeds_all(url=f'{constants.LATEST_URL}?{URL_parameters_encoded}',max_result=max_result)
@@ -213,7 +237,7 @@ def archive_api(
213237
language:Optional[Union[str, list]]=None, domain:Optional[Union[str, list]]=None, size:Optional[int]=None,domainurl:Optional[Union[str, list]]=None,
214238
excludedomain:Optional[Union[str, list]]=None, timezone:Optional[str]=None, full_content:Optional[bool]=None,image:Optional[bool]=None,
215239
video:Optional[bool]=None,prioritydomain:Optional[str]=None, page:Optional[str]=None, scroll:Optional[bool]=False, max_result:Optional[int]=None,
216-
from_date:Optional[str]=None, to_date:Optional[str]=None, qInMeta:Optional[str]=None, excludefield:Optional[Union[str,list]]=None
240+
from_date:Optional[str]=None, to_date:Optional[str]=None, qInMeta:Optional[str]=None, excludefield:Optional[Union[str,list]]=None,raw_query:Optional[str]=None
217241
) -> dict:
218242
"""
219243
Sending GET request to the archive api
@@ -222,31 +246,22 @@ def archive_api(
222246
params = {
223247
'q':q,'qInTitle':qInTitle,'country':country,'category':category,'language':language,'domain':domain,'size':size,'domainurl':domainurl,'excludedomain':excludedomain,
224248
'timezone':timezone,'full_content':full_content,'image':image,'video':video,'prioritydomain':prioritydomain,'page':page,'from_date':from_date,'to_date':to_date,
225-
'apikey':self.apikey,'qInMeta':qInMeta,'excludefield':excludefield
249+
'apikey':self.apikey,'qInMeta':qInMeta,'excludefield':excludefield,'raw_query':raw_query
226250
}
227-
URL_parameters = {}
228-
for key,value in params.items():
229-
if value is not None:
230-
URL_parameters.update(self.__validate_parms(param=key,value=value))
231-
251+
URL_parameters = self.__validate_parms(user_param=params)
232252
URL_parameters_encoded = urlencode(URL_parameters, quote_via=quote)
233253
if scroll == True:
234254
return self.__get_feeds_all(url=f'{constants.ARCHIVE_URL}?{URL_parameters_encoded}',max_result=max_result)
235255
else:
236256
return self.__get_feeds(url=f'{constants.ARCHIVE_URL}?{URL_parameters_encoded}')
237257

238-
def sources_api( self, country:Optional[str]= None, category:Optional[str]= None, language:Optional[str]= None, prioritydomain:Optional[str]= None):
258+
def sources_api( self, country:Optional[str]= None, category:Optional[str]= None, language:Optional[str]= None, prioritydomain:Optional[str]= None,raw_query:Optional[str]=None):
239259
"""
240260
Sending GET request to the sources api
241261
For more information about parameters and input, Please visit our documentation page: https://newsdata.io/documentation
242262
"""
243-
URL_parameters = {}
244-
params = {"apikey":self.apikey, "country":country, "category":category, "language":language, "prioritydomain":prioritydomain}
245-
URL_parameters = {}
246-
for key,value in params.items():
247-
if value is not None:
248-
URL_parameters.update(self.__validate_parms(param=key,value=value))
249-
263+
params = {"apikey":self.apikey, "country":country, "category":category, "language":language, "prioritydomain":prioritydomain,'raw_query':raw_query}
264+
URL_parameters = self.__validate_parms(user_param=params)
250265
URL_parameters_encoded = urlencode(URL_parameters, quote_via=quote)
251266
return self.__get_feeds(url=f'{constants.SOURCES_URL}?{URL_parameters_encoded}')
252267

@@ -256,7 +271,7 @@ def crypto_api(
256271
timezone:Optional[str]=None, full_content:Optional[bool]=None,image:Optional[bool]=None, video:Optional[bool]=None, prioritydomain:Optional[str]=None,
257272
page:Optional[str]=None, scroll:Optional[bool]=False,max_result:Optional[int]=None, qInMeta:Optional[str]=None,tag:Optional[Union[str,list]]=None,
258273
sentiment:Optional[str]=None,coin:Optional[Union[str, list]]=None,excludefield:Optional[Union[str,list]]=None,from_date:Optional[str]=None,
259-
to_date:Optional[str]=None,removeduplicate:Optional[bool]=None
274+
to_date:Optional[str]=None,removeduplicate:Optional[bool]=None,raw_query:Optional[str]=None,
260275
)->dict:
261276
"""
262277
Sending GET request to the crypto api
@@ -267,13 +282,9 @@ def crypto_api(
267282
'apikey':self.apikey,'q':q,'qInTitle':qInTitle,'language':language,'domain':domain,'size':size,'domainurl':domainurl,
268283
'excludedomain':excludedomain,'timezone':timezone,'full_content':full_content,'image':image,'video':video,'prioritydomain':prioritydomain,'page':page,
269284
'timeframe':str(timeframe) if timeframe else timeframe,'qInMeta':qInMeta,'tag':tag, 'sentiment':sentiment,'coin':coin,'excludefield':excludefield,
270-
'from_date':from_date,'to_date':to_date,'removeduplicate':removeduplicate
285+
'from_date':from_date,'to_date':to_date,'removeduplicate':removeduplicate,'raw_query':raw_query
271286
}
272-
URL_parameters = {}
273-
for key,value in params.items():
274-
if value is not None:
275-
URL_parameters.update(self.__validate_parms(param=key,value=value))
276-
287+
URL_parameters = self.__validate_parms(user_param=params)
277288
URL_parameters_encoded = urlencode(URL_parameters, quote_via=quote)
278289
if scroll == True:
279290
return self.__get_feeds_all(url=f'{constants.CRYPTO_URL}?{URL_parameters_encoded}',max_result=max_result)

setup.py

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

77
setup(
88
name='newsdataapi',
9-
version='0.1.19',
9+
version='0.1.20',
1010
packages=['newsdataapi'],
1111
description='Python library for newsdata client-API Call',
1212
long_description=long_description,

0 commit comments

Comments
 (0)