I'm just beginning to learn python/django. I've been teaching myself PHP and now I would like to learn python. I'm having issues integrating yelp's API. I'm getting errors:
Values instance has no attribute 'q'
I have this code:
def search(request):
parser = optparse.OptionParser()
parser.add_option('-c', '--consumer_key', dest='my_consumer_key_goes_here', help='OAuth consumer key (REQUIRED)')
parser.add_option('-s', '--consumer_secret', dest='my_consumer_secret_goes_here', help='OAuth consumer secret (REQUIRED)')
parser.add_option('-t', '--token', dest='my_token_goes_here', help='OAuth token (REQUIRED)')
parser.add_option('-e', '--token_secret', dest='my_token_secret_goes_here', help='OAuth token secret (REQUIRED)')
parser.add_option('-a', '--host', dest='host', help='Host', default='api.yelp.com')
options, args = parser.parse_args()
# search stuff?
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
parser.add_option('-q', '--term', dest=q, help='Search term')
url_params = {}
if options.q:
url_params['term'] = options.q
# Sign the URL
consumer = oauth2.Consumer(consumer_key, consumer_secret)
oauth_request = oauth2.Request('GET', url, {})
oauth_request.update({'oauth_nonce': oauth2.generate_nonce(),
'oauth_timestamp': oauth2.generate_timestamp(),
'oauth_token': token,
'oauth_consumer_key': consumer_key})
token = oauth2.Token(token, token_secret)
oauth_request.sign_request(oauth2.SignatureMethod_HMAC_SHA1(), consumer, token)
signed_url = oauth_request.to_url()
else:
message = 'You submitted an empty form.'
#return HttpResponse(message)
print 'Signed URL: %s\n' % (signed_url,)
# Connect
try:
conn = urllib2.urlopen(signed_url, None)
try:
response = json.loads(conn.read())
finally:
conn.close()
except urllib2.HTTPError, error:
response = json.loads(error.read())
return response
response = request(options.host, '/v2/search', url_params, options.consumer_key, options.consumer_secret, options.token, options.token_secret)
print json.dumps(response, sort_keys=True, indent=2)
Now as I'm still new to this whole python language, I wonder if I'm also adding the API consumer_key, secret, etc... in the right places? Do I even have this code set correctly? Most of it was from the original yelp api script. I guess the issue lies in the if options.q: area... not sure if I'm doing this correctly?
Thanks
I would say that calling parser.parse_args() before you declared your q option is probably your immediate problem.
But unless I am missing something about what you are trying to do, Django settings [1] are what you need to use for those first 5 options (don't use optparse at all). And then I don't know what you are trying to do with the rest of the function.
[1] https://docs.djangoproject.com/en/1.4/topics/settings/
Related
So a follow up on this question, where I still have the same code: to start working with some live data, I switched from sandbox to individual key, and started getting this error with code that did work in sandbox mode:
HTTPError: 401 Client Error: Unauthorized for url: https://apisb.etrade.com/v1/market/optionexpiredate?symbol=NFLX&expiryType=ALL
Here's the authentication code, in case I messed up here:
consumer_key = "[key, double checked]"
consumer_secret = "[secret, double checked]"
def authenticate():
#get the auth UIL
oauth = pyetrade.ETradeOAuth(consumer_key, consumer_secret)
oauth.setToken(consumer_key)
oauth.setTokenSecret(consumer_secret)
print(oauth.get_request_token())
#ask the user to put the verification code in to get tokens
verifier_code = input("Enter verification code: ")
global tokens
tokens = oauth.get_access_token(verifier_code)
print(tokens)
#Setting up the object used for Access Management
global authManager
authManager = pyetrade.authorization.ETradeAccessManager(
consumer_key,
consumer_secret,
tokens['oauth_token'],
tokens['oauth_token_secret']
)
And this is the code that returns the error:
try:
q = market.get_option_expire_date(thisSymbol,resp_format='xml')
expiration_dates = option_expire_dates_from_xml(q)
except:
raise Exception("Rip, get date not working")
I'm not sure why this is happening :( any help would be super appreciated!
I saw some code look like this:
graph = facebook.GraphAPI(User_Access_Token)
graph.request("search", {'q' : 'social web', 'type' : 'page'})
This seems fetch all the data containing the key word 'social web'. But I don't understand why we can do such request.
I read the document of help(graph.request), which says
request(self, path, args=None, post_args=None, files=None, method=None) method of facebook.GraphAPI instance
Fetches the given path in the Graph API.
It doesn't mention "search" at all.
I have the same question and I assume you installed pip install facebook-sdk as well and I assume again that your source is Mining the Social Web: Analyzing Data from Facebook, Twitter, LinkedIn, and Other Social Media Sites - Feb 11, 2011 by Matthew A. Russell. The facebook-sdk version is facebook_sdk-2.0.0 . I am not sure the versioning system is the same with Facebook's GraphAPI, but if it is, the API documentation for that is not supported anymore. I downloaded the library from here and in /facebook-sdk-2.0.0/facebook/__init__.py you will be able to see this block of code.
def request(
self, path, args=None, post_args=None, files=None, method=None):
"""Fetches the given path in the Graph API.
We translate args to a valid query string. If post_args is
given, we send a POST request to the given path with the given
arguments.
"""
args = args or {}
if post_args is not None:
method = "POST"
# Add `access_token` to post_args or args if it has not already been
# included.
if self.access_token:
# If post_args exists, we assume that args either does not exists
# or it does not need `access_token`.
if post_args and "access_token" not in post_args:
post_args["access_token"] = self.access_token
elif "access_token" not in args:
args["access_token"] = self.access_token
try:
response = requests.request(method or "GET",
FACEBOOK_GRAPH_URL + path,
timeout=self.timeout,
params=args,
data=post_args,
proxies=self.proxies,
files=files)
except requests.HTTPError as e:
response = json.loads(e.read())
raise GraphAPIError(response)
headers = response.headers
if 'json' in headers['content-type']:
result = response.json()
elif 'image/' in headers['content-type']:
mimetype = headers['content-type']
result = {"data": response.content,
"mime-type": mimetype,
"url": response.url}
elif "access_token" in parse_qs(response.text):
query_str = parse_qs(response.text)
if "access_token" in query_str:
result = {"access_token": query_str["access_token"][0]}
if "expires" in query_str:
result["expires"] = query_str["expires"][0]
else:
raise GraphAPIError(response.json())
else:
raise GraphAPIError('Maintype was not text, image, or querystring')
if result and isinstance(result, dict) and result.get("error"):
raise GraphAPIError(result)
return result
I hope it helps.
This code is supposed to use the Yelp API to retrieve information about restaurants. Every time I run it, I get a HTTP 400 Error, which I think should mean a syntax error. In reviewing it by myself I cannot find my error. I've searched Stack Overflow for a question related to mine and haven't found one.
The return Error message is: Encountered HTTP error 400. Abort program.
# -*- coding: utf-8 -*-
"""
Yelp API v2.0 code sample.
This program demonstrates the capability of the Yelp API version 2.0
by using the Search API to query for businesses by a search term and location,
and the Business API to query additional information about the top result
from the search query.
Please refer to http://www.yelp.com/developers/documentation for the API documentation.
This program requires the Python oauth2 library, which you can install via:
`pip install -r requirements.txt`.
Sample usage of the program:
`python sample.py --term="bars" --location="San Francisco, CA"`
"""
import argparse
import json
import pprint
import sys
import urllib
import urllib2
import oauth2
API_HOST = 'api.yelp.com'
DEFAULT_TERM = 'restaurants'
DEFAULT_LOCATION = 'Ottawa'
SEARCH_LIMIT = '75'
SEARCH_PATH = '/v2/search/'
BUSINESS_PATH = '/v2/business/'
# OAuth credential placeholders that must be filled in by users.
CONSUMER_KEY =########
CONSUMER_SECRET =######
TOKEN =#######
TOKEN_SECRET =#######
def request(host, path, url_params=None):
"""Prepares OAuth authentication and sends the request to the API.
Args:
host (str): The domain host of the API.
path (str): The path of the API after the domain.
url_params (dict): An optional set of query parameters in the request.
Returns:
dict: The JSON response from the request.
Raises:
urllib2.HTTPError: An error occurs from the HTTP request.
"""
url_params = url_params or {}
encoded_params = urllib.urlencode(url_params)
url = 'http://{0}{1}?{2}'.format(host, path, encoded_params)
consumer = oauth2.Consumer(CONSUMER_KEY, CONSUMER_SECRET)
oauth_request = oauth2.Request('GET', url, {})
oauth_request.update(
{
'oauth_nonce': oauth2.generate_nonce(),
'oauth_timestamp': oauth2.generate_timestamp(),
'oauth_token': TOKEN,
'oauth_consumer_key': CONSUMER_KEY
}
)
token = oauth2.Token(TOKEN, TOKEN_SECRET)
oauth_request.sign_request(oauth2.SignatureMethod_HMAC_SHA1(), consumer, token)
signed_url = oauth_request.to_url()
print 'Querying {0} ...'.format(url)
conn = urllib2.urlopen(signed_url, None)
try:
response = json.loads(conn.read())
finally:
conn.close()
return response
def search(term, location):
"""Query the Search API by a search term and location.
Args:
term (str): The search term passed to the API.
location (str): The search location passed to the API.
Returns:
dict: The JSON response from the request.
"""
url_params = {
'term': term,
'location': location,
'limit': SEARCH_LIMIT
}
return request(API_HOST, SEARCH_PATH, url_params=url_params)
def get_business(business_id):
"""Query the Business API by a business ID.
Args:
business_id (str): The ID of the business to query.
Returns:
dict: The JSON response from the request.
"""
business_path = BUSINESS_PATH + business_id
return request(API_HOST, business_path)
def query_api(term, location):
"""Queries the API by the input values from the user.
Args:
term (str): The search term to query.
location (str): The location of the business to query.
"""
response = search(term, location)
businesses = response.get('businesses')
if not businesses:
print 'No businesses for {0} in {1} found.'.format(term, location)
return
business_id = businesses[0]['id']
print '{0} businesses found, querying business info for the top result "{1}" ...'.format(
len(businesses),
business_id
)
response = get_business(business_id)
print 'Result for business "{0}" found:'.format(business_id)
pprint.pprint(response, indent=2)
def main():
parser = argparse.ArgumentParser()
parser.add_argument('-q', '--term', dest='term', default=DEFAULT_TERM, type=str, help='Search term (default: %(default)s)')
parser.add_argument('-l', '--location', dest='location', default=DEFAULT_LOCATION, type=str, help='Search location (default: %(default)s)')
input_values = parser.parse_args()
try:
query_api(input_values.term, input_values.location)
except urllib2.HTTPError as error:
sys.exit('Encountered HTTP error {0}. Abort program.'.format(error.code))
if __name__ == '__main__':
main()
In yelp api v2 they use oauth 1.oa,but you use oauth2.
You limit parameter is set to a very high value. try something like 10 to begin with.
This code is available online to run a map of your connections in linkedin
This uses linkedin api.
I'm able to connect fine and everything runs okay till the last script of actually writing the data to a csv.
Whenever I run the code
import oauth2 as oauth
import urlparse
import simplejson
import codecs
CONSUMER_KEY = "xxx"
CONSUMER_SECRET = "xxx"
OAUTH_TOKEN = "xxx"
OAUTH_TOKEN_SECRET = "xxx"
OUTPUT = "linked.csv"
def linkedin_connections():
# Use your credentials to build the oauth client
consumer = oauth.Consumer(key=CONSUMER_KEY, secret=CONSUMER_SECRET)
token = oauth.Token(key=OAUTH_TOKEN, secret=OAUTH_TOKEN_SECRET)
client = oauth.Client(consumer, token)
# Fetch first degree connections
resp, content = client.request('http://api.linkedin.com/v1/people/~/connections?format=json')
results = simplejson.loads(content)
# File that will store the results
output = codecs.open(OUTPUT, 'w', 'utf-8')
# Loop thru the 1st degree connection and see how they connect to each other
for result in results["values"]:
con = "%s %s" % (result["firstName"].replace(",", " "), result["lastName"].replace(",", " "))
print >>output, "%s,%s" % ("John Henry", con)
# This is the trick, use the search API to get related connections
u = "https://api.linkedin.com/v1/people/%s:(relation-to-viewer:(related-connections))?format=json" % result["id"]
resp, content = client.request(u)
rels = simplejson.loads(content)
try:
for rel in rels['relationToViewer']['relatedConnections']['values']:
sec = "%s %s" % (rel["firstName"].replace(",", " "), rel["lastName"].replace(",", " "))
print >>output, "%s,%s" % (con, sec)
except:
pass
if __name__ == '__main__':
linkedin_connections()
for result in results["values"]:
KeyError: 'values'
When I run this I get an error message:
Traceback (most recent call last):
File "linkedin-2-query.py", line 51, in <module>
linkedin_connections()
File "linkedin-2-query.py", line 35, in linkedin_connections
for result in results["values"]:
KeyError: 'values'
Any suggestions or help would be greatly appreciated!
I encountered the same issue working through the post Visualizing your LinkedIn graph using Gephi – Part 1.
Python raises a KeyError whenever a dict() object is requested (using the format a = adict[key]) and the key is not in the dictionary. KeyError - Python Wiki
After searching a bit and adding some print statements, I realize that my OAuth session has expired, so the OAuth token in my linkedin-2-query.py script was is longer valid.
Since the OAuth token is invalid, the LinkedIn API does not return a dictionary with the key "values" like the script expects. Instead, the API returns the string 'N'. Python tries to find the dict key "values"in the string 'N', fails, and generates the KeyError: 'values'.
So a new, valid OAuth token & secret should get the API to return a dict containing connection data.
I run the linkedin-1-oauth.py script again, and then visit the LinkedIn Application details page to find my new OAuth token. (The screenshot omits the values for my app. You should see alphanumeric values for each Key, Token, & Secret.)
...
I then update my linkedin-2-query.py script with the new OAuth User Token and OAuth User Secret
OAUTH_TOKEN = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # your updated OAuth User Token
OAUTH_TOKEN_SECRET = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # your updated OAuth User Secret
After updating the OAuth token & secret, I immediately run my linkedin-2-query.py script. Hooray, it runs without errors and retrieves my connection data from the API.
The last days I've been banging my head against the wall trying to upload a movie to YouTube using its official Python Wrapper lib.
What I've succeeded till now:
Building an Request Access URL
Saving the returned OAuth Secret for a later use (getting the actual Access Token)
Getting an Access Token and its coupled Secret. Stored them in a DB.
What I'm trying without success:
Preparing and uploading a video - this always get me a:
{'status': 401, 'body': 'Token invalid - Invalid AuthSub token.', 'reason': 'Unauthorized'}
Below is a compilation of the relevant code blocks for the above:
Getting the Access Request URL
def GetOAuthToken():
callback_url = 'http://www.mysite.com/media_sites/oauth_access_token_callback/youtube'
scope = 'http://gdata.youtube.com'
secure = False
session = True
yt_service.developer_key = YOUTUBE_DEVELOPER_KEY
yt_service.client_id = YOUTUBE_KEY
yt_service.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.HMAC_SHA1, YOUTUBE_KEY, consumer_secret=YOUTUBE_SECRET)
req_token = yt_service.FetchOAuthRequestToken(scopes=scope)
print 'secret: %s' % req_token.secret
yt_service.SetOAuthToken(req_token)
yt_service.SetOAuthToken(req_token)
return yt_service.GenerateOAuthAuthorizationURL(callback_url=callback_url, )
Getting the Access Token
def handle_token():
scope = 'http://gdata.youtube.com'
yt_service = gdata.youtube.service.YouTubeService()
yt_service.developer_key = YOUTUBE_DEVELOPER_KEY
yt_service.client_id = YOUTUBE_KEY
yt_service.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.HMAC_SHA1, YOUTUBE_KEY, consumer_secret=YOUTUBE_SECRET)
oauth_token = gdata.auth.OAuthTokenFromUrl('http://www.mysite.com/media_sites/oauth_access_token_callback/youtube?oauth_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
oauth_token.secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
if oauth_token:
oauth_token.oauth_input_params = gdata.auth.OAuthInputParams(gdata.auth.OAuthSignatureMethod.HMAC_SHA1, YOUTUBE_KEY, consumer_secret=YOUTUBE_SECRET)
yt_service.SetOAuthToken(oauth_token)
access_token = yt_service.UpgradeToOAuthAccessToken()
Uploading The Video
def upload_vid(access_token, access_token_secret):
my_media_group = gdata.media.Group(
title=gdata.media.Title(text='My Test Movie'),
description=gdata.media.Description(description_type='plain',
text='My description'),
keywords=gdata.media.Keywords(text='cars, funny'),
category=[gdata.media.Category(
text='Autos',
scheme='http://gdata.youtube.com/schemas/2007/categories.cat',
label='Autos')],
player=None
)
yt_service = gdata.youtube.service.YouTubeService()
yt_service.developer_key = YOUTUBE_DEVELOPER_KEY
yt_service.client_id = YOUTUBE_KEY
yt_service.SetOAuthInputParameters(gdata.auth.OAuthSignatureMethod.HMAC_SHA1, YOUTUBE_KEY, consumer_secret=YOUTUBE_SECRET)
oauth_token = gdata.auth.OAuthToken(key=access_token, secret=access_token_secret, scopes='http://gdata.youtube.com')
oauth_token.oauth_input_params = gdata.auth.OAuthInputParams(gdata.auth.OAuthSignatureMethod.HMAC_SHA1, YOUTUBE_KEY, consumer_secret=YOUTUBE_SECRET)
yt_service.SetOAuthToken(oauth_token)
where = gdata.geo.Where()
where.set_location((37.0,-122.0))
video_entry = gdata.youtube.YouTubeVideoEntry(media=my_media_group, geo=where)
video_file_location = '/home/path/of/myfile.flv'
new_entry = yt_service.InsertVideoEntry(video_entry, video_file_location)
So basically this gives me a 401 every time I try to upload a movie.
Any help will be great!
I solved it at the end.
On my case it was sending an escaped token to a method which expect a raw string.
Just make sure you have your token "not escaped" prior to sending them as parameters.
googles OAuth tokens may include a slash which escapes as %2F
sending such a token will bring you to a 401