<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>Niall O'Higgins</title>
    <link>http://niallohiggins.com/</link>
    <description></description>
    <pubDate>Tue, 03 Apr 2012 18:02:46 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>MongoDB with Python, Pyramid and Akhet</title>
      <link>http://niallohiggins.com/2011/05/18/mongodb-python-pyramid-akhet</link>
      <pubDate>Wed, 18 May 2011 12:24:00 PDT</pubDate>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[MongoDB]]></category>
      <category><![CDATA[Pylons]]></category>
      <category><![CDATA[Database]]></category>
      <guid>http://niallohiggins.com/2011/05/18/mongodb-python-pyramid-akhet</guid>
      <description>MongoDB with Python, Pyramid and Akhet</description>
      <content:encoded><![CDATA[

<img src="/images/pyramid-small.png"/>
&nbsp;
<img src="/images/pylonsfw-small.png"/>
<br/>
<h2>Pylons vs Pyramid</h2>
<p>
If you weren't already aware of it, the <a
  href="http://pylonsproject.org">Pylons project</a> has recently sprouted an
all-new Python Web framework called Pyramid. Pyramid is kinda like Pylons 2.0 -
it is a completely new codebase with no code-level backwards compatibility. It
is actually based on <a href="http://bfg.repoze.org/">repoz.bfg</a>.  However, many of the concepts are very similar
to the older Pylons 1.x.
Pyramid is where all the new development is happening, and it has fantastic
code test coverage and documentation. 
</p>

<p>
You can learn more about Pyramid in the <a href="http://docs.pylonsproject.org/faq/pyramid.html">Pyramid FAQ</a>.</p>

<h2>What Is Akhet</h2>

<p> On its own, Pyramid is just a framework - a set of libraries you can use.
Projects are most easily started from a <a
href="http://docs.pylonsproject.org/projects/pyramid/1.0/narr/project.html#paster-templates-included-with-pyramid">template</a>.
A number of different templates are included, offering different persistence
options, URL mappers and session implementations.  </p>

<p>

<b>Akhet</b> is a Pyramid project template (AKA scaffold) which tries to
give you a more Pylons 1.x-like environment. Personally, I'm much more familiar
with Pylons than Pyramid and so Akhet is a great place to start.
</p>

<p>It is well worth your while <a
  href="http://docs.pylonsproject.org/projects/akhet/dev/index.html">reading
  the Akhet documentation</a>. However, the subject of this post, working with
MongoDB, takes advantage of a few changes I have made myself to <a
  href="https://bitbucket.org/niallohiggins/akhet">my Akhet fork on
  BitBucket</a>. I am hoping Mike Orr will accept my changes upstream, but for
now you will need to build the egg from my sources. I will explain how in the next section. </p>

<h2>Starting A Pyramid Project With MongoDB</h2>
<p>
First you need to create a virtual env for your project. Depending on your
platform, you should be able to install the virtualenv tool through a package
manager (sudo port install virtualenv-2.7 in Mac Ports, for example).
</p>

<h3>Install Pyramid</h3>
<p>
Once you have the virtual env tool installed, create the virtualenv, install
Pyramid and its dependencies into it:
</p>

<div class="pygments_murphy"><pre><span class="gp">$</span> mkdir ~/projects/ahket-example
<span class="gp">$</span> virtualenv --no-site-packages myenv
<span class="gp">$</span> <span class="nb">cd </span>myenv
<span class="gp">$</span> <span class="nb">source </span>bin/activate
<span class="gp">$</span> easy_install pyramid
</pre></div>




<h3>Install Akhet</h3>
<p>
Now you have Pyramid and all its dependencies installed. However, you still
need Akhet and its dependencies like PyMongo etc. We are going to use my fork
of Akhet, because it has MongoDB support at the moment.
</p>
<p>
In a new terminal, type the following (you will need Mercurial installed to
fetch the sources from BitBucket):
</p>

<div class="pygments_murphy"><pre><span class="gp">$</span> <span class="nb">cd</span> ~/projects/akhet-example
<span class="gp">$</span> hg clone https://bitbucket.org/niallohiggins/akhet
<span class="gp">$</span> <span class="nb">cd </span>akhet
<span class="gp">$</span> python setup.py sdist
</pre></div>




<p>
Now you have the Akhet with MongoDB support module available. Install it in
your virtual env (go back to original terminal, or re-source
~/projects/akhet-example/myenv/bin/activate):
</p>


<div class="pygments_murphy"><pre><span class="gp">$</span> pip install ~/projects/akhet-example/akhet/dist/Akhet-1.0.1.tar.gz
</pre></div>




<h3>Create Pyramid Project with Akhet and MongoDB Support</h3>
<p>
Okay, great - you can create your Pyramid project now! We shall call it "mongofu".
<br/>

<div class="pygments_murphy"><pre><span class="gp">$</span> <span class="nb">cd</span> ~/projects/akhet-example
<span class="gp">$</span> paster create -t akhet mongofu
<span class="go">Selected and implied templates:</span>
<span class="go">  Akhet#akhet  A Pylons-like Pyramid project</span>

<span class="go">Enter project name: mongofu</span>
<span class="go">Variables:</span>
<span class="go">  egg:      mongofu</span>
<span class="go">  package:  mongofu</span>
<span class="go">  project:  mongofu</span>
<span class="go">Enter sqlalchemy (Include SQLAlchemy configuration? (y/n)) [True]: n</span>
<span class="go">Enter mongodb (Include MongoDB configuration? (y/n)) [False]: y</span>
</pre></div>



</p>

<h3>Install Akhet Dependencies</h3>
<p>
You are just about ready to go. You need to make sure your virtual environment has all the dependencies needed by your mongofu project (e.g. the PyMongo driver). To do so run the following:

<div class="pygments_murphy"><pre><span class="gp">$</span> <span class="nb">cd </span>mongofu ; python setup.py develop
</pre></div>



</p>
<p>
Assuming all went well, you should now have a directory called "mongofu" with a
whole bunch of stuff in it. The default configuration files tell Pyramid to
connect to a MongoDB server on <b>localhost</b>, and a database called
<b>mydb</b>. If you need to change that, simply edit the <b>mongodb.url</b> and
<b>mongodb.db_name</b> settings in the INI-files.
</p>

<h3>Start The Development Server</h3>
<p>
Now try starting up a development server:


<div class="pygments_murphy"><pre><span class="gp">$</span> paster serve development.ini
</pre></div>




If things are working correctly, you should see a message like this on your terminal:

<div class="pygments_murphy"><pre><span class="go">Starting server in PID 6020.</span>
<span class="go">serving on http://127.0.0.1:5000</span>
</pre></div>



</p>

<h2>Talking to MongoDB with Pyramid/Akhet</h2>
<p>

Now you are ready to write some MongoDB queries! Edit the file <b>mongofu/handlers/main.py</b>.

<br/>

In the Main class, we can add a simple query to the "index" action method, referencing the <b>request.db</b> property - which is a handle to our MongoDB database:


<div class="pygments_murphy"><pre><span class="k">class</span> <span class="nc">Main</span><span class="p">(</span><span class="n">base</span><span class="o">.</span><span class="n">Handler</span><span class="p">):</span>
    <span class="nd">@action</span><span class="p">(</span><span class="n">renderer</span><span class="o">=</span><span class="s">&quot;index.html&quot;</span><span class="p">)</span>
    <span class="k">def</span> <span class="nf">index</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="c"># Do some logging.</span>
        <span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s">&quot;testing logging; entered Main.index()&quot;</span><span class="p">)</span>
        <span class="c"># MongoDB Query</span>
        <span class="c"># can just as easily write request.db.mycollection.find()</span>
        <span class="n">records</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">db</span><span class="p">[</span><span class="s">&#39;mycollection&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">find</span><span class="p">()</span>
        <span class="c"># Push a flash message if query param &#39;flash&#39; is non-empty.</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">params</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">&quot;flash&quot;</span><span class="p">):</span>
            <span class="kn">import</span> <span class="nn">random</span>
            <span class="n">num</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">999999</span><span class="p">)</span>
            <span class="n">message</span> <span class="o">=</span> <span class="s">&quot;Random number of the day is:  </span><span class="si">%s</span><span class="s">.&quot;</span> <span class="o">%</span> <span class="n">num</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">session</span><span class="o">.</span><span class="n">flash</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
            <span class="c"># Normally you&#39;d redirect at this point but we have nothing to</span>
            <span class="c"># redirect to.</span>
        <span class="c"># Return a dict of template variables for the renderer.</span>
        <span class="k">return</span> <span class="p">{</span><span class="s">&quot;project&quot;</span><span class="p">:</span><span class="s">&quot;mongofu&quot;</span><span class="p">}</span>
</pre></div>



</p>

<p>
As you can see, we specify a collection in that database to query against. We're not doing anything with the results, but that is enough to demonstrate how to talk to MongoDB with Pyramid and Akhet.
</p>


</p>


]]></content:encoded>
    </item>
    <item>
      <title>Search by product name with Best Buy API</title>
      <link>http://niallohiggins.com/2009/05/21/search-by-product-name-with-best-buy-api/</link>
      <pubDate>Thu, 21 May 2009 21:21:37 PDT</pubDate>
      <category><![CDATA[Technical]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Database]]></category>
      <guid>http://niallohiggins.com/?p=519</guid>
      <description>Search by product name with Best Buy API</description>
      <content:encoded><![CDATA[
<img src="http://www.freebase.com/api/trans/image_thumb/en/best_buy?maxwidth=320&maxheight=200" />

<p>
I've been playing with the recently-released <a href="http://remix.bestbuy.com/">HTTP API for accessing the Best Buy product catalog</a>.  While its a little strange to use at first, its actually pretty useful.  One of the things I am interested in is online retail, specifically how to make Internet shopping easier.  Lets imagine I am looking for information on a particular digital camera - the <a href="http://www.freebase.com/view/en/nikon_coolpix_s210">Nikon Coolpix S210</a>.
</p>

<p>
<b>A Python skeleton</b>
<br/>

First, lets get our little Python test harness together.  Also, you are going to need <a href="http://remix.bestbuy.com/apps/register">your own Best Buy Remix API key</a>.  Here is a skeletal Python HTTP client:
</p>

<pre lang="python">
import httplib

API_KEY='<Your API Key Here>'

QUERY="/v1/products(name=Coolpix*&modelNumber=S210)"
OPTS="?sort=name.desc&show=all&format=json"
c = httplib.HTTPConnection('api.remix.bestbuy.com')
c.request('GET', "%s%s&apiKey=%s" %(QUERY, OPTS, API_KEY))
r = c.getresponse()
data = r.read()
print data
</pre>

Save the above to a file like bb.py.

<p>
<b>Our first Best Buy query</b>
<br/>

Now lets try to write a sample query for the Nikon Coolpix S210.  Although the <a href="http://remix.bestbuy.com/docs/types/Product_Queries">Best Buy Remix API docs</a> are a bit sparse, we can guess that items must have an attribute called 'name'.  In fact they do!  So lets try searching for the camera by name.  
</p>

<pre lang="python">
# Same code as above, but we change the value of QUERY:
QUERY="/v1/products(name=Nikon Coolpix S210)"
</pre>

Looks pretty reasonable.  Unfortunately, Best Buy is going to give us back a 400 error:

<pre>
<code>
$ python bb.py
&lt;?xml version="1.0" encoding="iso-8859-1"?&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;
 &lt;head&gt;
  &lt;title&gt;400 - Bad Request&lt;/title&gt;
 &lt;/head&gt;
 &lt;body&gt;
  &lt;h1&gt;400 - Bad Request&lt;/h1&gt;
 &lt;/body&gt;
&lt;/html&gt;
</code>
</pre>

<p>
<b>Gimme everything!</b>
<br/>

It turns out that Best Buy don't name their products in the most intuitive way.  Lets try a wildcard on just `Coolpix' instead:
</p>

<pre lang="python">
# Same code as above, but we change the value of QUERY:
QUERY="/v1/products(name=Coolpix*)"
</pre>

<img src="http://img.freebase.com/api/trans/image_thumb/en/nikon_coolpix_s210?maxwidth=320&maxheight=200" />

<p>
This time, we are going to get tons of data back, in <a href="http://json.org">JSON format</a>.  Best Buy remix defaults to XML, but I prefer JSON so I added the <b>format=json</b> parameter to the query.  Ok, so now we have an overwhelming amount of data on Coolpix cameras - but we really just want information for the S210.  
</p>
<p>
<b>Best Buy's quirky product schema</b>
<br/>

Well, there is a solution.  Best Buy don't store the model number in the `name' attribute - instead they store it in a separate `modelNumber' attribute.  If we query for name=Coolpix* AND modelNumber=S210, we should get the expected result, finally:
</p>

<pre lang="python">
# Same code as above, but we change the value of QUERY:
QUERY="/v1/products(name=Coolpix*&modelNumber=S210)"
</pre>

<p>
Et voila!  Now Best Buy gives us back all the information it has about the <b>Nikon Coolpix S210</b>.  This is pretty detailed stuff, including all those details like compatible memory formats, digital zoom, along with the price and availability.  Very cool!  Just for kicks, lets show the whole script to send a query to Best Buy, parse the JSON response, and finally print the price:
</p>

<pre lang="python">
import httplib
import json

API_KEY='<Your API Key Here>'
QUERY="/v1/products(name=Coolpix*&modelNumber=S210)"
OPTS="?sort=name.desc&show=all&format=json"
c = httplib.HTTPConnection('api.remix.bestbuy.com')
c.request('GET', "%s%s&apiKey=%s" %(QUERY, OPTS, API_KEY))
r = c.getresponse()
data = r.read()

camera_info = json.loads(data)

print "price: %s"%(camera_info['products'][0]['regularPrice'])
</pre>

And we run it:

<pre lang="bash">
$ python bb.py
price: 89.99
</pre>

Whee!
]]></content:encoded>
    </item>
    <item>
      <title>Get a DB-API cursor object with Python and SQLObject</title>
      <link>http://niallohiggins.com/2009/05/20/get-a-db-api-cursor-object-with-python-and-sqlobject/</link>
      <pubDate>Wed, 20 May 2009 18:30:52 PDT</pubDate>
      <category><![CDATA[Technical]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Database]]></category>
      <guid>http://niallohiggins.com/?p=498</guid>
      <description>Get a DB-API cursor object with Python and SQLObject</description>
      <content:encoded><![CDATA[
<p>
<b>On ORMs</b>
<br/>
It so happens that I end up dealing with the Python <a href="http://en.wikipedia.org/wiki/Object-relational_mapping">ORM</a> <a href="http://www.sqlobject.org/">SQLObject</a> pretty often.  I don't really like ORMs very much, since in my experience they make those 80% of database things that are already easy to do with plain SQL easier, while making the other 20% of database things which are already hard impossible.  They do save some boiler-plate, and let you express your schema and queries in Python (or whatever programming language you are using) instead of SQL - but this tends to break down at a certain level of complexity, and just gets in the way.  You end up doing a huge amount of wrangling with the ORM to do something which is very simple in plain old SQL.  Fundamentally, SQL was designed as a declarative query language for the relational model and not to represent object hierarchies in the same way programming languages do, hence ORMs are always going to be a nasty hack in my opinion.
</p>

<p>
<b>SQLObject vs. SQLAlchemy</b>
<br/>
<a href="http://niallohiggins.com/wp-content/uploads/2009/05/sqla-logo6.gif"><img src="http://niallohiggins.com/wp-content/uploads/2009/05/sqla-logo6.gif" alt="sqlalchemy logo" title="sqla-logo6" width="188" height="52" class="size-full wp-image-501" /></a>
I actually much prefer <a href="http://www.sqlalchemy.org/">SQLAlchemy</a> to SQLObject.  SQLAlchemy has a more explicit divide between its various components - you aren't forced to use the ORM stuff if you don't want to.  It can be used just as a handy database abstraction layer with programmatic SQL and connection pooling and so on if you want.  And if you truly want to go the full ORM mapping route, they provide that too.  For truly tricky things, SQLAlchemy will be happy to provide you with a <a href="http://www.python.org/dev/peps/pep-0249/">DB-API 2.0</a> cursor so that you can execute whatever custom SQL you wish.
</p>

<p>
<b>Monolithic vs. modular</b>
<br/>
<img src="http://niallohiggins.com/wp-content/uploads/2009/05/monolith.jpg" alt="monolith" title="monolith" width="320" height="200" class="aligncenter size-full wp-image-507" />
This is my main problem with SQLObject - its very difficult to figure out how to get at the underlying database connection.  I don't know how its possible to use the connection pooling and programmatic SQL builder without using the ORM but perhaps it is doable.  The <a href="http://www.sqlobject.org/SQLObject.html">documentation for SQLObject</a> is far inferior to the <a href="http://www.sqlalchemy.org/docs/">documentation of SQLAlchemy</a> I'm sorry to say.  Just try to figure out how to use transactions reliably with SQLObject!  Even when I managed to put together some code which according to the documentation should work, SQLObject decided to interleave the actions in separate transactions.  With SQLAlchemy I never had this problem.
</p>

<p>
<b>Getting at the cursor</b>
<br/>
While seemingly undocumented, it is in fact possible to get the underlying driver's connection object, and from there grab a <a href="http://www.python.org/dev/peps/pep-0249/">DB-API</a> cursor.  The pattern is:
</p>

<pre lang="python">
# Set up the SQLObject connection as usual
connection = connectionForURI('sqlite:/:memory:')
# Grab the database connection
dbobj = connection.getConnection()
# Get a cursor from the low-level driver
cursor = dbobj.cursor()
# <do stuff with the cursor>
cursor.close()
</pre>

Et voila.
]]></content:encoded>
    </item>
    <item>
      <title>Pylons tip #2: Using SQLite with Pylons</title>
      <link>http://niallohiggins.com/2008/11/16/using-sqlite-with-pylons/</link>
      <pubDate>Sun, 16 Nov 2008 18:30:12 PST</pubDate>
      <category><![CDATA[Technical]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Database]]></category>
      <guid>http://niallohiggins.com/?p=117</guid>
      <description>Pylons tip #2: Using SQLite with Pylons</description>
      <content:encoded><![CDATA[
<a href="http://www.sqlite.org/">SQLite</a> is an extremely useful little database.  It <a href="http://www.sqlite.org/features.html">has a nifty bunch of features</a> and is super simple to set up.  Using SQLite reduces the cost of developing and maintaining a powerful SQL database even more than traditional free RDBMS' like <a href="http://www.postgresql.org">PostgreSQL</a> and <a href="http://www.mysql.com">MySQL</a>.  Your database is simply an on-disk file - no need to configure user accounts, connection strings or any of that stuff.

While this has its limitations, I have found that SQLite is more than sufficient for many web applications.  These days I like to write my web applications in <a href="http://www.pylonsbook.com">Pylons</a>.  Python <a href="http://docs.python.org/lib/module-sqlite3.html">has a full-featured</a> SQLite module which conforms to <a href="http://www.python.org/dev/peps/pep-0249/">DB-API 2.0</a>.

To use SQLite in a Pylons application, all you need to do is open the SQLite database file.  I use a little convenience function to do this:

<pre lang="python" line="1">
import sqlite3
def open_db():
    conn = sqlite3.connect(config['sqlite_db_file'])
    return conn
</pre>

As you can see, the open_db() function references a configuration variable, <strong>sqlite_db_file</strong>.  Instead of having to hard-code the location of the file in your source code, you can simply put it in your Pylons configuration file.  to do this, simply add the settings to the <strong>app:man</strong> section of your INI-file - typically development.ini or test.ini:

<pre lang="ini" line="1">
[app:main]
use = egg:MyApp
full_stack = true
cache_dir = %(here)s/data
beaker.session.key = mykey
beaker.session.secret = somesecret
sqlite_db_file = /path/to/your/sqlite.db
</pre>

And there you go!]]></content:encoded>
    </item>
    <item>
      <title>Freebase Suggest and restricting to multiple types </title>
      <link>http://niallohiggins.com/2008/11/14/freebase-suggest-and-restricting-to-multiple-types/</link>
      <pubDate>Fri, 14 Nov 2008 21:43:49 PST</pubDate>
      <category><![CDATA[Technical]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Database]]></category>
      <guid>http://niallohiggins.com/?p=98</guid>
      <description>Freebase Suggest and restricting to multiple types </description>
      <content:encoded><![CDATA[
<a href="http://code.google.com/p/freebase-suggest/">Freebase Suggest</a> is a little JavaScript (and <a href="http://jquery.com">jQuery</a>) widget for adding <a href="http://www.freebase.com">Freebase</a>'s <a href="http://www.freebase.com/view/guid/9202a8c04000641f8000000006ad84c9">auto-complete and search API</a> reconciliation features to any of your text boxes.  While this might sound a bit strange or pointless initially, its actually incredibly useful in many applications  

Imagine you are running a site for your own music reviews.  You have a nice web form for writing the reviews, which includes fields for artist name and album.  It can be a pain sometimes to remember the exact album title or band name, and you probably find yourself having to double-check this a few times before posting your review.  However, chances are high that your artist and album are already available in Freebase, and this is where the Freebase Suggest widget comes in.  You simply attach the widget to your artist field, and your album field.  Now by default, you can auto-complete to any topic in Freebase.  This is pretty good, but wait there's more!  You can trivially nail down the types returned by the auto-complete service to just be, say, <a href="http://www.freebase.com/view/music/album">/music/album</a>.  You could do the same for your musical artist box by limiting to <a href="http://www.freebase.com/view/music/artist">/music/artist</a>.  To see what this Freebase Suggest widget looks like in this configuration, <a href="http://mqlx.com/freebase-suggest/examples/suggest_demo2.html">check out some of the examples</a>.

So now you know how to add Freebase Suggest to your web forms to reduce friction on input.  You also know how to nail down the auto-complete results to a specific type.  But what if you have a single input box which accepts, say a more generic 'media title'.  This could be a <a href="http://www.freebase.com/view/film/film">film</a> name, a <a href="http://www.freebase.com/view/tv/tv_program">TV show</a> or a music album.  Again, it would be really nice here to be able to use Freebase Suggest to leverage the already-entered and verified data of Freebase to ease input in your form - but how do you make it work with multiple types?

This is something I wanted to do in one of my own applications today, and its very easy!  In order to limit your Freebase Suggest results to a specific type, you already have some code <a href="http://code.google.com/p/freebase-suggest/wiki/Usage">setting up the ac_param dictionary</a> passed to the widget.  That code probably looks something like this:

<pre lang="javascript" line="1">
var o = { type:'/music/album' };
$(id).freebaseSuggest({ac_param:o});
$(id).bind("fb-select", suggest_cb);
</pre>

Now, to adapt this so that it also handles completion of <a href="">films</a> and <a href="http://www.freebase.com/view/tv/tv_program">TV shows</a>, we simply add multiple type keys to our options dictionary, like so:

<pre lang="javascript" line="1">
var o = { type:'/music/album', 
          type:'/film/film',
          type:'/tv/tv_program' };
$(id).freebaseSuggest({ac_param:o});
$(id).bind("fb-select", suggest_cb);
</pre>

And there you have it!  Freebase Suggest results restricted to multiple types.
]]></content:encoded>
    </item>
    <item>
      <title>Trivially show an image for anything - Freebase ID to Image service</title>
      <link>http://niallohiggins.com/2008/11/02/trivially-show-an-image-for-anything-freebase-id-to-image-service/</link>
      <pubDate>Sun, 02 Nov 2008 21:04:11 PST</pubDate>
      <category><![CDATA[Technical]]></category>
      <category><![CDATA[Database]]></category>
      <guid>http://niallohiggins.com/?p=72</guid>
      <description>Trivially show an image for anything - Freebase ID to Image service</description>
      <content:encoded><![CDATA[
<b>DNS for things</b>

<a href="http://www.freebase.com/">Freebase</a> is extremely useful for many things, but one of the most simple is as a sort of "DNS for things".  Take for example films, computer games, programming languages.  There are various disparate databases, with their own keys, all over the internet.   It would be difficult to write an application to understand both an <a href="http://www.imdb.com">IMDB</a> key and a key from  a software site like <a href="http://www.freshmeat.net">freshmeat.net</a>, for example. 

Freebase makes this possible, however.  There are a huge number of things in Freebase, each with their own (and often humanly readable) IDs.

<b>More than just a repository of IDs</b>

Of course, Freebase tries to store not just a key for a thing, but also as much information about that thing as possible.  There are huge swathes of data about things from <a href="http://hathayoga.freebase.com">Hatha Yoga</a> postures to <a href="http://saturdaynightlive.freebase.com/">Saturday Night Live</a>.

<b>Lots of images</b>

One of the most basic things which Freebase tries to store with each thing (or topic, in Freebase terms) is an image (or images).  Freebase actually has pretty good coverage for images - around 40% of topics in Freebase have an associated image - many of which come from <a href="http://wikipedia.org">Wikipedia</a>.

<b>Mapping a thing to an image</b>

Freebase makes images (and other static content blobs) available through its <a href="http://www.freebase.com/view/guid/9202a8c04000641f8000000006cf5696">"trans" API</a>.  Trans provides a couple of transformations - the most interesting in this context being the <a href="http://www.freebase.com/view/guid/9202a8c04000641f8000000006cf560a">image thumbnailing service</a> - along with providing access to the raw binary data.

Content is addressed by its own Freebase ID.  Freebase Topics then link to these content objects.  So, in order to, for example, fetch an image for a topic, you need to query Freebase using <a href="http://mql.freebaseapps.com/">MQL</a>.  The MQL query is trivial:

<pre lang="javascript" line="1">
[{ 
    'id': /* id of topic to find image for */, 
    '/common/topic/image': [{}]
}]
</pre>

The result will contain an array of image IDs, which can be plugged into the trans api, such that you can write code like:

<pre lang="html" line="1">
<img src="http://www.freebase.com/api/trans/raw/guid/9202a8c04000641f8000000009497050" />
</pre>

Thats nice, but wouldn't it be nice if you could just have a path to the Freebase ID, and have the first associated image be returned? For example to get a picture of US Treasury Secretary Henry Paulson, you could just write:

<pre lang="html" line="1">
<img src="http://www.freebase.com/api/trans/id2image/en/henry_paulson" />
</pre>

<b>Acre applications</b>

While you could write your own app to issue the MQL queries on your behalf and return the resultant URLs,  Freebase provides a framework for these kinds of applications - hosted on their servers (close to the databases etc) so you don't have to.  This hosted application service is called <a href="http://www.freebase.com/view/guid/9202a8c04000641f80000000086ea59b">Acre</a>, and while it is still in the early stages of development, it works fine for simple things like this.

<b>`ID 2 Image' Acre Application</b>

I wrote this simple id-2-image translation application in 11 lines of JavaScript, and it works just fine.  Here is the source:

<pre lang="javascript" line="1">
if (acre.environ.path_info == "/") {
    acre.start_response(400);
    acre.exit();
}
var query = [{ "id" : acre.environ.path_info, "/common/topic/image":[{}]}];
var r = acre.freebase.MqlRead(query);
acre.start_response(302, {
        'Location': acre.freebase.imgurl(r.result[0]['/common/topic/image'][0]['id'].substring(1))
});
</pre>

Using this application, you can write HTML like this, and have it display:

<pre lang="html" line="1">
<img src="http://id2image.niallo.user.dev.freebaseapps.com/id/en/henry_paulson" />
</pre>

To prove it works, here is the image generated by it:

<img src="http://id2image.niallo.user.dev.freebaseapps.com/id/en/henry_paulson" />

So there you have it - trivially show an image for anything.  Coupling this concept of being able to generate interesting output for a given Freebase ID, with the power of making it easy to find, select and store Freebase IDs in your application via freely available widgets like <a href="http://code.google.com/p/freebase-suggest/">Freebase Suggest</a> is extremely compelling.

If you are in the SF Bay area, and are interested in Freebase, why not consider coming to the Freebase Hack Day on November 8th?  Click the link below for details.

<a href="http://tinyurl.com/freebasehackday"><img src="http://www.freebase.com/api/trans/raw/guid/9202a8c04000641f8000000009497050" style="border: none" /></a>]]></content:encoded>
    </item>
    <item>
      <title>Amusing PostgreSQL tid-bit: dates treated as arithmetic expressions</title>
      <link>http://niallohiggins.com/2008/03/17/amusing-postgresql-tid-bit-dates-treated-as-arithmetic-expressions/</link>
      <pubDate>Mon, 17 Mar 2008 21:14:05 PDT</pubDate>
      <category><![CDATA[Technical]]></category>
      <category><![CDATA[Database]]></category>
      <guid>http://niallohiggins.com/2008/03/17/amusing-postgresql-tid-bit-dates-treated-as-arithmetic-expressions/</guid>
      <description>Amusing PostgreSQL tid-bit: dates treated as arithmetic expressions</description>
      <content:encoded><![CDATA[
This evening I was trying to select entries within a specific date range, for example, all torrents for films which had been released in 2007.  My query looked something like:

<pre lang="sql" line="1">SELECT name FROM table WHERE date > 2007-01-01 AND date < 2008-01-01</pre>

<a href="http://www.postgresql.org">PostgreSQL</a> consistently returned very odd results.  As far as it was concerned, Transformers was not a 2007 release, furthermore Batman Begins - which I distinctly remember going to see about three years ago - was.

Any relatively experienced SQL hacker is no doubt chuckling, having immediately seen my error.  Of course, PostgreSQL is treating the un-quoted dates as arithmetic expressions and evaluating them numerically. When you think about it, 2005 - 05 - 05 = 1995. This is a perfectly valid arithmetic expression, its just that it happens to look like a definitive calendar date to my brain.

I found this mistake on my part absolutely hilarious.]]></content:encoded>
    </item>
  </channel>
</rss>

