<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">g.raphaelli's weblog</title>
  <id>http://g.raphaelli.com/2010/01/feed.atom</id>
  <updated>2010-01-25T01:41:15Z</updated>
  <link href="http://g.raphaelli.com/" />
  <link href="http://g.raphaelli.com/2010/01/feed.atom" rel="self" />
  <generator uri="http://zine.pocoo.org/" version="0.1.2">Zine</generator>
  <entry xml:base="http://g.raphaelli.com/2010/01/feed.atom">
    <title type="text">Flickr.API 0.4.3</title>
    <id>tag:g.raphaelli.com,2010-01-25:/entry;2010/1/25/flickr-api-0-4-3</id>
    <updated>2010-01-25T01:41:15Z</updated>
    <published>2010-01-25T01:26:00Z</published>
    <link href="http://g.raphaelli.com/2010/01/25/flickr-api-0-4-3" />
    <author>
      <name>g</name>
    </author>
    <content type="html">&lt;a href="http://aaronland.info/"&gt;Aaron&lt;/a&gt; kindly informed me of a problem with &lt;a href="http://pypi.python.org/pypi/Flickr.API/"&gt;Flickr.API&lt;/a&gt; where calling &lt;a href="http://www.flickr.com/services/api/flickr.urls.lookupUser.htm"&gt;flickr.urls.lookupUser&lt;/a&gt; with the required 'url' parameter returns the the contents of the resource pointed to by that url, instead of the expected API response.  The problem is easily demonstrated using &lt;a href="http://static.g.raphaelli.com/contrib/code/flickrcall.py"&gt;flickrcall.py&lt;/a&gt;, introduced in &lt;a href="http://g.raphaelli.com/2009/08/06/flickr-api-helper-script"&gt;this post&lt;/a&gt;:

&lt;div class="syntax"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;flickrcall.py flickr.urls.lookupUser &lt;span class="s2"&gt;&amp;quot;url=http://www.flickr.com/photos/graph&amp;quot;&lt;/span&gt;

&amp;lt;!DOCTYPE HTML PUBLIC &lt;span class="s2"&gt;&amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot;&lt;/span&gt;&amp;gt;

&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
...
&lt;/pre&gt;&lt;/div&gt;


The trouble lies in the Flickr.API.Request init:

&lt;div class="syntax"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;http://api.flickr.com/services/rest/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;urllib2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


Clearly I didn't anticipate 'url' as a valid argument - if you pass it in through **args it overwrites the default url parameter.  Worse, if you wanted to use a different api endpoint, you couldn't even call this method with the required url parameter as python will complain about multiple values for the same 'url' argument.  Here's a simple demonstration of what's happening:

&lt;div class="syntax"&gt;&lt;pre&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;baz&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;baz&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bar&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;bar&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;bar&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;baz&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;keyword&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;baz&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="ne"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;got&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;keyword&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


For 0.4.3, I've simply changed the url keyword parameter to apiurl to make things work as I haven't thought of any backwards compatible way to fix this.  Now we get the right response:

&lt;div class="syntax"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;flickrcall.py flickr.urls.lookupUser &lt;span class="s2"&gt;&amp;quot;url=http://www.flickr.com/photos/graph&amp;quot;&lt;/span&gt;
&amp;lt;?xml &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&amp;gt;
&amp;lt;rsp &lt;span class="nv"&gt;stat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ok&amp;quot;&lt;/span&gt;&amp;gt;
&amp;lt;user &lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;83127823@N00&amp;quot;&lt;/span&gt;&amp;gt;
	&amp;lt;username&amp;gt;raphco&amp;lt;/username&amp;gt;
&amp;lt;/user&amp;gt;
&amp;lt;/rsp&amp;gt;
&lt;/pre&gt;&lt;/div&gt;


I'm hoping that unless you work at Flickr (&lt;a href="http://www.flickr.com/jobs"&gt;we're hiring!&lt;/a&gt;), you're not likely to change the endpoint url and this change should only fix this particular problem for you.</content>
  </entry>
</feed>

