1

I'm trying to get a very simple Python script to talk to Freebase.

All the examples I've found use the simple / api key authorization model. So I made a Google Developer account, made a project, and tried to get a key as Google says to. It demands I provide a list of numeric IP addresses that I'll call from. Not feasible, since I don't have a fixed IP (I do have dyndns set up, but that doesn't help since Google won't take a domain name, only numerics).

So I tried OAuth2, which is overkill for what I need (I'm not accessing any non-public user data). But I couldn't find even one online example of using OAuth2 for Freebase. I tried adjusting other examples, but after bouncing around between appengine, Decorator, several obsolete Python libraries, and several other approaches, I got nowhere.

Can anyone either explain or point to a good example of how to do this (without spending 10x more time on authorization, than on the app I'm trying to authorize)? A working example with OAuth2, preferably without many layers of "simplifying" APIs; or a tip on how to get around the fixed-IP requirement for API key authorization, would be fantastic. Thanks!

Steve

2 Answers 2

1

I had to do this for Google Drive, but as far as I know this should work for any Google API.

When you create a new Client ID in the developer console, you should have the option to create a Service Account. This will create a public/private key pair, and you can use that to authenticate without any OAuth nonsense.

I stole this code out of our GDrive library, so it may be broke and it is GDrive specific, so you will need to replace anything that says "drive" with whatever Freebase wants.

But I hope it's enough to get you started.

# Sample code that connects to Google Drive from apiclient.discovery import build import httplib2 from oauth2client.client import SignedJwtAssertionCredentials, VerifyJwtTokenError SERVICE_EMAIL = "[email protected]" PRIVATE_KEY_PATH ="./private_key.p12" # Load private key key = open(PRIVATE_KEY_PATH, 'rb').read() # Build the credentials object credentials = SignedJwtAssertionCredentials(SERVICE_EMAIL, key, scope='https://www.googleapis.com/auth/drive') try: http = httplib2.Http() http = credentials.authorize(http) except VerifyJwtTokenError as e: print(u"Unable to authorize using our private key: VerifyJwtTokenError, {0}".format(e)) raise connection = build('drive', 'v2', http=http) # You can now use connection to call anything you need for freebase - see their API docs for more info. 
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! That got me much of the way there; I'll post working sample below (won't fit in comment).
0

Working from @Rachel's sample code, with a bit of fiddling I got to this, which works, and illustrates the topic, search, and query features.

Must install libraries urllib and json, plus code from https://code.google.com/p/google-api-python-client/downloads/list Must enable billing from 'settings' for the specific project The mglread() interface for Python is broken as of April 2014. The documented 'freebase.readonly' scope doesn't work.

from apiclient.discovery import build import httplib2 from oauth2client.client import SignedJwtAssertionCredentials, VerifyJwtTokenError # Set up needed constants # SERVICE_EMAIL = args.serviceEmail PRIVATE_KEY_PATH = args.privateKeyFile topicID = args.topicID query = args.query search_url = 'https://www.googleapis.com/freebase/v1/search' topic_url = 'https://www.googleapis.com/freebase/v1/topic' mql_url = "https://www.googleapis.com/freebase/v1/mqlread" key = open(PRIVATE_KEY_PATH, 'rb').read() credentials = SignedJwtAssertionCredentials(SERVICE_EMAIL, key, scope='https://www.googleapis.com/auth/freebase') try: http = httplib2.Http() http = credentials.authorize(http) except VerifyJwtTokenError as e: print(u"Unable to authorize via private key: VerifyJwtTokenError, {0}".format(e)) raise connection = build('freebase', 'v1', http=http) # Search for a topic by Freebase topic ID # https://developers.google.com/freebase/v1/topic-overview # params = { 'filter': 'suggest' } url = topic_url + topicID + '?' + urllib.urlencode(params) if (args.verbose): print("URL: " + url) resp = urllib.urlopen(url).read() if (args.verbose): print("Response: " + resp) respJ = json.loads(resp) print("Topic property(s) for '%s': " % topicID) for property in respJ['property']: print(' ' + property + ':') for value in respJ['property'][property]['values']: print(' - ' + value['text']) print("\n") # Do a regular search # https://developers.google.com/freebase/v1/search-overview # params = { 'query': query } url = search_url + '?' + urllib.urlencode(params) if (args.verbose): print("URL: " + url) resp = urllib.urlopen(url).read() if (args.verbose): print("Response: " + resp) respJ = json.loads(resp) print("Search result for '%s': " % query) theKeys = {} for res in respJ['result']: print ("%-40s %-15s %10.5f" % (res['name'], res['mid'], res['score'])) params = '{ "id": "%s", "type": []}' % (res['mid']) # Run a query on the retrieved ID, to get its types: url = mql_url + '?query=' + params resp = urllib.urlopen(url).read() respJ = json.loads(resp) print(" Type(s): " + `respJ['result']['type']`) otherKeys = [] for k in res: if (k not in ['name', 'mid', 'score']): otherKeys.append(k) if (len(otherKeys)): print(" Other keys: " + ", ".join(otherKeys)) sys.exit(0) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.