Get request not returning expected data python - python

I'm trying to include a list of synonyms for words that a user inputs in my program. I want to send the word to the Big Huge Thesaurus API which returns the data. I'm using the requests module to send the term but the API is only returning the HTTP response code. What I am expecting is a json object that I can extract the synonyms from. Can someone help me with this please?
>>import requests
>>term = 'Big'
>>Thesaurus=requests.get("http://words.bighugelabs.com/api/2/mykey/%s/json" % term, auth=('',''))
>>print Thesaurus
<Response [200]>

Pretty sure you have to use Thesaurus.content, Thesaurus.text, or Thesaurus.json. requests.get() returns a requests.Response object, and when you print that, it's just doing an implicit string cast, which for this type of object, just returns the response code formatted in the string you are seeing printed here.

Related

How to extract only wanted property from JSON object

When I run the code:
import requests
import json
def get_fact():
catFact = requests.get("https://catfact.ninja/fact?max_length=140")
json_data = json.loads(catFact.text)
return json_data
print(get_fact())
The output is like
{'fact': "Cats are the world's most popular pets, outnumbering dogs by as many as three to one", 'length': 84}
However I just want the fact.
How do I get rid of the 'fact:' at the front and 'length:' at the back?
What you want is to access the key in the python dict you made with the json.loads call. We actually don't need the json library as requests can read and deserialize JSON itself.
This code also checks if the response was OK and fails with informative error message. It follows PEP 20 – The Zen of Python.
import requests
def get_fact():
# Get the facts dictionary in a JSON serialized form.
cat_fact_response = requests.get("https://catfact.ninja/fact?max_length=140")
# Let the response raise the exception if something bad happened to the cat facts server connection.
cat_fact_response.raise_for_status()
# Deserialize the json (make a Python dict from the text we got). requests can do that on it's own:
cat_fact_dict = cat_fact_response.json()
# Access the fact from the json from the dictionary
return cat_fact_dict['fact']
print(get_fact())
When called you get following output as wanted:
# python3 script.py
The cat's tail is used to maintain balance.
Short answer:
you need to use either get_fact()['fact'] or get_fact().get('fact'). The former will throw an exception if fact doesn't exist whereas the latter will return None.
Why:
In your code sample you fetch some json data, and then print out the entire bit of json. When you parse json, the output is a key/value map called a dictionary (or map or object in other languages). The dictionary in this case contains two keys: fact and length. If you only one want of the values, then you need to tell python that you want only a single value -- fact in this case.
Remember though: this wouldn't apply to every json object you read. Not every one is going to have a fact key.
What you are returning in get_fact is a complete JSON object which you are then printing.
To get just its property fact (without the length) use a reference to that key or property like:
return json_data["fact"]
Below is also a link to a tutorial on using JSON in Python:
w3schools: Python JSON
To extract fact field from the response, use:
import requests
import json
def get_fact():
catFact = requests.get("https://catfact.ninja/fact?max_length=140")
json_data = json.loads(catFact.text)
return json_data['fact'] # <- HERE
print(get_fact())
Output:
Cats have "nine lives" thanks to a flexible spine and powerful leg and back muscles
Note: you don't need json module here, use json() method of Response instance returned by requests:
import requests
def get_fact():
catFact = requests.get("https://catfact.ninja/fact?max_length=140").json()
return catFact['fact']
print(get_fact())

What is a good way to parse JSON response with varied data types?

I am trying to write API calls to retrieve the last package status using UPS Tracking API. However, it seems that the JSON strings returned by the API vary in the data type returned - for example, ["TrackResponse"]["Shipment"]["Package"] returns either a JSON string or a list of JSON strings.
I am currently managing these using the below try / except statements. If a list of JSONs is returned instead of a singular JSON string, I specify that I am looking for the first JSON string in the list.
response = requests.request("POST", url, data=payload, headers=headers)
response_json=response.json()
try:
status = response_json["TrackResponse"]["Shipment"]["Package"]["Activity"][0]["Status"]["Type"]
code = response_json["TrackResponse"]["Shipment"]["Package"]["Activity"][0]["Status"]["Code"]
location = response_json["TrackResponse"]["Shipment"]["Package"]["Activity"][0]["ActivityLocation"]["Address"]["City"]
except:
status = response_json["TrackResponse"]["Shipment"]["Package"][0]["Activity"][0]["Status"]["Type"]
code = response_json["TrackResponse"]["Shipment"]["Package"][0]["Activity"][0]["Status"]["Code"]
location = response_json["TrackResponse"]["Shipment"]["Package"][0]["Activity"][0]["ActivityLocation"]["Address"]["City"]
Unfortunately, this seems like it isn't going to work well as there are multiple parts of the API response where this issue is occurring. Eg."Activity" also returns a JSON if only one activity was found, or a list of JSONs if multiple activities are returned.
Is there a more elegant way of resolving these issues, besides writing multiple nested if/else or try/except statements to test the datatype returned at each point of the JSON response?
Thanks!

Python Requests - add text at the beginning of query string

When sending data through python-requests a GET request, I have a need to specifically add something at the beginning of the query string. I have tried passing the data in through dicts and json strings with no luck.
The request as it appears when produced by requests:
/apply/.../explain?%7B%22......
The request as it appears when produced by their interactive API documentation (Swagger):
/apply/.../explain?record=%7B%22....
Where the key-value pairs of my data follow the excerpt above.
Ultimately, I think the missing piece is the record= that gets produced by their documentation. It is the only piece that is different from what is produced by Requests.
At the moment I've got it set up something like this:
import requests
s = requests.Session()
s.auth = requests.auth.HTTPBasicAuth(username,password)
s.verify = certificate_path
# with data below being a dictionary of the values I need to pass.
r = s.get(url,data=data)
I am trying to include an image of the documentation below, but don't yet have enough reputation to do so:
apply/model/explain documentation
'GET' requests don't have data, that's for 'POST' and friends.
You can send the query string arguments using params kwarg instead:
>>> params = {'record': '{"'}
>>> response = requests.get('http://www.example.com/explain', params=params)
>>> response.request.url
'http://www.example.com/explain?record=%7B%22'
From the comments i felt the need to explain this.
http://example.com/sth?key=value&anotherkey=anothervalue
Let's assume you have a url like the above in order to call with python requests you only have to write
response = requests.get('http://example.com/sth', params={
'key':'value',
'anotherkey':'anothervalue'
})
Have in mind that if your value or your keys have any special character in them they will be escaped thats the reason for the %7B%2 part of url in your question.

how to pass params as json in ajax call from ruby?

I am making ajax rest call from ruby and its going to python to do rest call proccess. when i trying to call rest and passing params in json formate, i think its may not passing this as json data.
My ajax call is following:
get '/cnet' do
temp="mynet"
url = URI.parse('http://192.168.1.9:8080/v2.0/networks')
params = {'net_name'=>temp}.to_json
resp = Net::HTTP.post_form(url, params)
resp_text = resp.body
puts resp_text
erb resp_text
end
Python code is following:
#app.route('/v2.0/networks',methods=['POST'])
def net_create():
net_res=request.json
print "======================="
print net_res['net_name']
print "======================="
net_name=net_res['net_name']
when i am trying to read json data from python its giving following error:
File "/network-ui/neutron_plugin.py", line 226, in net_create
net_name=net_res['net_name']
TypeError: 'NoneType' object has no attribute '__getitem__'
I don't know what is exactly happening.
I am following there link for ajax post call:
http://rest.elkstein.org/2008/02/using-rest-in-ruby.html
http://developer.yahoo.com/ruby/ruby-rest.html
Any help much appreciated. Thanks
Don't pass JSON to Net::HTTP. The method requires a simple ruby hash.
In fact, you send POST params - POST params are sent through the HTTP request body, they are not JSON or whatever, just simple strings. This is HTTP basics, so i suggest you read a bit about how things work over this protocol, it will be a lot easier if you understand it.
Regarding the python side, I don't know much Python but if you really need JSON (which i doubt), you will have to somehow parse the params.

python json unicode - how do I eval using javascript

Really spent a lot of time searching for this. Please need some help.
I am trying to add multilingual feature to my web app framework. For this I am unable to send non ascii characters as JSON. Here is what I am doing
Here is what I get from the database
'\xe0\xa4\xa4\xe0\xa5\x87\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4'
which when I print gives me which is okay
तेस्त
I make the response object
response = {'a':'\xe0\xa4\xa4\xe0\xa5\x87\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4'}
Send the repsonse
import json
sys.stdout.write(json.dumps(response))
This is what it prints
Returns u'{"a": "\u0924\u0947\u0938\u094d\u0924"}'
Any help, pointers will be welcome
Thanks!
Rushabh
Is this your desired output (see ensure_ascii argument for json.dumps)?
sys.stdout.write(json.dumps(response, ensure_ascii=False))
{"a": "तेस्त"}

Categories