Where to store data, in flask, while paginating - python

Respected people:
I need a hint as to where should I hold the data, that I need to paginate, I am using flask.
Should I use session to remember what data I sent earlier, and do the same for subsequent requests?
Also, how should I hold the data sent from the API in json format?
data_received_from_the_api = calltoApi()
#How do I make flask to remember/store above data,
#for pagination, If I am not using sessions.
I am thinking of maintaining a list, with session[current-index], session[previous-index]. The json data has 5 fields and the number of json-records sent by the API is 100.
Could it be done without using session?

I used a list approach in a project:
When the page is loaded, if the req is a POST it check for previous ones and rememberers the actual:
if request.method == "POST" and list(request.form.to_dict().values())[0] in req_indicator_html_names_dict.keys() :
selector_remember = ast.literal_eval( list(request.form.to_dict().keys())[0] )
else :
selector_remember = []
appending the actual request to the list:
selector_remember.append( req_ind_html_name )
It then pass the list to the page so you can keep track of the previous requests.
Hope it helps!

Related

post request using python for multiple json body

I am trying to post requests to a url with input body as a dict, here's the sample code
import requests
json_ = [{"foo":"bar"},{"foo1":"bar1"},{"foo2":"bar2"}]
for i in json_:
r = requests.post(url, json=i,auth=auth)
print(r.text)
but i have around 20k dict bodies, and using for loop takes lot of time,is there any way i can get the request content by passing all json_ in a single POST ?
That depends on the API you're posting to. If it only accepts a single object at a time, no.
You could split the job between threads and speed up the progress a lot that way. You can split up the list in some five lists and make a function that does the post. Then, make a thread for each list, start them and join them.
https://realpython.com/intro-to-python-threading/

Imgur API - How do I retrieve all favorites without pagination?

According to the Imgur Docs, the "GET Account Favorites" API call takes optional arguments for pagination, implying that all objects are returned without it.
However, when I use the following code snippet (the application has been registered and OAuth has already performed against my account for testing), I get only the first 30 JSON objects. In the snippet below, I already have an access_token for an authorized user and can retrieve data for that username. But the length of the returned list is always the first 30 items.
username = token['username']
bearer_headers = {
'Authorization': 'Bearer ' + token['access_token']
}
fav_url = 'https://api.imgur.com/3/account/' + username + '/' + 'favorites'
r = requests.get(fav_url, headers=bearer_headers)
r_json = r.json()
favorites=r_json['data']
len(favorites)
print(favorites)
The requests response returns a dictionary with three keys: status (the HTTP status code), success (true or false), and data, of which the value is a list of dictionaries (one per favorited item).
I'm trying to retrieve this without pagination so I can extract specific metadata values into a Pandas dataframe (id, post date, etc).
I originally thought this was a Pandas display problem in Jupyter notebook, but tracked it back to the API only returning the newest 30 list items, despite the docs indicating otherwise. If I place an arbitrary page number at the end (eg, "/favorites/1"), it returns the 30 items appropriate to that page, but there doesn't seem to be an option to get all items or retrieve a count of the total items or number of pages in advance.
What am I missing?
Postscript: It appears that none of the URIs work without pagination, eg, get account images, get gallery submissions, etc. Anything where there is an optional "/{{page}}" parameter, it will default to first page if none is specified. So I guess the larger question is, "does Imgur API even support non-paginated data, and how is that accessed?".
Paginated data is usually used when the possible size of the response can be arbitrarily large. I would be surprised if a major service like Imgur had an API that didn't work this way.
As you have found, the page attribute may be optional, and if you don't provide it, you get the first page as your response.
If you want to get more than the first page, you will need to loop over the page number:
data = []
page = 0
while block := connection.get(page=page):
data.append(block)
page += 1
This assumes Python3.8+ due to the := assignment expression. If you are on an older version you'll need to set block in the loop body, but the same idea applies.

Response to a google form including text box?

Here is my example form: https://docs.google.com/forms/d/e/1FAIpQLSfVXZ1721ZRrHetp1qUak9T-o-MwKA9G3q01rLAFI2OJhZjUw/viewform
I want to send a response to it with python, but I don't know how to fill the "text box", so I can't even start it. Can you help me, please?
For submitting data to google form you first need to replace viewform to formResponse in your url.
You are going to POST submission to the form response URL.
You need to keep 2 things in mind.
Get the form response URL. It can be found by replacing your form ID into the following:
https://docs.google.com/forms/d/<form_id>/formResponse
Assemble the submission. This will be a dictionary reference with keys being the IDs of the form questions and the values being what you'd like to submit. To get the IDs, again go to your live form and inspect the html (Right Click -> Inspect Elements) components where you would typically input your information. You should discover a group of ss-structure passage objects with name attribute like:
name="entry.<id>"
A simple program to send response would be:
import requests
url ="https://docs.google.com/forms/d/e/1FAIpQLSfVXZ1721ZRrHetp1qUak9T-o-MwKA9G3q01rLAFI2OJhZjUw/formResponse"
data_to_send = 'DATA' # Assign Data to be sent
requests.post(url, {"entry.685250623":data_to_send}) # Found the entry Id viewing your form
Hope this answers your question!!!

In GMail API, using Python 3, how do I skip to the last page of my results?

I am using GMail API to mine some informations like flights, receipts, invoices, ecc.
I want to skip a number of pages or skip to the very last one. How do I do that with Python?
You can skip pages by relying on the nextPageToken field as described in the reference of the list call. The nextPageToken field is part of the response payload.
query = 'example query has:attachment'
nextPageToken = ''
# The following while goes through all pages using the nextPageToken key in the response.
while True:
### GET MESSAGES THAT MATCH A QUERY
msg_results = service.users().messages().list(userId='me', maxResults=20, pageToken=nextPageToken, q=query).execute()
# messages = msg_results.get('messages', [])
if('nextPageToken' in msg_results or nextPageToken==''):
nextPageToken = msg_results['nextPageToken']
print('nextPageToken={}'.format(nextPageToken))
else:
break
Once you've done this loop, your msg_results will contain only the messages that belong to the last page. How many messages you get will depend on how maxResults is set.
If you only want to skip a number of pages like 3 or 4 it's easy to change the above snippet to count the loops and quit when it's at the desired page.
To have a fully working code example you can try integrating the above snippet with this code on GitHub or with the nice boilerplate from GMail knowledge base which is also on GitHub.

Does urllib.request.urlopen(url) use cache?

I have this long list of URL that I need to check response code of, where the links are repeated 2-3 times. I have written this script to check the response code of each URL.
connection =urllib.request.urlopen(url)
return connection.getcode()
The URL comes in XML in this format
< entry key="something" > url</entry>
< entry key="somethingelse" > url</entry>
and I have to associate the response code with the attribute Key so I don't want to use a SET.
Now I definitely don't want to make more than 1 request for the same URL so I was searching whether urlopen uses cache or not but didn't find a conclusive answer. If not what other technique can be used for this purpose.
You can store the urls in a dictionary (urls = {}) as you make a request and check if you have already made a req to that url later:
if key not in urls:
connection = urllib.request.urlopen(url)
urls[key] = url
return connection.getcode()
BTW if you make requests to the same urls repeatedly (multiple runs of the script), and need a persistent cache, i recommend using requests with requests-cache
Why don't you create a python set() of the URLs? That way each url is included only once.
How are you associating the URL with the key? A dictionary?
You can use a dictionary to map the URL to it's response and any other information you need to keep track of. If the URL is already in the dictionary then you know the response. So you have one dictionary:
url_cache = {
"url1" : ("response", [key1,key2])
}
If you need to organize things differently it shouldn't be too hard with another dictionary.

Categories

Resources