Using a variable URL value for Python HTTPConnection.request failing

720 views Asked by At

I am trying to make an API call to Yelp's Fusion API. My calls work when hard coded. I am trying to get a list of businesses and then get a list of reviews for those businesses which requires two GETs. I'd like to step through the list of businesses and get their associated reviews. The following code results in a Send a complete request to the server message when using the variable form. Hard coding a business ID value works fine. Not sure what the challenge is. (Newbie question so my code is probably not the best either)

import http.client
import json

conn = http.client.HTTPSConnection("api.yelp.com")

headers = {
'authorization': "Bearer <access token value>",
'cache-control': "no-cache",
'postman-token': "<token value>"
}
#This request works fine
conn.request("GET", "/v3/businesses/search?latitude=40.8059518&longitude=-73.9657435&limit=10&radius=200&term=restaurant", headers=headers)

res = conn.getresponse()
data = res.read()

yelp_result = json.loads(data.decode("utf-8"))

all_businesses = []
for business in yelp_result['businesses']:
    b_name = business['name']
    b_id = business['id']
    rurl = "/v3/businesses/" + b_id + "/reviews"
    #This is the request resulting in error given earlier
    conn.request("GET",rurl,headers=headers)
    all_businesses.append((b_id, b_name))
1

There are 1 answers

0
lmckeogh On

Challenge with the conn.request call seems to be that it also needs corresponding conn.getresponse() and res.read() calls. Doesn't like to open a connection if nothing is going to be done with it. (Would love it if someone had more insightful reason for this). Here's how to make a call to get limited number of businesses within a radius of a location (lat/long) and then also incorporate review snippets as part of that businesses info (not returned in the new Fusion API)

#My version of pulling a Yelp review around a particular business
#3 step proceedure
#   1. find all businesses around a location
#   2. convert to a dictionary with the key = business ID in Yelp
#   3a. request the reviews for the business ID, iteratively if necessary
#   3b. add reviews to the appropriate business as a list[0:2] of dict

import http.client
import json
# Step 1. Yelp API call to return list of businesses around a location
# for example, hard coded lat/long values used in conn.request call below. 
# Future functions: 
#    - dynamically create desired location. 
#    - number of businesses to return, current limit is 5 for testing
headers = {
    'authorization': "Bearer <access token value>",
    'cache-control': "no-cache",
    'postman-token': "<token value>"
}
conn = http.client.HTTPSConnection("api.yelp.com")
conn.request("GET", "/v3/businesses/search?latitude=40.8059518&longitude=-73.9657435&limit=5&radius=200&term=restaurant", headers=headers)
res = conn.getresponse()
data = res.read()
yelp_result = json.loads(data.decode("utf-8")) #converts byte data to just text

# Step 2. convert to a dictionary with keys = business ID values
# Think the for loop below can be simplified. (Future effort)
biz2 = {}
for business in yelp_result['businesses']:
    b_id = business['id']
    biz2[b_id] = business

# Step 3. Request and adding reviews to appropriate business
for business in yelp_result['businesses']:
    b_id = business['id']
    r_url = "/v3/businesses/" + b_id + "/reviews"    #review request URL creation based on business ID
    #Step 3a. request the reviews for the business ID
    conn.request("GET",r_url,headers=headers)
    rev_res = conn.getresponse()     #response and read functions needed else error(?)
    rev_data = rev_res.read()
    yelp_reviews = json.loads(rev_data.decode("utf-8"))
    #Step 3b. add reviews to the appropriate business
    biz2[b_id]['reviews'] = yelp_reviews['reviews']

print(json.dumps(biz2, indent=3, separators=(',', ': ')))