Question

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

Was it helpful?

Solution

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 = "you@gmail.com"
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. 

OTHER TIPS

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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top