I'm trying to make an API call to Google CSE from python and then manipulate the resulting object into a dictionary object that I can manipulate. I think this question is not duplicated because the issue here I believe is that there are non ASC-II characters which leads to the resulting object being of type 'NoneType' and the resulting json object 'null'. I've played with the options documented for json including "ensure_ascii=False", but haven't been successful. Any help will be greatly appreciated!
Code:
import pprint, os, json
from googleapisclient.discovery import build
def search(searchkey,datekey,developkey,enginekey):
service = build("customsearch", "v1",
developerKey=developkey).cse().list(
q=searchkey,dateRestrict=datekey,
cx=enginekey,
).execute()
pprint.pprint(service)
mykey = 'My_Private_Key'
myengine = '009333857041890623793:z_drq9obxp0'
object2write = search('narco','20170101-20170201',mykey,myengine)
type(object2write)
jsonAbder = json.dumps(object2write, ensure_ascii=False, allow_nan=False)
print(jsonAbder)
The proximal cause of your error is that your search function doesn't have an explicit return statement. Thus, it implicitely returns None, which gets encoded into JSON null. Your issue has nothing to do with character encodings.
Just add:
return service
at the end of your function.
Related
Im trying to retrieve data from a database named RethinkDB, they output JSON when called with r.db("Databasename").table("tablename").insert([{ "id or primary key": line}]).run(), when doing so it outputs [{'id': 'ValueInRowOfid\n'}] and I want to parse that to just the value eg. "ValueInRowOfid". Ive tried with JSON in Python, but I always end up with the typeerror: list indices must be integers or slices, not str, and Ive been told that it is because the Database outputs invalid JSON format. My question is how can a JSON format be invalid (I cant see what is invalid with the output) and also what would be the best way to parse it so that the value "ValueInRowOfid" is left in a Operator eg. Value = ("ValueInRowOfid").
This part imports the modules used and connects to RethinkDB:
import json
from rethinkdb import RethinkDB
r = RethinkDB()
r.connect( "localhost", 28015).repl()
This part is getting the output/value and my trial at parsing it:
getvalue = r.db("Databasename").table("tablename").sample(1).run() # gets a single row/value from the table
print(getvalue) # If I print that, it will show as [{'id': 'ValueInRowOfid\n'}]
dumper = json.dumps(getvalue) # I cant use `json.loads(dumper)` as JSON object must be str. Which the output of the database isnt (The output is a list)
parsevalue = json.loads(dumper) # After `json.dumps(getvalue)` I can now load it, but I cant use the loaded JSON.
print(parsevalue["id"]) # When doing this it now says that the list is a str and it needs to be an integers or slices. Quite frustrating for me as it is opposing it self eg. It first wants str and now it cant use str
print(parsevalue{'id'}) # I also tried to shuffle it around as seen here, but still the same result
I know this is janky and is very hard to comprehend this level of stupidity that I might be on. As I dont know if it is the most simple problem or something that just isnt possible (Which it should or else I cant use my data in the database.)
Thank you for reading this through and not jumping straight into the comments and say that I have to read the JSON documentation, because I have and I havent found a single piece that could help me.
I tried reading the documentation and watching tutorials about JSON and JSON parsing. I also looked for others whom have had the same problems as me and couldnt find.
It looks like it's returning a dictionary ({}) inside a list ([]) of one element.
Try:
getvalue = r.db("Databasename").table("tablename").sample(1).run()
print(getvalue[0]['id'])
I am trying to pull some data from EIA API, below is what I tried but I'm getting the error on the first line of code:
AttributeError: 'str' object has no attribute 'text'
Any help would be much appreciated!
call_eia = requests.get = 'https://api.eia.gov/v2/nuclear-outages/facility-nuclear-outages/data?api_key=XXXXXXXX'
data_eia=pd.read_csv(StringIO(call_eia.text))
You haven't requested anything from the API. Look carefully at your first line:
call_eia = requests.get = 'https://api.eia.gov/v2/nuclear-outages/facility-nuclear-outages/data?api_key=XXXXXXXX'
# ^ ^
There are 2 = signs, so what you're really doing is assigning the URL string to both your call_eia variable and the get attribute of the requests module, overwriting the function that was there originally. Then, when you try to pass call_eia to pd.read_csv(), instead of passing a requests object, you're just passing a string, the URL.
Try
call_eia = requests.get('https://api.eia.gov/v2/nuclear-outages/facility-nuclear-outages/data?api_key=XXXXXXXX')
instead and your code should work.
I'm trying to interpret data from the Twitch API with Python. This is my code:
from twitch.api import v3
import json
streams = v3.streams.all(limit=1)
list = json.loads(streams)
print(list)
Then, when running, I get:
TypeError, "the JSON object must be str, not 'dict'"
Any ideas? Also, is this a method in which I would actually want to use data from an API?
Per the documentation json.loads() will parse a string into a json hierarchy (which is often a dict). Therefore, if you don't pass a string to it, it will fail.
json.loads(s, encoding=None, cls=None, object_hook=None,
parse_float=None, parse_int=None, parse_constant=None,
object_pairs_hook=None, **kw) Deserialize s (a str instance containing
a JSON document) to a Python object using this conversion table.
The other arguments have the same meaning as in load(), except
encoding which is ignored and deprecated.
If the data being deserialized is not a valid JSON document, a
JSONDecodeError will be raised.
From the Twitch API we see that the object being returned by all() is a V3Query. Looking at the source and documentation for that, we see it is meant to return a list. Thus, you should treat that as a list rather than a string that needs to be decoded.
Specifically, the V3Query is a subclass of ApiQuery, in turn a subclass of JsonQuery. That class explicitly runs the query and passes a function over the results, get_json. That source explicitly calls json.loads()... so you don't need to! Remember: never be afraid to dig through the source.
after streams = v3.streams.all(limit=1)
try using
streams = json.dumps(streams)
As the streams should be a JSON string and be in the form:
'{"key":value}'
instead of just dict form:
{"key":value}
I've written some code that converts a JSON object to an iCalendar (.ics) object and now I am trying to test it. The problem is that I can't figure out how to create a generic JSON object to use as the parameter. Some of my attempts are as follows:
# 1
obj_json = u'sample json data in string form'
obj = json.loads(obj_json)
# 2
# I'm not sure about this very first line. My supervisor told me to put it in but he
# has a very heavy accent so I definitely could have heard him incorrectly.
input.json
with open('input.json') as f:
obj = json.loads(f.read())
Try,
import json
some_dict = {'id': 0123, 'text': 'A dummy text'}
dummy_json = json.dumps(some_dict)
Now, feed your dummy json to your function. i.e.
'{"text": "A dummy text", "id": 83}'
You can do dumps with a string object too.
See pnv's answer, but you probably don't need to dump it. Just use a dictionary, as pnv did, and pass that into whatever you need to. Unless you are about to pass your json object over the wire to something, I don't know why you'd want to dump it.
I would've added this as a comment, but no rep, yet. :)
I am trying to use the requests library in Python to push data (a raw value) to a firebase location.
Say, I have urladd (the url of the location with authentication token). At the location, I want to push a string, say International. Based on the answer here, I tried
data = {'.value': 'International'}
p = requests.post(urladd, data = sjson.dumps(data))
I get <Response [400]>. p.text gives me:
u'{\n "error" : "Invalid data; couldn\'t parse JSON object, array, or value. Perhaps you\'re using invalid characters in your key names."\n}\n'
It appears that they key .value is invalid. But that is what the answer linked above suggests. Any idea why this may not be working, or how I can do this through Python? There are no problems with connection or authentication because the following works. However, that pushes an object instead of a raw value.
data = {'name': 'International'}
p = requests.post(urladd, data = sjson.dumps(data))
Thanks for your help.
The answer you've linked is a special case for when you want to assign a priority to a value. In general, '.value' is an invalid name and will throw an error.
If you want to write just "International", you should write the stringified-JSON version of that data. I don't have a python example in front of me, but the curl command would be:
curl -X POST -d "\"International\"" https://...
Andrew's answer above works. In case someone else wants to know how to do this using the requests library in Python, I thought this would be helpful.
import simplejson as sjson
data = sjson.dumps("International")
p = requests.post(urladd, data = data)
For some reason I had thought that the data had to be in a dictionary format before it is converted to stringified JSON version. That is not the case, and a simple string can be used as an input to sjson.dumps().