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)
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 run my csv data thru "https://rxnav.nlm.nih.gov/REST/interaction" to identify any drug interactions using python. What else do I need in order to have the program be ready?
I got 200 when print status_code is that mean my code is up and ready?
import requests
response = requests.get("https://rxnav.nlm.nih.gov/REST/interaction")
print(response.status_code)
Here's how you'd hit this API, using requests and the details in their example:
import requests
uri = "https://rxnav.nlm.nih.gov/REST/interaction/interaction.json"
params = {'rxcui': 341248}
r = requests.get(uri, params)
Now you can check that r.status_code is 200, and get at the result of the request. For example:
r.json()
As you may realize, this returns a Python dictionary.
The general idea is that requsts.get() takes the base URL, followed by the query parameters, given as a dictionary. What you get back depends on the API endpoint you're querying, and/or on the parameters. In this, it's giving you JSON. Others might give you text (see r.text for this representation), or bytes (r.content).
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.
I Need to create cronjob to test the website whether the data is retrieved for every one hour.
Initially have tried by pasted the json data into text file and validated the data by encoding and decoding it. Now i need the real time data(json data) to get loaded on every time running the cron job. used urllib2 but it is not getting the request response from the url.
Url -> on loading -> through firebug gives url to execute and to json data from that. how can i import or parse such url into python. Please get me with an example.
my steps:
create shedule
1.45 08 * * 1-5 /home/user/myfile/daily_verifydata.sh >> /home/user/cronlog.log
daily_verifydata.sh
#!/bin/sh
python /home/user/path/Dashboard_test.py
Dashboard_test.py
import json
import urllib2
f = open('test.txt','r') # open in read mode
data = f.read()
print data
# How to Parse the json from the URL to python
data_string = json.dumps(data)
print '\n''ENCODED:', data_string
decoded = json.loads(data_string)
print '\n''DECODED:', decoded
# Validating data through decoded output.
If possible parsing through curl, need to know the syntax
Thanks, vijay
For retrieveing your JSON in bash script — you can use nice tool httpie
If you'd like to pull JSON from python script — best option is requests lib
And for validation, it it's complex — JSONSchema
i recommend using requests
import requests
import simplejson
session = requests.session()
# I presume your site has authentication
response = session.post(URL_TO_LOGIN, {
'username': username,
'password': password
})
response = session.get(URL_TO_JSON)
if response.ok:
simplejson.loads(response.text)