Google Places Detail Not Returning Websites - google-maps

I'm trying to utilize Google's Place Detail API to return business websites. Here is the code I am running, but I've been unsuccessful across multiple tests with different Place IDs.
import requests
import json
params = {
'place_id': 'ChIJIR7nCYMvXIgRe6yefY5IfWQ',
'fields': 'website',
'key': 'API_KEY',
}
response = requests.get('https://maps.googleapis.com/maps/api/place/details/json', params=params)
data = json.loads(response.content)
print(data)
The output reads:
{'html_attributions': [], 'result': {}, 'status': 'OK'}
What am I doing wrong? Am I using the wrong API?

Related

Python Request Post Loop through set of Json

I am trying to build a script that will take each json object I have and execute a requests.post successfully until it is finished. The problem I feel I may be having is running a successful loop that handles that task for me. It has been awhile since I coded some python so any insights will be helpful. Below is my data and code sets
new_df = {
"id": 1,
"name": "memeone",
"smartphoneWidth": 0,
"isHtmlCompatible": true,
"instancesPerPage": 1,
"isArchived": false
}, {
"id": 1,
"name": "memetwo",
"smartphoneWidth": 0,
"isHtmlCompatible": true,
"instancesPerPage": 1,
"isArchived": false
}
I realize it is not in an a list or within brackets [], but this is the only I can get the data to successfully post in my experience. Do I need to put it in a dataframe?
Below is my code that I am using -
test_df = pd.read_csv('dummy_format_no_id_v4.csv').rename_axis('id')
test_two_df = test_df.reset_index().to_json(orient='records')
test_three_df = test_two_df[1:-1]
new_df = test_three_df
for item in new_df:
try:
username = 'username'
password = 'password'
headers = {"Content-Type": "application/json; charset=UTF-8"}
response = requests.post('https://api.someurl.com/1234/thispath', data=new_df, headers=headers, auth=(username, password))
print(response.text)
except:
print('ERROR')
the issue here is it will post first json object ("name": "memeone") successfully, but won't post the next one ("name":"memetwo")? How can I get it to iterate and also post the next json object? Must it be in a dataframe?
Thank you for any advice in advance. Apologies if my code is bad.
Actually, package requests itself has a json parameter that has been provided, and you can use that. instead of using data or saving it in dataframe, you can use like this :
for item in new_df:
try:
headers = {"Content-Type": "application/json; charset=UTF-8"}
response = requests.post(
f"https://httpbin.org/anything/{new_df}", json=new_df, headers=headers
)
# put break statement to terminate the loop
print(response.text)
break
except Exception as e:
raise Exception(f"Uncaught exception error {e}")

Using GraphQL machinery, but return CSV

A normal REST API might let you request the same data in different formats, with a different Accept header, e.g. application/json, or text/html, or a text/csv formatted response.
However, if you're using GraphQL, it seems that JSON is the only acceptable return content type. However, I need my API to be able to return CSV data for consumption by less sophisticated clients that won't understand JSON.
Does it make sense for a GraphQL endpoint to return CSV data if given an Accept: text/csv header? If not, is there a better practise way to do this?
This is more of a conceptual question, but I'm specifically using Graphene to implement my API. Does it provide any mechanism for handling custom content types?
Yes, you can, but it's not built in and you have to override some things. It's more like a work around.
Take these steps and you will get csv output:
Add csv = graphene.String() to your queries and resolve it to whatever you want.
Create a new class inheriting GraphQLView
Override dispatch function to look like this:
def dispatch(self, request, *args, **kwargs):
response = super(CustomGraphqlView, self).dispatch(request, *args, **kwargs)
try:
data = json.loads(response.content.decode('utf-8'))
if 'csv' in data['data']:
data['data'].pop('csv')
if len(list(data['data'].keys())) == 1:
model = list(data['data'].keys())[0]
else:
raise GraphQLError("can not export to csv")
data = pd.json_normalize(data['data'][model])
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="output.csv"'
writer = csv.writer(response)
writer.writerow(data.columns)
for value in data.values:
writer.writerow(value)
except GraphQLError as e:
raise e
except Exception:
pass
return response
Import all necessary modules
Replace the default GraphQLView in your urls.py file with your new view class.
Now if you include "csv" in your GraphQL query, it will return raw csv data and then you can save the data into a csv file in your front-end. A sample query is like:
query{
items{
id
name
price
category{
name
}
}
csv
}
Remember that it is a way to get raw data in csv format and you have to save it. You can do that in JavaScript with the following code:
req.then(data => {
let element = document.createElement('a');
element.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(data.data));
element.setAttribute('download', 'output.csv');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
})
This approach flattens the JSON data so no data is lost.
I have to implement the functionality of exporting list query into a CSV file. Here is how I implement extending #Sina method.
my graphql query for retriving list of users (with limit pagination) is
query userCsv{
userCsv{
csv
totalCount
results(limit: 50, offset: 50){
id
username
email
userType
}
}
}
Make CustomGraphQLView view by inheriting from GraphQLView and overide dispatch function to see if query has a csv also make sure you update graphql url pointing to this custom GraphQLView.
class CustomGraphQLView(GraphQLView):
def dispatch(self, request, *args, **kwargs):
try:
query_data = super().parse_body(request)
operation_name = query_data["operationName"]
except:
operation_name = None
response = super().dispatch(request, *args, **kwargs)
csv_made = False
try:
data = json.loads(response.content.decode('utf-8'))
try:
csv_query = data['data'][f"{operation_name}"]['csv']
csv_query = True
except:
csv_query = None
if csv_query:
csv_path = f"{settings.MEDIA_ROOT}/csv_{datetime.now()}.csv"
results = data['data'][f"{operation_name}"]['results']
# header = results[0].keys()
results = json_normalize(results)
results.to_csv(csv_path, index=False)
data['data'][f"{operation_name}"]['csv'] = csv_path
csv_made = True
except GraphQLError as e:
raise e
except Exception:
pass
if csv_made:
return HttpResponse(
status=200, content=json.dumps(data), content_type="application/json"
)
return response
Operation name is the query name by which you are calling. In previous example given it is userCsv and it is required because the final result as a response came with this key. Response obtained is django http response object. using above operation name we check if csv is present in the query if not present return response as it is but if csv is present then extract query results and make a csv file and store it and attach its path in response.
Here is the graphql schema for the query
class UserListCsvType(DjangoListObjectType):
csv = graphene.String()
class Meta:
model = User
pagination = LimitOffsetGraphqlPagination(default_limit=25, ordering="-id")
class DjangoListObjectFieldUserCsv(DjangoListObjectField):
#login_required
def list_resolver(self, manager, filterset_class, filtering_args, root, info, **kwargs):
return super().list_resolver(manager, filterset_class, filtering_args, root, info, **kwargs)
class Query(graphene.ObjectType):
user_csv = DjangoListObjectFieldUserCsv(UserListCsvType)
Here is the sample response
{
"data": {
"userCsv": {
"csv": "/home/shishir/Desktop/sample-project/media/csv_2021-11-22 15:01:11.197428.csv",
"totalCount": 101,
"results": [
{
"id": "51",
"username": "kathryn",
"email": "candaceallison#gmail.com",
"userType": "GUEST"
},
{
"id": "50",
"username": "bridget",
"email": "hsmith#hotmail.com",
"userType": "GUEST"
},
{
"id": "49",
"username": "april",
"email": "hoffmanzoe#yahoo.com",
"userType": "GUEST"
},
{
"id": "48",
"username": "antonio",
"email": "laurahall#hotmail.com",
"userType": "PARTNER"
}
]
}
}
}
PS: Data generated above are from faker library and I'm using graphene-django-extras and json_normalize is from pandas. CSV file can be download from the path obtained in response.
GraphQL relies on (and shines because of) responding nested data. To my understanding CSV can only display flat key value pairs. This makes CSV not really suitable for GraphQL responses.
I think the cleanest way to achieve what you want to do would be to put a GraphQL client in front of your clients:
+------+ csv +-------+ http/json +------+
|client|<----->|adapter|<----------->|server|
+------+ +-------+ +------+
The good thing here is that your adapter would only have to be able to translate the queries it specifies to CSV.
Obviously you might not always be able to do so (but how are you making them send GraphQL queries then). Alternatively you could build a middleware that translates JSON to CSV. But then you have to deal with the whole GraphQL specification. Good luck translating this response:
{
"__typename": "Query",
"someUnion": [
{ "__typename": "UnionA", "numberField": 1, "nested": [1, 2, 3, 4] },
{ "__typename": "UnionB", "stringField": "str" },
],
"otherField": 123.34
}
So if you can't get around having CSV transported over HTTP GraphQL is simply the wrong choice because it was not built for that. And if you disallow those GraphQL features that are hard to translate to CSV you don't have GraphQL anymore so there is no point in calling it GraphQL then.

Extract data from Zapier Storage

I was successful in publishing (POST) a JSON file in Zapier and creating a Storage for it. However, I´d like to access the JSON in Zapier Storage using a Python code run locally. I am able to access the storage with Python3, see that is something written there, but I cannot access the JSON contents.
import urllib
import json
import codecs
reader = codecs.getreader("utf-8")
access_token = "password"
def GetStorage(page_id, access_token):
url = 'https://hooks.zapier.com/url/'
response = urllib.request.urlopen(url)
data = json.load(reader(response))
return data
a=GetStorage(url, access_token)
print(a)
All I get is:
{'attempt': '5a539a49-65eb-44f8-a30e-e171faf7a680',
'id': '1b38d21a-0150-46df-98c1-490a0d04b565',
'request_id': '5a539a49-65eb-44f8-a30e-e171faf7a680',
'status': 'success'}
When in fact I need:
{'Name':'value',
'Address': 'value'
}
Any ideas ?
David here, from the Zapier Platform team.
You're close! hooks.zapier.com is the url we use for incoming webhooks, so we always reply with a 200 and the response body you're seeing.
Instead, use store.zapier.com. You'll also want to make sure to include your secret. A full request URL will look like:
https://store.zapier.com/api/records?secret=test
which will return arbitrary json data:
{
"name": "david",
"job": "programmer"
}
The full docs are in json here: https://store.zapier.com/

Implement request as JSON for google geolocation API

I'm trying to implement google geolocation API in order to get a location by providing the cell data. Would like to make a form where you put in the cell info and get its location.
Here's the page i'm following: https://developers.google.com/maps/documentation/geolocation/intro
I have MNC, MCC, CID, but I really can't understand how to set up a form in HTML that POST a request, with the body in JSON.
Can anyone post me an example please?
Thanks!!
i wrote a python script that return the GPS location of a cell. it uses Google Geolocation API, if there is no result, it looks up the coordinates using OpenCellID API.
#!/bin/python
"""
Written by Atissonoun - Credits to MFC & HAC
***You need to initialize the script in order to fix the import and the dependency.
This is only a Beta version of the project***
This python file works as the engine for the project.
imports, coordinates, run......
"""
#Importing modules
import requests
#defining a Api_Keys
Google_API_KEY="Your google API Key goes here"
OpenCell_Api_Key ="Your OpenCellID API Key goes here"
def Google(MMC,MNC,LAC,ID,API_KEY=Google_API_KEY):
url = "https://www.googleapis.com/geolocation/v1/geolocate?key={}".format(API_KEY)
data={
"radioType": "gsm",
"cellTowers":[
{
"cellId": ID,
"locationAreaCode": LAC,
"mobileCountryCode": MMC,
"mobileNetworkCode": MNC
}
]
}
response = requests.post(url, json=data)
if response.status_code == 200 :
lat=response.json()[u'location'][u'lat']
long = response.json()[u'location'][u'lng']
d={'LAT':lat,'LONG':long}
print('Located Cell: {}'.format(ID))
return d
else:
print('Error: {}'.format(response.status_code))
return None
def Opencell(MMC,MNC,LAC,ID,API_KEY=OpenCell_Api_Key):
url = "https://us1.unwiredlabs.com/v2/process.php"
data = {
"token": API_KEY,
"radio": "gsm",
"mcc": MMC,
"mnc": MNC,
"cells": [{
"lac": LAC,
"cid": ID
}]
}
response = requests.post(url, json=data)
if response.status_code == 200:
if response.json()[u'status']== 'error':
print('Error: {}'.format(response.json()[u'message']))
return None
else:
lat = response.json()[u'lat']
long = response.json()[u'lon']
d = {'LAT': lat, 'LONG': long}
print('Located Cell: {}'.format(ID))
return d
else:
print('Error: {}'.format(response.status_code))
return None

Pivotal Tracker API Labels

I am trying to use the Pivotal Tracker API to post a story using python. I am able to do so using the python requests module. The following is a sample code that I can use to create a new story:
payload = {"name":"Create story w/create label"}
requests.post('https://www.pivotaltracker.com/services/v5/projects/xxxxxx/stories', data=payload4, headers={'X-TrackerToken':token}).json()
for which the output is
{u'created_at': u'2015-03-04T18:47:28Z',
u'current_state': u'unscheduled',
u'id': xxxxxx,
u'kind': u'story',
u'labels': [],
u'name': u'Create story w/create label',
u'owner_ids': [],
u'project_id': xxxxxx,
u'requested_by_id': xxxxxx,
u'story_type': u'feature',
u'updated_at': u'2015-03-04T18:47:28Z',
u'url': u'https://www.pivotaltracker.com/story/show/xxxxxx'}
Great. Now, I want to create a story and add a label to it. According to the POST /projects/{project_id}/stories API on https://www.pivotaltracker.com/help/api/rest/v5, I should be able to format my json as follows and run a POST request:
payload = {"name":"Create story w/create label","labels":[{"name":"orbit"}]}
requests.post('https://www.pivotaltracker.com/services/v5/projects/xxxxxx/stories', data=payload, headers={'X-TrackerToken':token}).json()
however, I get the following 400 response:
{u'code': u'invalid_parameter',
u'error': u'One or more request parameters was missing or invalid.',
u'general_problem': u"'labels' must be an array of label values",
u'kind': u'error'}
From what I understand, the way I formatted the payload json is correct and the label resource json is formatted properly. I'm not sure if the error is on my end or if it is something else. If someone with knowledge of the API could provide some help, it would be much appreciated.
Thanks
Solved it, there' s a JSON encoding issue. We never told pivotal tracker that we were sending JSON. This code snippet works:
data = {
"labels": ["major request"],
"name": "some cool feature",
"description": "solve world hunger",
"comments": ["requested by not the 1%"]
}
headers = {'X-TrackerToken': TRACKER_TOKEN,
'Content-type': 'application/json',
'Accept': 'application/json'
}
return requests.post(url, headers=headers, data=json.dumps(data))
Need to tell the API that we are sending JSON and accepting JSON.