I am using Google Ads API SDK for Python. I want to get some Ads data and put them into a Dataframe to transform a bit. I made a call with the code below:
client = GoogleAdsClient.load_from_storage("config.yaml")
customer_id = '<customer_id>'
ga_service = client.get_service("GoogleAdsService")
query = """
SELECT
campaign.id,
campaign.name,
customer.id
FROM campaign
"""
response = ga_service.search_stream(customer_id=customer_id, query=query)
for batch in response:
for row in batch.results:
print(row)
df = pd.DataFrame(row)
print(df)
Here is the response I receive:
customer {
resource_name: "customers/<customer-id>"
id: <customer-id>
}
campaign {
resource_name: "customers/<customer-id>/campaigns/<campaign-id>"
name: "Test_campaign_1"
id: <campaign-id>
}
Traceback (most recent call last):
File "c:\Users\User\main.py", line 36, in <module>
print(dict(row))
TypeError: 'GoogleAdsRow' object is not iterable
I tried using google.protobuf.json_format to convert the result into json/dict format with the below code
from google.protobuf.json_format import MessageToJson
response = ga_service.search_stream(customer_id=customer_id, query=query)
for batch in response:
for row in batch.results:
print(row)
jsonobj = MessageToJson(row)
But I got the below error message:
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\proto\message.py", line 605, in __getattr__
raise AttributeError(str(ex))
AttributeError: 'DESCRIPTOR'
Could you please help me with this? Thank you.
Sorry for bothering, but I found this question and got the answer for my question.
I changed my code to below (add ._pb to the response):
response = ga_service.search(customer_id=customer_id, query=query)
dictobj = MessageToDict(response._pb)
df = pd.json_normalize(dictobj,record_path=['results'])
print(df)
and it works!
Related
I made a little script to get the UUID's of people who joined my minecraft server, then run them through the PlayerDB API through a post request to: https://playerdb.co/api/player/minecraft/* where the * is a player UUID, however it returns random 404 errors.
Error runs on the player_name_history line and highlights KeyError at 'player':
def getPlayerData(UUID_list):
baseurl = "https://playerdb.co/api/player/minecraft/"
player_names=[]
icon_list = []
for UUID in UUID_list:
response = requests.post(baseurl+UUID)
print("url posted:",baseurl+UUID)
print(response.status_code)
responseObject = response.json()
with open('responseObject.json','w') as f:
json.dump(responseObject, f)
player_name_history = responseObject['data']['player']['meta']['name_history']
for x in player_name_history:
player_name = x['name'] #iterates through all names, last name will not be overrwritten
player_names.append(player_name)
icon_link = responseObject['data']['player']['avatar']
icon_list.append(icon_link)
return player_names, icon_list
for x in player_name_history:
player_name = x['name'] #iterates through all names, last name will not be overrwritten
player_names.append(player_name)
icon_link = responseObject['data']['player']['avatar']
icon_list.append(icon_link)
return player_names, icon_list
You can pass my UUID into the function as a list to test:
['bf22088f-3d5b-45ef-b7dd-8d5bd3cdc310']
Example of it working:
url posted: https://playerdb.co/api/player/minecraft/bf22088f-3d5b-45ef-b7dd-8d5bd3cdc310
200
(['zonkedzolt'], ['https://crafthead.net/avatar/bf22088f-3d5b-45ef-b7dd-8d5bd3cdc310'])
Example of it not working:
url posted: https://playerdb.co/api/player/minecraft/bf22088f-3d5b-45ef-b7dd-8d5bd3cdc310
404
Traceback (most recent call last):
File "g:\*\getPlayerData.py", line 74, in <module>
print(getPlayerData(UUID_list))
File "g:\*\getPlayerData.py", line 58, in getPlayerData
player_name_history = responseObject['data']['player']['meta']['name_history']
KeyError: 'player'
json Dump: {"message": "", "code": "api.404", "data": {}, "success": false, "error": false}
The reason why i suspect it might be my code is because when i get the error, if i ctrl+left click the link on the "url posted:" line it brings up the correct result.
If you are getting error messages from the API like this:
{"message": "", "code": "api.404", "data": {}, "success": false, "error": false}
try requesting each UUID seperately and once you have gotten a good response, try running it with your program. It seems that the API caches UUIDs that have been asked for the first time, but if you ask again too quickly it will return the error above.
Occasionally I still run into the error above, but a re-request sorts it out. You can make a while loop to keep requesting until you recieve a good response. Here is the while loop I made:
goodResponse = False
while goodResponse == False:
response = requests.post(baseurl+UUID)
print("url posted:",baseurl+UUID)
print(response.status_code)
responseObject = response.json()
if "player" in responseObject['data']: #checks if UUID has recieved a good response, otherwise loops until it does.
goodResponse = True #continue code here
import json
from botocore.vendored import requests
#import requests
def weatherfunc(city_name):
api_key = 'e914e5e16947fe541140de82a88e5888'
base_url = 'http://api.openweathermap.org/data/2.5/weather?'
finalurl = base_url + 'appid=' + api_key + '&q=' + city_name
response = requests.get(finalurl)
x = response.json()
y = x['main']
current_temperature = y['temp']
current_pressure = y['pressure']
current_humidiy = y['humidity']
z = x['weather']
weather_description = z[0]['description']
return {
'current temp': current_temperature,
'humidity': current_humidiy,
'pressure': current_pressure,
'description': weather_description,
}
def lambda_handler(event, context):
city = event['City']
a = weatherfunc(city)
return (a)
I want to return weather information to my lex bot, I am coming across error:
Response:
{
"errorMessage": "'City'",
"errorType": "KeyError",
"stackTrace": [
" File "/var/task/lambda_function.py", line 28, in lambda_handler\n city = event['City']\n"
]
}
Plase help me troubleshoot error.
According to the error message:
You call lambda_handler (in lambda_handler)
... that function encountered a KeyError ("errorType": "KeyError")
... at line 28, which is: city = event['City'] (line 28, city = event['City'])
With a 30 second google search on KeyError python doc you will come accross this website documenting KeyError.
The first relevant line in this website reads: Raised when a mapping (dictionary) key is not found in the set of existing keys.
Please check the event content passed in request, to fetch city name properly. If u r fetching City from event content of lex... It could be like this - city = event['currentIntent']['slot']['city']. Please refer event content.
First off I am total noob when it comes to writing python so a lot of what I've done thus far has been all learn as I go so with that said:
I have this bit of code here
if buycott_token != '':
print("Looking up in Buycott")
url = "https://www.buycott.com/api/v4/products/lookup"
headers = {
'Content-Type': 'application/json'
}
data={'barcode':upc,
'access_token':buycott_token
}
try:
r = requests.get(url=url, json=data, headers=headers)
j = r.json()
if r.status_code == 200:
print("Buycott found it so now we're going to gather some info here and then add it to the system")
name = j['products'][0]['product_name']
description = j['products'][0]['product_description']
#We now have what we need to add it to grocy so lets do that
#Sometimes buycott returns a success but it never actually does anything so lets just make sure that we have something
if name != '':
add_to_system(upc, name, description)
except requests.exceptions.Timeout:
print("The connection timed out")
except requests.exceptions.TooManyRedirects:
print ("Too many redirects")
except requests.exceptions.RequestException as e:
print e
98% of the time this works just fine with no issues. Then I'll scan something with my barcode scanner and I'll get
Traceback (most recent call last):
File "./barcode_reader.py", line 231, in <module>
increase_inventory(upc)
File "./barcode_reader.py", line 34, in increase_inventory
product_id_lookup(upc)
File "./barcode_reader.py", line 79, in product_id_lookup
upc_lookup(upc)
File "./barcode_reader.py", line 128, in upc_lookup
name = aj['products'][0]['product_name']
KeyError: 'products'
I am certain that it has something to do with how the json is being returned. Problem is when this is thrown it kills the script and that is that. Thank you for your assistance.
The problem is that there is no 'products' key in your response JSON. The workaround could be providing a default value if a 'products' key is not present:
default_value = [{'product_name': '', 'product_description': ''}]
j.get('products', default_value)[0]['product_name']
or you could simply check whether your response has the products key:
if 'products' not in j:
return 'Product not found'
I think this error is because of API doesn't give you proper json in response. So I think you can check from your side if key is in API response or not.
if 'products' in j:
name = j['products'][0]['product_name']
description = j['products'][0]['product_description']
else:
#Whatever you want when 'product' is not in API response
I would think there is not problem with that, but I am really having troubles with this piece of code and cannot seem to come up with a solution.
I have a dictionary whose keys are proper name, e.g. John Green, and I am using the API of the Sunlight Foundation to retrieve information about congress members (check here). Now I need to request using name and lastname so my code looks something like this:
for key in my_dict:
query_params2 = { 'apikey': 'xxxxxxxxxxx',
'firstname' : key.split()[0],
'lastname' : key.split()[-1]
}
endpoint2 = "http://services.sunlightlabs.com/api/legislators.get.json"
resp2 = requests.get(endpoint2, params = query_params2)
data2 = resp2.json().decode('utf-8')
print data2['response']['legislator']['bioguide_id']
Which gives some error I can not really interpret:
Traceback (most recent call last):
File "my_program.py", line 102, in <module>
data = resp.json()
File "//anaconda/lib/python2.7/site-packages/requests/models.py", line 741, in json
return json.loads(self.text, **kwargs)
File "//anaconda/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "//anaconda/lib/python2.7/json/decoder.py", line 365, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "//anaconda/lib/python2.7/json/decoder.py", line 383, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
I would guess it has something to do with the encoding, but I am not sure what and how to solve it.
Needless to say, if I put by hand a name and lastname, the request works perfectly.
Anybody can help with this? Thanks a lot!
This has nothing to do with the encoding. The answer simply isn't JSON. When I try your code with 'John' and 'Green' I get a 400 Bad Request and the content of the response is 'No Such Object Exists'.
Trying John Green in the web interface also comes up with an empty answer. Also the URL in the API documentation differs from the URL in your example.
The following works for me (again no John Green):
import requests
LEGISLATORS_URL = 'https://congress.api.sunlightfoundation.com/legislators'
API_KEY = 'xxxx'
def main():
names = [('John', 'Green'), ('John', 'Kerry')]
for first_name, last_name in names:
print 'Checking', first_name, last_name
response = requests.get(
LEGISLATORS_URL,
params={
'apikey': API_KEY,
'first_name': first_name,
'last_name': last_name,
'all_legislators': 'true'
}
).json()
print response['count']
if response['count'] > 0:
print response['results'][0]['bioguide_id']
if __name__ == '__main__':
main()
Output:
Checking John Green
0
Checking John Kerry
1
K000148
I'm trying to post a JSON object through a POST. I'm trying to do it as follows:
import json, urllib, urllib2
filename = 'test.json'
race_id = 2530
f = open(filename, 'r')
fdata = json.loads(f.read())
f.close()
prefix = 'localhost:8000'
count = 0
for points in fdata['positions'].iteritems():
print '--' + str(count) + '--------'
url = 'http://'+prefix+'/api/points'
parameters = {'point_data': json.dumps(points), 'race_id': race_id}
data = urllib.urlencode(parameters)
print data
request = urllib2.Request(url, data)
response = urllib2.urlopen(request)
count += 1
break;
print 'Finished adding points'
The data is then received on the other end (I'm using Google App Engine) with:
point_data = json.load(self.request.get('point_data'))
But I get the following error:
ERROR 2010-06-30 15:08:05,367
__init__.py:391] 'unicode' object has no attribute 'read' Traceback (most
recent call last): File
"/home/ian/workspace/google_appengine/google/appengine/ext/webapp/__init__.py",
line 513, in __call__
handler.post(*groups) File "/home/ian/workspace/codebase/track_builder/geo-api.py",
line 276, in post
point_data = json.load(self.request.get('point_data'))
File
"/home/ian/workspace/google_appengine/lib/django/django/utils/simplejson/__init__.py",
line 208, in load
return cls(encoding=encoding, **kw).decode(fp.read()) AttributeError: 'unicode' object has
no attribute 'read' INFO
2010-06-30 15:08:05,376
dev_appserver.py:3266] "POST
/api/points HTTP/1.1" 500 -
Any ideas on how to fix this?
EDIT: As requested here is an example of the points:
(u'1276859700',
{
u'24': {
u'tempc': u'-22.7',
u'gpsq': u'1',
u'altm': u'65527',
u'hd': u'112',
u'hdop': u'0.93',
u'bton': u'0',
u'maxv': u'20.15',
u'idit': u'1',
u'satc': u'10',
u'minv': u'20.15',
u'lat': u'35.271993',
u'btusr': u'0',
u'lng': u'-121.845353',
u'knots': u'7'
},
u'11': {
u'tempc': u'13.0',
u'gpsq': u'1',
u'altm': u'65535',
u'hd': u'130',
u'hdop': u'0.84',
u'bton': u'0',
u'maxv': u'15.96',
u'idit': u'1',
u'satc': u'12',
u'minv': u'15.88',
u'lat': u'34.877815',
u'btusr': u'0',
u'lng': u'-121.386116',
u'knots': u'8'
}
}
EDIT 2:
Thanks to Daniel Roseman and Nick Johnson who both caught my error. I've changed
point_data = json.loads(self.request.get('point_data'))
This has solved the error but, now I'm getting:
ERROR 2010-06-30 16:07:29,807 __init__.py:391] 'list' object has no attribute 'iteritems'
Traceback (most recent call last):
File "/home/ian/workspace/google_appengine/google/appengine/ext/webapp/__init__.py", line 513, in __call__
handler.post(*groups)
File "/home/ian/workspace/codebase/track_builder/geo-api.py", line 255, in post
for time, units in point_data.iteritems():
AttributeError: 'list' object has no attribute 'iteritems'
INFO 2010-06-30 16:07:29,816 dev_appserver.py:3266] "POST /api/points HTTP/1.1" 500 -
which relates to the following code:
class TrackPoint(webapp.RequestHandler):
def post(self):
point_data = json.loads(self.request.get('point_data'))
race_id = self.request.get('race_id')
added = []
failed = []
for time, units in point_data.iteritems():
for unit, data in units.iteritems():
...
Any ideas on this one?
It looks like self.request.get() is returning a unicode object rather than a file-like object. You could try using json.loads() instead of json.load().
json.load() expects a file object, but self.request.get returns the value of the parameter as a string.
The solution is easy: use json.loads.
Also, free tip: I presume from the name that you're bundling your own copy of the json library. App Engine actually includes a copy of simplejson that you can use - just do:
from django.utils import simplejson
first in js I recognize that json object must in STRING format (javascript file)
// using jquery, json2
var js = {"name":"nguyen","age":"1"};
$.post("/", {'data': JSON.stringify(js)}, function(ret){
alert(ret);
});
then in gae
from django.utils import simplejson as json
class PesonReq(webapp.RequestHandler):
def post(self):
t = json.loads(self.request.POST['data'])
self.response.out.write(t['name'])