I am sending a json post request in Python and I am getting two return dictionary values but they are stored in one object.
This is what I have:
import json
import requests
def call():
pay = {'token' : "4593543"}
r = requests.post('https://www.hackerrank.com/challenges', params=pay)
I am getting two values store in the r object.
'{"needle":"qvsmbjkc", "haystack": ["pgunkqay","qvsmbjkc","qgswmzin","arwokfjm","taskzcup","yjvcabgr","xcrsldof","tecipvzf","cjtahlqb","pqgykrcz","ufyjrpad","hqezmcwl","fsyimbxr","tosqznha","lzujpvob","mbfsikde","nqvpjbhi","uwsqybai","ozetipqw","imancdqr"]}'
A needle and haystack value but they are both in the r object. How can I separate them into different variables?
requests as a json-Method to read json responses directly into python structures:
r = requests.post('https://www.hackerrank.com/challenges', params=pay)
response = r.json()
print(response['needle'])
Related
I am making my first API; any advice to improve my process is much appreciated.
I plan on passing JSON-like strings into the HTML request to this FastAPI microservice down there
#app.get("/create/{value}")
def createJSON(value:str):
person_json = value.strip()
fileName = person_json['Value']['0'] + person_json['Value']['1']
with open('%s.JSON','w') as writeFile:
writeFile.write(string)
return "Person has been created"
My HTTP request would look like this:
http://127.0.0.1:8000/create/{"Key":{"0":"name","1":"grad_year","2":"major","3":"quarter","4":"pronoun","5":"hobbies","6":"fun_fact","7":"food","8":"clubs","9":"res"},"Value":{"0":"adfasdfa","1":"adf'asd","2":"asd","3":"fads","4":"fa","5":"sdfa","6":"df","7":"asd","8":"fa","9":"df"}}
However, when doing this. The values passed are strings. Thus rendering the fileName portion of the code useless. How can I convert it to a Python dict? I have tried to use .strip(), but it did not help.
You're on the wrong track, Such a request should be essentially modeled as POST or a PUT request. That would allow you to send JSON in the body of the request and obtain it as a dict in python. You can see here
And even if you want to pass data in a GET request, there are query params
Coming back to the original doubt, you would have to use json.loads() to parse the json data and load it in a python dict then you can dump whatever file you like after that.
I'd recommend using the requests library
import requests
url = 'http://127.0.0.1:8000/create/'
params = dict(
name = 'Josh',
grad_year = '1987',
major = 'computer science',
quarter = '3'
)
resp = requests.get(url=url, params=params)
data = resp.json()
Then see here how to handle the JSON Response Content:
https://requests.readthedocs.io/en/master/user/quickstart/#json-response-content
The dict in the code I posted is different than the JSON you're trying to send through though. I assume you have a specific reason for having a "Key" array with the names than a "Value" array for the values of those specific names. But if not I'd recommend using a dictionary instead that way you can do things like:
fileName = person_json['name'] + person_json['grad-year']
This may be a silly question but I am really confused(I am a newbie). I am trying to make an API that accepts JSON as input and I am using Flask. The API takes POST method, so when a request comes along, it gets the JSON data from the body using
data = requests.get_json()
I expect data to be a string because, if I am not mistaken, JSON is nothing but a formatted string.
So, I do data = json.loads(data) But, my flask app crashes because it says data is a dictionary not a string. Of course, I can fix it by not using json.loads But it just bothers me and I wonder why I get a dictionary not a string.
Here is how I send test-requests, which seriously confuse me
1)
import requests
import pandas as pd
data = pd.read_csv('some.csv')
data = data.iloc[[0]].to_json(orient='records') // get the first row into json
res = requests.post(url, json=data) // I get a string in my Flask app.
import requests
data = {'name':'foo','age':99}
res = requests.post(url, json=data) // I get a dictionary in my Flask app.
const xhr = new XMLHttpRequest();
const json = {'name':'foo','age':99};
xhr.open("POST",url);
xhr.setRequestHeader("Content-Type","application/json");
xhr.send(JSON.stringify(json)); // Though stringified, I get a dictionary in my Flask app. Why?
I am not sure if you can see my confusion. In some cases, I get a dictionary, and in some other cases I get a string. So, I am confused and don't know how to design my API and handle the requests.
Thank you in advance for your attention!
Pandas' DataFrame.to_json returns a string (str). Hence, in this code
data = df.to_json(orient='records')
res = requests.post(url, json=data)
data is actually a str object, and passing it to the json parameter of requests.post will encode that string as JSON again. See
response = requests.post(url, json={"foo": 1})
print(response.request.body)
response = requests.post(url, json='{"foo": 1}')
print(response.request.body)
Will print
b'{"foo": 1}'
b'"{\\"foo\\": 1}"'
What you must do, to send that JSON data correctly, is
data = df.to_json(orient='records')
response = requests.post(url, data=data.encode())
or actually convert the DataFrame to a dict
data = df.to_dict(orient='records')
response = requests.post(url, json=data)
JSON object is nothing but a dictionary in python and flask is framework written python
Accordingly, the json library exposes the dump() method for writing data to files. There is also a dumps() method (pronounced as “dump-s”) for writing to a Python string.
Simple Python objects are translated to JSON according to a fairly intuitive conversion.
Python JSON
dict object
list,tuple array
str string
int,long,float number
True true
False false
None null
so depending upon what is extracted from json python variable behaves accordingly,
like in first case
data = data.iloc[[0]].to_json(orient='records') data variable is nothing but a string,
so this is why res = requests.post(url, json=data) shows such behaviour here
In second Case
data = {'name':'foo','age':99} it's dictionary
so this why
res = requests.post(url, json=data) shows such behaviour
I am trying to access a dictionary that has been returned after making a post to an API, but I am having difficulty formatting the data with JSON.
It seems to be returning the data as a dictionary but I receive the error 'list indices must be integers or slices, not str' which makes me believe that it is just returning a list that looks like a dictionary. I have tried using json.loads() and trying to access the data through lists but I can't seem to get it. The data I am trying to has multiple sub dictionaries/lists.
resp = post(url = endpoint_url, data = data, headers = headers)
data_for_process = resp.json()
print(data_for_process['pages']['keyValuePairs']['key'])
I expected the print statement to return the value for that specific key but I get the error instead.
Any help much appreciated.
you can use the json library of python
import json
import pprint
resp = post(url = endpoint_url, data = data, headers = headers)
resp_json = json.loads(resp.content)
pprint.pprint(resp_json) # to display the dict prettier
I am needing to automate a daily pull of app Annie data reviews and land them in S3. With the below I am trying to see if I can just pull one days worth of data but am getting an error 'TypeError: expected string or buffer'. I am new to python, can someone explain what I am doing wrong or another way to accomplish what I am trying to do?
import json
import requests
url = 'https://api.appannie.com/v1.2/apps/ios/app/331177714/reviews?
start_date=2016-1-01&end_date=2016-6-26&countries=US'
key = 'Authorization: bearer 585e46.....'
response = requests.get(url,
headers = {'Authorization':'bearer 585e46.....'})
data = json.loads(response.json())
.json method you're using comes from requests object and it already converts string to proper json. So you can do two things
Convert to json with requests object method:
data = response.json()
Get text from your response and turn into json with Python json lib:
data = json.loads(response.text)
I'm hitting the Hacker news API here and want to get the details of each posts that I get through the JSON. I want to send this JSON to my React front-end.
This request is taking a long time. What do I need to do to send the response?
#app.route('/api/posts')
def get_posts():
r = requests.get('https://hacker-news.firebaseio.com/v0/askstories.json?print=pretty')
data = r.text
jsonData = []
for post in data:
r = requests.get('https://hacker-news.firebaseio.com/v0/item/'+post+'.json?print=pretty')
r.text
jsonData.append(r.text)
jsonData = jsonify(jsonData)
print jsonData
return jsonData
You're querying a json API and treating the response as text:
r = requests.get('https://hacker-news.firebaseio.com/v0/askstories.json?print=pretty')
data = r.text
So, r.text would be a string "[1234,1235,1236]" and not a list of integers.
So when you iterate over that in your for post in data what you're doing is getting each character:
for post in data:
print(post)
Would give you:
[
1
2
3
4
,
...etc
So your essentially querying the hacker news API for hundreds of invalid posts, instead of tens of actual ones. You should be treating the json as json— by using the json features built into requests: data = r.json()
That will give you a list of numbers to iterate over— you'd also need to change the bad way you're concatenating your data to make your url string (use .format).
requests has a .json() method that you should use to convert your JSON array string into a python list.
In [1]: import requests
In [2]: r = requests.get('https://hacker-news.firebaseio.com/v0/askstories.json?print=pretty')
In [3]: jsonData = r.json()
In [4]: for data in jsonData[:5]:
... print data
...:
12102489
12100796
12101060
12097110
12094366
As stated in the other answer, for post in data: is going to give you individual characters from the HTTP response. In other words, think about what would for post in "abc": give you.
The page is taking a very long time to load
That's because you are running a new query against all those individual characters.