Python Forum
Need help to correct my python function for fetching full data!
Thread Rating:
  • 1 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need help to correct my python function for fetching full data!
#1
I am trying to fetch product data from an api using Python3.6.

By default this api returns 20 products and in a single request the api can return max 500 products if we use api's parameter Limit=500.

So for fetching all products we need to use one more parameter with Limit- Offset(Number of products to skip).

I have written following function to achieve this but in case of full data my function is not working well and it's giving me error like- Login failed, Signature mismatching.

def get_data(userid, api_key, action, pagination=True): timeformat = datetime.datetime.now().replace(microsecond=0).isoformat() + '+08:00' endpoint = 'https://example.com' page_json = {} # set required parameters for this api parameters = { 'UserID': userid, 'Version': '1.0', 'Action': action, 'Format': 'JSON', 'Timestamp': timeformat } if pagination: page = 0 parameters['Limit'] = 500 while True: parameters['Offset'] = 500 * page # set the required cryptographic signature concatenated = urllib.parse.urlencode(sorted(parameters.items())) parameters['Signature'] = HMAC(api_key, concatenated.encode('utf-8'), sha256).hexdigest() page += 1 try: response = requests.get(endpoint, params=parameters) page_json = response.json() except requests.exceptions.ConnectionError: print("Connection refused!") sleep(5) else: try: concatenated = urllib.parse.urlencode(sorted(parameters.items())) # set the required cryptographic signature parameters['Signature'] = HMAC(api_key, concatenated.encode('utf-8'), sha256).hexdigest() response = requests.get(endpoint, params=parameters) page_json = response.json() except requests.exceptions.ConnectionError: print("Connection refused!") sleep(5) return page_json
It looks like I am not fitting my signature parameter line correctly in case of full data.

Can you please look into my function and help me to find out what I have written wrong and what it should be like?
Reply
#2
Hi,

The 2 things I see there are that when you put pagination = True you enter in an endless loop and that you overwrite the results of the previous query.

I have not way to try it, specially confirm that the json object returned is a list of results and there is not more wrappers... but try this:
def get_data(userid, api_key, action, limit=500): timeformat = datetime.datetime.now().replace(microsecond=0).isoformat() + '+08:00' endpoint = 'https://example.com' page_json = {} # set required parameters for this api parameters = { 'UserID': userid, 'Version': '1.0', 'Action': action, 'Format': 'JSON', 'Timestamp': timeformat } if limit > 0: parameters['Limit'] = limit page = 0 while True: parameters['Offset'] = limit * page # set the required cryptographic signature concatenated = urllib.parse.urlencode(sorted(parameters.items())) parameters['Signature'] = HMAC(api_key, concatenated.encode('utf-8'), sha256).hexdigest() try: response = requests.get(endpoint, params=parameters) except requests.exceptions.ConnectionError: print("Connection refused!") sleep(5) # As the page was not recovered, just try it again, # do not increase the page counter continue # Ok, one page recovered, append to the total result page += 1 # Here I assume the answer is a dictionary of entries like: # { 501: value, 502: value, ...} # you might need to look for the right element to accumulate. # i.e.: if response is something like: # {'result': [value, value, value...]} # The following lines will not be valid delta = response.json() page_json.update(delta) # This might be the end, no more pages... but this criteria again depends # on the api you are using if len(delta) % limit == 0: # Here we enter only if the number of results are 0 or 500 break else: try: concatenated = urllib.parse.urlencode(sorted(parameters.items())) # set the required cryptographic signature parameters['Signature'] = HMAC(api_key, concatenated.encode('utf-8'), sha256).hexdigest() response = requests.get(endpoint, params=parameters) page_json = response.json() except requests.exceptions.ConnectionError: print("Connection refused!") sleep(5) return page_json
Notice that I changed your pagination flag with the limit number (so you can request 50 by 50, 100 by 100...) use limit=0 for the equivalent of your pagination=False.
Reply
#3
Thanks killerrex!
I am able to find issue in my code.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Extracting the correct data from a CSV file S2G 6 2,948 Jun-03-2024, 04:50 PM
Last Post: snippsat
  fetching exit status hangs in paramiko saisankalpj 3 3,211 Dec-04-2022, 12:21 AM
Last Post: nilamo
  Fetching the port number using asyncio gary 0 1,910 Nov-01-2022, 02:53 AM
Last Post: gary
  The formula in the function is not giving the correct value quest 1 2,152 Mar-30-2022, 03:20 AM
Last Post: quest
  How to make a test data file for the full length of definition? MDRI 6 5,880 Apr-16-2021, 01:47 AM
Last Post: MDRI
  Fetching data from multiple tables in a single request. swaroop 0 2,869 Jan-09-2021, 04:23 PM
Last Post: swaroop
  Correct data structure for this problem Wigi 13 8,401 Oct-09-2020, 11:09 AM
Last Post: buran
  How do I get full XPath extract using Python? MDRI 1 3,406 Sep-18-2020, 02:13 AM
Last Post: MDRI
  How to append a tuple full of records to a dbf file in Python? DarkCoder2020 4 6,289 May-29-2020, 02:40 PM
Last Post: DarkCoder2020
  Python animate live plotting fetching data from Mysql Table dhirajm 6 6,276 Apr-24-2020, 05:07 PM
Last Post: dhirajm

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020
This forum uses Lukasz Tkacz MyBB addons.
Forum use Krzysztof "Supryk" Supryczynski addons.