summaryrefslogtreecommitdiff
path: root/freebase-api
diff options
context:
space:
mode:
authornitromaster101 <nitromaster101@5914aa95-5b3a-0410-a3b5-7b719e7fe9b2>2009-06-17 18:49:38 +0000
committernitromaster101 <nitromaster101@5914aa95-5b3a-0410-a3b5-7b719e7fe9b2>2009-06-17 18:49:38 +0000
commitaf28a4f55a9c9d2142050c91c5ffdacd2262332b (patch)
treeb3b67af011309f1ca294840bc989f9d831b5c4f3 /freebase-api
parent02b92cfdfc2c294ad12308cef3b25dcaf477d741 (diff)
updated api, added documentation, added freebase.funcname functionality
git-svn-id: http://freebase-python.googlecode.com/svn/trunk@86 5914aa95-5b3a-0410-a3b5-7b719e7fe9b2
Diffstat (limited to 'freebase-api')
-rwxr-xr-xfreebase-api/freebase/__init__.py40
-rw-r--r--freebase-api/freebase/api/session.py141
-rwxr-xr-xfreebase-api/test/test_all.py124
3 files changed, 272 insertions, 33 deletions
diff --git a/freebase-api/freebase/__init__.py b/freebase-api/freebase/__init__.py
index e69de29..3cca4ff 100755
--- a/freebase-api/freebase/__init__.py
+++ b/freebase-api/freebase/__init__.py
@@ -0,0 +1,40 @@
+import sys
+
+from freebase.api.session import HTTPMetawebSession
+import sandbox
+
+__all__ = ["HTTPMetawebSession", "sandbox"]
+
+base = HTTPMetawebSession("freebase.com")
+
+# we want to add base's functions to __init__.py
+# so that we can say freebase.func() and really
+# just call base.func()
+
+# a little trick to refer to __init__
+# self isn't defined because __init__ is in
+# a world in and of itself
+self = sys.modules[__name__]
+
+for funcname in dir(base):
+
+ # we only want the 'real' functions
+ if not funcname.startswith("_"):
+ func = getattr(base, funcname)
+
+ # let's make sure we're getting functions
+ # instead of constants or whatever
+ if callable(func):
+
+ # we're setting these functions
+ # so that they can be called like
+ # freebase.funcname -> base.func()
+ setattr(self, funcname, func)
+
+ # make sure we import the base's
+ # functions if we import freebase
+ __all__.append(funcname)
+
+# we don't want any self-referencing
+# business going. Plus, this is cleaner.
+del self
diff --git a/freebase-api/freebase/api/session.py b/freebase-api/freebase/api/session.py
index e6b9c00..0d5159b 100644
--- a/freebase-api/freebase/api/session.py
+++ b/freebase-api/freebase/api/session.py
@@ -50,7 +50,7 @@ except ImportError:
# appengine provides simplejson at django.utils.simplejson
from django.utils import simplejson
except ImportError:
- raise Error("unable to import simplejson")
+ raise Exception("unable to import simplejson")
try:
from urllib import quote as urlquote
except ImportError:
@@ -249,11 +249,9 @@ class HTTPMetawebSession(MetawebSession):
on whether urllib2 or httplib2 is in use?
"""
- if method == 'POST':
- assert body is not None or form is not None
- elif method == 'GET':
+ if method == 'GET':
assert body is None
- else:
+ if method != "GET" and method != "POST":
assert 0, 'unknown method %s' % method
url = self.service_url + service_path
@@ -273,7 +271,7 @@ class HTTPMetawebSession(MetawebSession):
assert ct is not None
if form is not None:
- qstr = '&'.join(['%s=%s' % (urlencode_weak(k), urlencode_weak(v))
+ qstr = '&'.join(['%s=%s' % (urlencode_weak(unicode(k)), urlencode_weak(unicode(v)))
for k,v in form.items()])
if method == 'POST':
# put the args on the url if we're putting something else
@@ -377,17 +375,23 @@ class HTTPMetawebSession(MetawebSession):
- def login(self):
- """sign in to the service"""
+ def login(self, username=None, password=None):
+ """sign in to the service. For a more complete description,
+ see http://www.freebase.com/view/en/api_account_login"""
+
+ service = '/api/account/login'
+
+ username = username or self.username
+ password = password or self.password
- assert self.username is not None
- assert self.password is not None
+ assert username is not None
+ assert password is not None
- self.log.debug('LOGIN USERNAME: %s', self.username)
+ self.log.debug('LOGIN USERNAME: %s', username)
- r = self._httpreq_json('/api/account/login', 'POST',
- form=dict(username=self.username,
- password=self.password))
+ r = self._httpreq_json(service, 'POST',
+ form=dict(username=username,
+ password=password))
if r.code != '/api/status/ok':
raise MetawebError(u'%s %r' % (r.get('code',''), r.messages))
@@ -395,9 +399,45 @@ class HTTPMetawebSession(MetawebSession):
self.log.debug('LOGIN RESP: %r', r)
self.log.debug('LOGIN COOKIES: %s', self.cookiejar)
+ def logout(self):
+ """logout of the service. For a more complete description,
+ see http://www.freebase.com/view/en/api_account_logout"""
+
+ service = '/api/account/logout'
+
+ self.log.debug("LOGOUT")
+
+ r = self._httpreq_json(service, 'GET')
+
+ if r.code != '/api/status/ok':
+ raise MetawebError(u'%s %r' % (r.get('code',''), r.messages)) #this should never happen
+ def user_info(self, mql_output=None):
+ """ get user_info. For a more complete description,
+ see http://www.freebase.com/view/en/api_service_user_info"""
+
+ service = "/api/service/user_info"
+
+ qstr = simplejson.dumps(mql_output)
+
+ r = self._httpreq_json(service, 'POST', form=dict(mql_output=qstr))
+ return r
+
+ def loggedin(self):
+ """check to see whether a user is logged in or not. For a
+ more complete description, see http://www.freebase.com/view/en/api_account_loggedin"""
+
+ service = "/api/account/loggedin"
+ try:
+ r = self._httpreq_json(service, 'GET')
+ if r.code == "/api/status/ok":
+ return True
+
+ except MetawebError, me:
+ return False
+
def mqlreaditer(self, sq, asof=None):
- """read a structure query"""
+ """read a structure query."""
cursor = True
@@ -422,7 +462,8 @@ class HTTPMetawebSession(MetawebSession):
return
def mqlread(self, sq, asof=None):
- """read a structure query"""
+ """read a structure query. For a more complete description,
+ see http://www.freebase.com/view/en/api_service_mqlread"""
subq = dict(query=sq, escape=False)
if asof:
subq['as_of_time'] = asof
@@ -470,20 +511,56 @@ class HTTPMetawebSession(MetawebSession):
return [self._mqlresult(rs[key]) for key in keys]
- def trans(self, guid):
- """translate blob from guid """
- url = '/api/trans/raw' + urlquote(guid)
+ def raw(self, id):
+ """translate blob from id. For a more complete description,
+ see http://www.freebase.com/view/en/api_trans_raw"""
+ url = '/api/trans/raw' + urlquote(id)
self.log.info(url)
resp, body = self._httpreq(url)
- self.log.info('%d bytes' % len(body))
+ self.log.info('raw is %d bytes' % len(body))
return body
+
+ def blurb(self, id, break_paragraphs=False, maxlength=200):
+ """translate only the text in blob from id. For a more
+ complete description, see http://www.freebase.com/view/en/api_trans_blurb"""
+ url = '/api/trans/blurb' + urlquote(id)
+
+ self.log.info(url)
+
+ resp, body = self._httpreq(url, form=dict(break_paragraphs=break_paragraphs, maxlength=maxlength))
+
+ self.log.info('blurb is %d bytes' % len(body))
+
+ return body
+
+ def image_thumb(self, id, maxwidth=None, maxheight=None, mode="fit", onfail=None):
+ """ given the id of an image, this will return a URL of a thumbnail of the image.
+ The full details of how the image is cropped and finessed is detailed at
+ http://www.freebase.com/view/en/api_trans_image_thumb """
+
+ service = "/api/trans/image_thumb"
+ assert mode in ["fit", "fill", "fillcrop", "fillcropmid"]
+
+ form = dict(mode=mode)
+ if maxwidth is not None:
+ form["maxwidth"] = maxwidth
+ if maxheight is not None:
+ form["maxheight"] = maxheight
+ if onfail is not None:
+ form["onfail"] = onfail
+
+ resp, body = self._httpreq(service + urlquote(id), form=form)
+ self.log.info('image is %d bytes' % len(body))
+
+ return body
def mqlwrite(self, sq):
- """do a mql write"""
+ """do a mql write. For a more complete description,
+ see http://www.freebase.com/view/en/api_service_mqlwrite"""
query = dict(query=sq, escape=False)
qstr = simplejson.dumps(query)
@@ -535,10 +612,14 @@ class HTTPMetawebSession(MetawebSession):
return True
def touch(self):
+ """ make sure you are accessing the most recent data. For a more
+ complete description, see http://www.freebase.com/view/en/api_service_touch"""
return self.mqlflush()
+
def upload(self, body, content_type, document_id=False, permission_of=False):
- """upload to the metaweb"""
+ """upload to the metaweb. For a more complete description,
+ see http://www.freebase.com/view/en/api_service_upload"""
service = '/api/service/upload'
@@ -568,8 +649,21 @@ class HTTPMetawebSession(MetawebSession):
headers=headers, body=body, form=form)
return self._mqlresult(r)
+
+ def version(self):
+ """ get versions for various parts of freebase. For a more
+ complete description, see http://www.freebase.com/view/en/api_version"""
+
+ service = "/api/version"
+ r = self._httpreq_json(service)
+
+ self._check_mqlerror(r)
+ return r
+
+ ### DEPRECATED IN API
def reconcile(self, name, etype=['/common/topic']):
- """reconcile name to guid"""
+ """DEPRECATED: reconcile name to guid. For a more complete description,
+ see http://www.freebase.com/view/en/dataserver_reconciliation"""
service = '/dataserver/reconciliation'
r = self._httpreq_json(service, 'GET', form={'name':name, 'types':','.join(etype)})
@@ -578,6 +672,7 @@ class HTTPMetawebSession(MetawebSession):
# TODO non-conforming service, fix later
#self._mqlresult(r)
return r
+
if __name__ == '__main__':
console = logging.StreamHandler()
diff --git a/freebase-api/test/test_all.py b/freebase-api/test/test_all.py
index f23dc14..1a9e124 100755
--- a/freebase-api/test/test_all.py
+++ b/freebase-api/test/test_all.py
@@ -28,8 +28,11 @@
import unittest
-import sys
-from freebase.api import HTTPMetawebSession
+import sys, logging
+import freebase
+import random
+
+from freebase.api import HTTPMetawebSession, MetawebError
USERNAME = 'username'
@@ -39,28 +42,79 @@ TEST_QUERY = {'id': 'null', 'name': 'Sting'}
class TestFreebase(unittest.TestCase):
- def test_login(self):
+ def test_freebase_dot_login_logout(self):
+ freebase.login(username=USERNAME, password=PASSWORD)
+ self.assertNotEqual(freebase.user_info(), None)
+ self.assertEqual(freebase.loggedin(), True)
+ freebase.logout()
+ self.assertRaises(MetawebError, freebase.user_info)
+ self.assertEqual(freebase.loggedin(), False)
+
+ def test_login_logout(self):
mss = HTTPMetawebSession(API_HOST, username=USERNAME,
password=PASSWORD)
mss.login()
+
+ user_info = mss.user_info()
+ self.assertNotEqual(None, user_info)
+ self.assertEqual(user_info.code, "/api/status/ok")
+ self.assertEqual(mss.loggedin(), True)
+
+ mss.logout()
+ self.assertRaises(MetawebError, mss.user_info)
+ self.assertEqual(mss.loggedin(), False)
+
- # check mss._cookies?
+ def test_freebase_dot_read(self):
+ query = {'type':'/music/artist','guid':[{}],'name':'Sting', 'album':[{}]}
+
+ result = freebase.mqlread(query)
+
+ self.assertNotEqual(None, result)
+ self.assert_(result.has_key('guid'))
+ self.assert_(result.has_key('type'))
+ self.assert_(result.has_key('name'))
+ self.assert_(result.has_key('album'))
+ self.assertEqual(type([]), type(result['album']))
+ self.assert_(len(result['album']) > 0)
+ self.assertEqual( 'Sting', result['name'])
+ self.assertEqual('#9202a8c04000641f8000000000092a01', result['guid'][0]['value'])
+
+ def test_freebase_dot_write(self):
+ read_query = {'type':'/music/artist','name':'Yanni\'s Cousin Tom', 'id':{}}
+
+ freebase.sandbox.login(username=USERNAME, password=PASSWORD)
+ result = freebase.sandbox.mqlread(read_query)
+ self.assertEqual(None, result)
+
+ write_query = {'create':'unless_exists', 'type':'/music/artist','name':'Yanni'}
+
+ write_result = freebase.sandbox.mqlwrite(write_query)
+ self.assertNotEqual(None, write_result)
+ self.assert_(write_result.has_key('create'))
+ self.assert_(write_result.has_key('type'))
+ self.assert_(write_result.has_key('name'))
+ self.assertEqual('existed', write_result['create'])
+ self.assertEqual('Yanni', write_result['name'])
+ self.assertEqual('/music/artist', write_result['type'])
def test_read(self):
- query = {'type':'/music/artist','id':[{}],'name':'Sting', 'album':[{}]}
+ query = {'type':'/music/artist','guid':[{}],'name':'Sting', 'album':[{}]}
mss = HTTPMetawebSession(API_HOST)
result = mss.mqlread(query)
+
self.assertNotEqual(None, result)
- self.assert_(result.has_key('id'))
+ self.assert_(result.has_key('guid'))
self.assert_(result.has_key('type'))
self.assert_(result.has_key('name'))
self.assert_(result.has_key('album'))
- self.assertEqual([].__class__, result['album'].__class__)
- self.assert_( result['album'].__len__() > 0)
+ self.assertEqual(type([]), type(result['album']))
+ self.assert_(len(result['album']) > 0)
self.assertEqual( 'Sting', result['name'])
- self.assertEqual( '/guid/9202a8c04000641f8000000000092a01', result['id'][0]['value'], str(result['id']))
+ self.assertEqual('#9202a8c04000641f8000000000092a01', result['guid'][0]['value'])
+
def test_write(self):
read_query = {'type':'/music/artist','name':'Yanni\'s Cousin Tom', 'id':{}}
@@ -81,6 +135,56 @@ class TestFreebase(unittest.TestCase):
self.assertEqual('Yanni', write_result['name'])
self.assertEqual('/music/artist', write_result['type'])
+ def test_trans_blurb(self):
+ kurt = "/en/kurt_vonnegut"
+
+ blurb = freebase.blurb(kurt)
+ self.assert_(blurb.startswith("Kurt Vonnegut"))
+ self.assertNotEqual(len(blurb), 0)
+
+ blurb14 = freebase.blurb(kurt, maxlength=14)
+ blurb57 = freebase.blurb(kurt, maxlength=57)
+ self.assertNotEqual(len(blurb14), len(blurb57))
+
+ blurbpar = freebase.blurb(kurt, break_paragraphs=True, maxlength=20000)
+ blurbnopar = freebase.blurb(kurt, break_paragraphs=False, maxlength=20000)
+ # self.assertNotEqual(blurbpar, blurbnopar) this doesn't work unless I get a good example
+ # of an article with paragraphs.
+
+ def test_trans_raw(self):
+ kurt = "/en/kurt_vonnegut"
+
+ self.assertRaises(MetawebError, lambda: freebase.raw(kurt))
+
+ r = freebase.mqlread({"id":kurt, "/common/topic/article":[{"id":None, "optional":True, "limit":1}]})
+ raw = freebase.raw(r["/common/topic/article"][0].id)
+ self.assertNotEqual(len(raw), 0)
+
+ def test_trans_image_thumb(self):
+ kurt = "/en/kurt_vonnegut"
+
+ r = freebase.mqlread({"id":kurt, "/common/topic/image":[{"id":None, "optional":True, "limit":1}]})
+ imageid = r["/common/topic/image"][0].id
+ rawimage = freebase.raw(imageid)
+
+ thumbedimage = freebase.image_thumb(imageid, maxheight=99)
+ self.assertNotEqual(rawimage, thumbedimage)
+
+ def test_upload(self):
+ my_text = "Kurt Vonnegut was an author! " + str(random.random())
+
+ freebase.sandbox.login(USERNAME, PASSWORD)
+ response = freebase.sandbox.upload(my_text, "text/plain")
+
+ self.assertEqual(freebase.sandbox.raw(response.id), my_text)
+ # since it's text/plain, blurb should also be equal
+ self.assertEqual(freebase.sandbox.blurb(response.id), my_text)
+
+
if __name__ == '__main__':
- unittest.main()
+ if USERNAME == "username" and PASSWORD == "password":
+ print "In order to run the tests, we need to use a valid freebase username and password"
+ USERNAME = raw_input("Please enter your username: ")
+ PASSWORD = raw_input("Please enter your password (it'll appear in cleartext): ")
+ unittest.main()