<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Leonardr on Launchpad Blog</title>
    <link>https://blog.launchpad.net/authors/leonardr/</link>
    <description>News and updates from the Launchpad team</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 19 Jan 2010 14:46:14 +0000</lastBuildDate>
    <atom:link href="https://blog.launchpad.net/feed/authors/leonardr/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Anonymous Access to the Launchpad Web Service API</title>
      <link>https://blog.launchpad.net/general/anonymous-access-to-the-launchpad-web-service-api/</link>
      <pubDate>Tue, 19 Jan 2010 14:46:14 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=1279</guid>
      <description>&lt;p&gt;You asked for it and we&amp;rsquo;ve delivered. Your launchpadlib scripts can now get read-only access to &lt;a href=&#34;https://help.launchpad.net/API&#34;&gt;the Launchpad web service API&lt;/a&gt; without going through any authorization process. Previously, to authorize your script, you had to open a web page in the end-user&amp;rsquo;s web browser and get the user to click a button. Now, you only have to go through that process if you want to access someone&amp;rsquo;s private data or modify the Launchpad dataset on their behalf.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re using the latest version of launchpadlib (1.5.4), you can log in anonymously with the &lt;code&gt;login_anonymously&lt;/code&gt; helper method. You just have to pass in a string identifying your client, and the name of the Launchpad server you want to access.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;from launchpadlib.launchpad import Launchpad
launchpad = Launchpad.login_anonymously(&amp;#34;my client&amp;#34;, &amp;#34;edge&amp;#34;)
print launchpad.bugs[1].title
# Microsoft has a majority market share&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(That code also illustrates how the latest version of Launchpadlib lets you specify a short string like &amp;ldquo;edge&amp;rdquo; instead of having to importing a constant like EDGE_SERVICE_ROOT.)&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re using an older version of launchpadlib, you can log in anonymously using the &lt;code&gt;login&lt;/code&gt; helper method. You can get anonymous access by passing in empty strings for the token string and access secret:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;from launchpadlib.launchpad import Launchpad, EDGE_SERVICE_ROOT
launchpad = Launchpad.login(&amp;#34;my client&amp;#34;, &amp;#34;&amp;#34;, &amp;#34;&amp;#34;, EDGE_SERVICE_ROOT)
print launchpad.bugs[1].title
# Microsoft has a majority market share&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Right now, anonymous access only works on Launchpad&amp;rsquo;s &amp;rsquo;edge&amp;rsquo; and &amp;lsquo;staging&amp;rsquo; instances. It&amp;rsquo;ll be installed on production at the end of the month, with the release of Launchpad 10.01.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Launchpad&#39;s web service code released as standalone libraries</title>
      <link>https://blog.launchpad.net/general/launchpads-web-service-code-released-as-standalone-libraries/</link>
      <pubDate>Wed, 29 Apr 2009 21:32:17 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=751</guid>
      <description>&lt;p&gt;The last time I posted to this blog I was describing &lt;a href=&#34;http://blog.launchpad.net/api/inside-the-launchpad-foundations-sprint&#34;&gt;a sprint in Montreal&lt;/a&gt;, where we were working on refactoring the web service code and moving it from Launchpad to a standalone library. Several weeks of work later, we&amp;rsquo;re done. You can now create your own web service using the same techniques we use in Launchpad.&lt;/p&gt;
&lt;p&gt;The library is &lt;a href=&#34;https://launchpad.net/lazr.restful&#34;&gt;lazr.restful&lt;/a&gt;, and there&amp;rsquo;s a companion client library called &lt;a href=&#34;https://launchpad.net/lazr.restfulclient&#34;&gt;lazr.restfulclient&lt;/a&gt;. They&amp;rsquo;re also on PyPI (&lt;a href=&#34;http://pypi.python.org/pypi/lazr.restful&#34;&gt;&lt;code&gt;restful&lt;/code&gt;&lt;/a&gt;, &lt;a href=&#34;http://pypi.python.org/pypi/lazr.restfulclient&#34;&gt;&lt;code&gt;restfulclient&lt;/code&gt;&lt;/a&gt;). The place to discuss these libraries is &lt;a href=&#34;https://launchpad.net/~lazr-users&#34;&gt;the lazr-users mailing list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll show you &lt;code&gt;lazr.restful&lt;/code&gt; first.  If you just want to use the package, and you have easy_install, try “easy_install lazr.restful“.  You can also &lt;a href=&#34;https://edge.launchpad.net/lazr.restful/+download&#34;&gt;download the tarball&lt;/a&gt; and use “python setup.py install“ on it.  Or you can get check out the source code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ bzr branch lp:lazr.restful mybranch
$ cd mybranch
$ python bootstrap
$ python bin/buildout
$ python bin/test
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;test&lt;/code&gt; command starts up the web service defined in &lt;code&gt;src/lazr/restful/example&lt;/code&gt; and puts it through its paces with simulated HTTP requests. The example web service shows how to use Python decorators to turn Zope interfaces into a web service with the same features as Launchpad&amp;rsquo;s web service. Just as an example, here&amp;rsquo;s what a normal Zope interface might look like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class IPerson(Interface):
    first_name = TextLine(title=u&amp;#34;First name&amp;#34;, required=True)
    last_name = TextLine(title=u&amp;#34;Last name&amp;#34;, required=True)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here&amp;rsquo;s what it would look like with &lt;code&gt;lazr.restful&lt;/code&gt; annotations:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;class IPerson(Interface):
    export_as_webservice_entry(plural_name=&amp;#39;people&amp;#39;)
    first_name = exported(TextLine(title=u&amp;#34;First name&amp;#34;, required=True))
    last_name = exported(TextLine(title=u&amp;#34;Last name&amp;#34;, required=True))
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;lazr.restful&lt;/code&gt; will inspect that interface and know that you&amp;rsquo;re defining an &amp;rsquo;entry&amp;rsquo; type resource, with each entry containing two bits of data. It&amp;rsquo;ll publish a WADL file describing that interface. Clients will be able to make GET, PUT, and PATCH requests to the &amp;lsquo;person&amp;rsquo; resources to manipulate your application data.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lazr.restful&lt;/code&gt; provides annotations for every web service feature you see in Launchpad: entries, collections, hosted files, named operations, and so on. It even has some features that aren&amp;rsquo;t used by Launchpad yet, like the ability to make entries respond to DELETE requests.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lazr.restfulclient&lt;/code&gt; is the client side. We took almost all the code out of &lt;code&gt;launchpadlib&lt;/code&gt; and made a generic client that will run against any &lt;code&gt;lazr.restful&lt;/code&gt; service.&lt;/p&gt;
&lt;p&gt;The same &lt;code&gt;bootstrap&lt;/code&gt;-&lt;code&gt;buildout&lt;/code&gt;-&lt;code&gt;test&lt;/code&gt; cycle that worked for &lt;code&gt;lazr.restful&lt;/code&gt; also works for &lt;code&gt;lazr.restfulclient&lt;/code&gt;. The &lt;code&gt;test&lt;/code&gt; command will start up the web service from &lt;code&gt;lazr.restful&lt;/code&gt;, and manipulate it with Pythonic launchpadlib-like commands instead of fake HTTP requests. Given a &amp;lsquo;person&amp;rsquo; resource like the one defined in the example above, you could run this code in &lt;code&gt;lazr.restfulclient&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;person_resource.first_name = &amp;#34;new first name&amp;#34;
person_resource.lp_save()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Before long we&amp;rsquo;ll be removing almost all the code from &lt;code&gt;launchpadlib&lt;/code&gt; leaving only the OAuth handling and some Launchpad-specific information. We&amp;rsquo;re also working to make it easier to use &lt;code&gt;lazr.restful&lt;/code&gt; with standard WSGI applications, so you don&amp;rsquo;t have to know as much Zope.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Inside the Launchpad Foundations sprint </title>
      <link>https://blog.launchpad.net/api/inside-the-launchpad-foundations-sprint/</link>
      <pubDate>Tue, 03 Mar 2009 16:06:32 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=592</guid>
      <description>&lt;p&gt;I&amp;rsquo;m in Montreal this week, with the rest of the Launchpad Foundations team and a few other Canonical engineers. We&amp;rsquo;re preparing for the open sourcing of Launchpad by doing a lot of refactoring, so that when the code is released in July it will be more comprehensible, and reusable in projects other than Launchpad.&lt;/p&gt;
&lt;p&gt;In addition to our main body of Launchpad code we&amp;rsquo;ll be releasing a framework project called &lt;a href=&#34;http://www.launchpad.net/lazr&#34;&gt;LAZR&lt;/a&gt;. Code that&amp;rsquo;s not Launchpad-related will go into LAZR or one of its subprojects: lazr.config, lazr.uri, lazr.batchnavigator, and so on. These will be little libraries that can be reused in other projects.&lt;/p&gt;
&lt;p&gt;For instance: underneath the Launchpad web service is a generic library that lets you create a web service from your existing data objects by annotating the Zope interfaces. All this code lives in LAZR: the only web service code in Launchpad has to do with Launchpad&amp;rsquo;s web service specifically.  We&amp;rsquo;d like you to reuse the LAZR webservice code in any project that uses Zope interfaces to describe its data objects.&lt;/p&gt;
&lt;p&gt;Unfortunately, there&amp;rsquo;s a lot of code in Launchpad that really should be in LAZR. If that wasn&amp;rsquo;t bad enough, the web service code in LAZR is full of dependencies on that Launchpad code. At the moment, you can&amp;rsquo;t run the LAZR web service code without bringing in all of Launchpad.&lt;/p&gt;
&lt;p&gt;The object of this sprint is to refactor this code and move it all into LAZR packages. Our medium-term goal is a working example web service (code name &amp;ldquo;Sharks&amp;rdquo;) that uses no Launchpad code, but it won&amp;rsquo;t stop there. The more utilities we can move out of Launchpad&amp;rsquo;s monolithic code base, the more likely it is you&amp;rsquo;ll be able to find a bit of code you want to reuse.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What&#39;s new with the Launchpad web service API</title>
      <link>https://blog.launchpad.net/cool-new-stuff/whats-new-with-the-launchpad-web-service-api/</link>
      <pubDate>Mon, 12 Jan 2009 15:05:33 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=408</guid>
      <description>&lt;p&gt;The frequency of these posts has fallen off recently because I&amp;rsquo;ve been working on a Javascript client for the Launchpad web service, which we&amp;rsquo;ll be using to add some Ajax functionality to Launchpad. But it&amp;rsquo;s time for another one, featuring progress that&amp;rsquo;s visible to you.&lt;/p&gt;
&lt;p&gt;First, an announcement: on Tuesday, the 20th of January, I&amp;rsquo;ll be doing an IRC chat on the Launchpad web service as part of Ubuntu Developer Week. &lt;a href=&#34;https://wiki.ubuntu.com/UbuntuDeveloperWeek&#34;&gt;See the schedule for details.&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;newly-published-objects&#34;&gt;Newly published objects&lt;/h2&gt;
&lt;p&gt;The Bugs team has published CVEs through the web service. There&amp;rsquo;s a &lt;code&gt;cves&lt;/code&gt; collection associated with every bug, and you can link and unlink CVEs from bugs.&lt;/p&gt;
&lt;p&gt;The Soyuz team has published archives. You can use the web service to inspect a distribution archive or PPA, copy packages from one archive to another, and manage the permissions of who&amp;rsquo;s allowed to upload to an archive.&lt;/p&gt;
&lt;p&gt;Merge proposals have also been published, but they&amp;rsquo;re read-only for now, so not very useful yet. But pretty soon you should be able to integrate them into an external code review tool.&lt;/p&gt;
&lt;h2 id=&#34;modify-fields-directly-instead-of-through-named-operations&#34;&gt;Modify fields directly instead of through named operations&lt;/h2&gt;
&lt;p&gt;Consider the bug task object. Up to this point it&amp;rsquo;s had a number of read-only fields like &amp;lsquo;status&amp;rsquo;, &amp;lsquo;importance&amp;rsquo;, and &amp;lsquo;assignee&amp;rsquo;. These fields aren&amp;rsquo;t &lt;em&gt;really&lt;/em&gt; read-only: you can modify them, but you have to know the secret. Each has a corresponding named operation: &lt;code&gt;transitionToStatus&lt;/code&gt;, &lt;code&gt;transitionToImportance&lt;/code&gt;, and &lt;code&gt;transitionToAssignee&lt;/code&gt;. To modify &amp;lsquo;status&amp;rsquo; you need to invoke &lt;code&gt;transitionToStatus&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So you can&amp;rsquo;t modify a bug task&amp;rsquo;s status the way you can modify a bug&amp;rsquo;s description. This launchpadlib code works:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; bug.description = &amp;#34;A new description&amp;#34;
&amp;gt;&amp;gt;&amp;gt; bug.lp_save()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But this code doesn&amp;rsquo;t (except now, on staging):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; task.status = &amp;#34;New&amp;#34;
&amp;gt;&amp;gt;&amp;gt; task.lp_save()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You have to do this instead:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; task.transitionToStatus(&amp;#34;New&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I&amp;rsquo;ve long felt that this &lt;code&gt;transitionTo&lt;/code&gt; stuff is an internal detail you shouldn&amp;rsquo;t have to worry about, and &lt;a href=&#34;https://bugs.edge.launchpad.net/malone/+bug/302836&#34;&gt;judging from the bugs you&amp;rsquo;re filing&lt;/a&gt;, some of you agree. So I&amp;rsquo;ve made &amp;lsquo;status&amp;rsquo;, &amp;lsquo;importance&amp;rsquo;, and &amp;lsquo;assignee&amp;rsquo; look like regular read-write fields.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;transitionTo&lt;/code&gt; methods are still available, so your old code will still work. In fact, the new code just calls the server-side &lt;code&gt;transitionTo&lt;/code&gt; methods behind the scenes. The validation errors you used to get from passing a bad value into &lt;code&gt;transitionToStatus&lt;/code&gt; will happen the same way if you set &amp;lsquo;status&amp;rsquo; to a bad value.&lt;/p&gt;
&lt;p&gt;There are other named operations that could be replaced by making the read-only field they modify into a read-write field, but I only changed those three bug task fields. I&amp;rsquo;ve talked to other Launchpad programmers about this new tool, and they&amp;rsquo;ll start using it according to their own schedules.&lt;/p&gt;
&lt;h2 id=&#34;http_etag&#34;&gt;&lt;code&gt;http_etag&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Finally, there&amp;rsquo;s one part of the Javascript work that&amp;rsquo;s generally useful if you&amp;rsquo;re writing code against the web service on the level of HTTP requests rather than using launchpadlib. That&amp;rsquo;s the &lt;code&gt;http_etag&lt;/code&gt; field now associated with entry objects such as people and bugs. It&amp;rsquo;s the same information provided in the HTTP header &amp;ldquo;ETag&amp;rdquo; when you get the entry object. So why send it again?&lt;/p&gt;
&lt;p&gt;Well, imagine that you get a whole collection of bugtasks, and then decide you want to edit one of them. Ideally you&amp;rsquo;d use the value of &amp;ldquo;ETag&amp;rdquo; to make a conditional PUT or PATCH request, so that you wouldn&amp;rsquo;t accidentally overwrite someone else&amp;rsquo;s changes.&lt;/p&gt;
&lt;p&gt;But you never got the ETag for that bugtask, because you got it as part of a collection. The &lt;code&gt;http_etag&lt;/code&gt; field comes to the rescue here, allowing you to make a conditional PUT or PATCH without having to send a separate GET just to get the bugtask&amp;rsquo;s ETag.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>This week in Launchpad&#39;s web API</title>
      <link>https://blog.launchpad.net/general/this-week-in-launchpads-web-api-3/</link>
      <pubDate>Fri, 26 Sep 2008 20:00:56 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=127</guid>
      <description>&lt;p&gt;You didn&amp;rsquo;t expect it, but here it is. &amp;ldquo;This Week in Launchpad&amp;rsquo;s Web API&amp;rdquo; returns for one more week! This week we&amp;rsquo;re pleased to announce that you can now search the bug tasks associated with a project, project group, distribution, or milestone. We know a lot of people have been waiting for this feature.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; launchpadlib_project = launchpad.projects[&amp;#39;launchpadlib&amp;#39;]
&amp;gt;&amp;gt;&amp;gt; me = launchpad.me
&amp;gt;&amp;gt;&amp;gt; my_launchpadlib_bugs = launchpadlib_project.searchTasks(assignee=me)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;a href=&#34;https://staging.launchpad.net/+apidoc#bug_target-searchTasks&#34;&gt;interface to searchTasks&lt;/a&gt; is very similar to the interface to Launchpad&amp;rsquo;s advanced search form. That fact should get you started searching easily.&lt;/p&gt;
&lt;p&gt;The other bug news is that you can now post a comment to a bug by invoking &lt;a href=&#34;https://staging.launchpad.net/+apidoc/index.html#bug-newMessage&#34;&gt;newMessage&lt;/a&gt; on the bug.&lt;/p&gt;
&lt;p&gt;Release files are now exposed through the web service. This means you can now integrate release management tools into Launchpad. When you do a release of your program, the same tool that packages the release can upload the release file to Launchpad and make a Launchpad release for it.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; series = launchpad.projects[&amp;#39;myproject&amp;#39;].series[0]
&amp;gt;&amp;gt;&amp;gt; release = series.addRelease(
...        version=new_item_name, code_name=&amp;#39;sumo&amp;#39;,
...        summary=&amp;#39;super new beta&amp;#39;,
...        description=&amp;#39;The be-all end-all version for the next century.&amp;#39;,
...        changelog=&amp;#39;Fixes security bug. Adds external support.&amp;#39;)
&amp;gt;&amp;gt;&amp;gt; release.add_file(filename=&amp;#34;release.tgz&amp;#34;,
...                          file_content=&amp;#34;[binary data]&amp;#34;,
...                          content_type=&amp;#34;application/x-gzip&amp;#34;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, we&amp;rsquo;ve changed launchpadlib so that when you upload a file, you need to set the filename you want the file to have on the server side. Previously, there was no way to set the filename.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; release_file = release.files[0]
&amp;gt;&amp;gt;&amp;gt; filehandle = release_file.open(&amp;#34;application/x-gzip&amp;#34;, &amp;#34;new-filename.tgz&amp;#34;, &amp;#34;w&amp;#34;)
&amp;gt;&amp;gt;&amp;gt; ...
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>This week in Launchpad&#39;s web API</title>
      <link>https://blog.launchpad.net/general/this-week-in-launchpads-web-api-2/</link>
      <pubDate>Thu, 18 Sep 2008 18:38:37 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=126</guid>
      <description>&lt;p&gt;This status report was put off until today because the edge site was frozen. This update is huge. We&amp;rsquo;ve made one change to launchpadlib, exposed a whole lot of Launchpad&amp;rsquo;s project registry, and published branches for the first time.&lt;/p&gt;
&lt;p&gt;Since the development cycle is over, the next update will probably be in two weeks.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Team restriction lifted&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You no longer need to be a member of the beta testers team to use the web service. We decided that the restriction didn&amp;rsquo;t make sense, given that nobody&amp;rsquo;s going to use the web service by accident. This &lt;em&gt;doesn&amp;rsquo;t&lt;/em&gt; mean that the web service is out of beta; we&amp;rsquo;ll make a much bigger deal of it when that happens.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;launchpadlib&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I fixed a longstanding annoyance in launchpadlib. This code will now work:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; launchpad.projects[&#39;firefox&#39;].releases[0]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Previously you would have had to slice the list and then index the slice:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; launchpad.projects[&#39;firefox&#39;].releases[:1][0]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;New Top-Level Collections&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve published the list of project groups as a new top-level collection.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; launchpad.project_groups[&amp;#39;mysql&amp;#39;].name
u&amp;#39;mysql&amp;#39;
&amp;gt;&amp;gt;&amp;gt; [group.name for group in launchpad.project_groups[:2]]
[u&amp;#39;launchpad-project&amp;#39;, u&amp;#39;aep&amp;#39;]

&amp;gt;&amp;gt;&amp;gt; [group.name for group in launchpad.project_groups.search(&amp;#34;mysql&amp;#34;)]
[u&amp;#39;tx&amp;#39;, u&amp;#39;wordpress-project&amp;#39;, u&amp;#39;samba-project&amp;#39;, u&amp;#39;openarchaeology&amp;#39;,
 u&amp;#39;mysql&amp;#39;, u&amp;#39;linterra&amp;#39;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We&amp;rsquo;ve also published the list of distributions.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; launchpad.distributions[&amp;#39;ubuntu&amp;#39;].name
u&amp;#39;ubuntu&amp;#39;

&amp;gt;&amp;gt;&amp;gt; [distro.name for distro in launchpad.distributions][:2]
[u&amp;#39;ubuntu&amp;#39;, u&amp;#39;elbuntu&amp;#39;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;The Pillar Set&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve published the Launchpad pillar set. This is a pretty confusing name but we haven&amp;rsquo;t found a better one yet. &amp;ldquo;Pillar&amp;rdquo; is a generic term that encompasses project, project group, and distribution. If you go to the &lt;a href=&#34;https://launchpad.net/&#34;&gt;Launchpad homepage&lt;/a&gt; you&amp;rsquo;ll see a list of &amp;ldquo;Featured projects&amp;rdquo;. These are actually featured &lt;em&gt;pillars&lt;/em&gt;: Extreme Tux Racer is a featured project, MySQL is a featured project group, and Ubuntu is a featured distribution. You can get access to the list of featured pillars with code like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; [pillar.name for pillar in launchpad.pillars.featured_pillars[:5]]
[u&amp;#39;anewt&amp;#39;, u&amp;#39;awn&amp;#39;, u&amp;#39;bauble&amp;#39;, u&amp;#39;bzr&amp;#39;, u&amp;#39;do&amp;#39;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can also use the pillar set to do a unified search across projects, project groups, and distributions. A search for &amp;lsquo;ubuntu&amp;rsquo; will pick up the &amp;lsquo;ubuntu&amp;rsquo; distribution, the &amp;lsquo;ubuntu-live-support&amp;rsquo; project group, and the &amp;lsquo;ubuntu-dev-docs&amp;rsquo; project.&lt;/p&gt;
&lt;p&gt;Unlike with, say, the bug set, you can&amp;rsquo;t just grab a bunch of pillar objects from inside &lt;code&gt;launchpad.pillars&lt;/code&gt;. The only interesting things about &lt;code&gt;launchpad.pillars&lt;/code&gt; are the things beneath it: the pillar search and the list of featured pillars.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Branches&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The code team has done some web service work, and you can now get basic information about a project&amp;rsquo;s registered bzr branches.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; branch = launchpad.projects[&amp;#39;firefox&amp;#39;].branches[0]
&amp;gt;&amp;gt;&amp;gt; branch.title
u&amp;#39;Firefox Trunk Package&amp;#39;
&amp;gt;&amp;gt;&amp;gt; branch.owner.name
u&amp;#39;asac&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Other Newly Published Objects&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We now publish a project&amp;rsquo;s release series, releases, and the files associated with those releases.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; release_series = launchpad.projects[&amp;#39;firefox&amp;#39;].series[1]
&amp;gt;&amp;gt;&amp;gt; release_series.title
u&amp;#39;Mozilla Firefox Series: 1.5&amp;#39;
&amp;gt;&amp;gt;&amp;gt; release = release_series.releases[0]
&amp;gt;&amp;gt;&amp;gt; release.version
u&amp;#39;1.5.0.2-source&amp;#39;
&amp;gt;&amp;gt;&amp;gt; release_file = release.files[0]
&amp;gt;&amp;gt;&amp;gt; release_file.date_uploaded
u&amp;#39;2006-10-23T09:26:47.228605+00:00&amp;#39;
&amp;gt;&amp;gt;&amp;gt; release_file.file.open().read()
[binary data]
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Last week in Launchpad&#39;s web API</title>
      <link>https://blog.launchpad.net/general/last-week-in-launchpads-web-api/</link>
      <pubDate>Mon, 08 Sep 2008 12:29:03 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=120</guid>
      <description>&lt;p&gt;Barry Warsaw, Francis Lacoste, and I gave an IRC chat about the Launchpad web service as part of Ubuntu Developer Week. There&amp;rsquo;s &lt;a href=&#34;https://wiki.ubuntu.com/MeetingLogs/devweek0809/LaunchpadWebService&#34;&gt;a transcript available&lt;/a&gt; in case you missed it.&lt;/p&gt;
&lt;p&gt;The big news from last week is that we finally have the API documentation being generated whenever a new version of Launchpad is deployed. Whatever server your script is running against, the &lt;code&gt;/+apidoc&lt;/code&gt; URL will contain the reference documentation for that version of Launchpad. &lt;a href=&#34;https://www.launchpad.net/+apidoc&#34;&gt;launchpad.net&amp;rsquo;s documentation&lt;/a&gt; will change when we do an official release of Launchpad, and &lt;a href=&#34;https://edge.launchpad.net/+apidoc&#34;&gt;edge.launchpad.net&amp;rsquo;s&lt;/a&gt; and &lt;a href=&#34;https://staging.launchpad.net/+apidoc&#34;&gt;staging.launchpad.net&amp;rsquo;s&lt;/a&gt; will be updated much more often, as our changes get pushed out to those servers.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s more!  I also added support to &lt;a href=&#34;https://help.launchpad.net/API/launchpadlib&#34;&gt;launchpadlib&lt;/a&gt; for access to the binary files hosted by Launchpad: mugshots, bug attachments, and so on. This is everything described in the reference doc as &amp;ldquo;a file resource.&amp;rdquo; If you upgrade launchpadlib, you can now access these files with a Pythonic file object interface.&lt;/p&gt;
&lt;p&gt;The server side of this has been in place since we launched the web service, so in theory you could have been messing with uploaded files this whole time by writing a custom-built client. But only recently did I update the &lt;a href=&#34;https://help.launchpad.net/API/Hacking&#34;&gt;hacking document&lt;/a&gt; that makes it easy to see how to do this.&lt;/p&gt;
&lt;p&gt;Finally, Edwin, Brad, and I have continued working on exporting the Launchpad registry. Of note are three new hosted-file resources: a project&amp;rsquo;s &lt;code&gt;brand&lt;/code&gt;, &lt;code&gt;logo&lt;/code&gt;, and &lt;code&gt;icon&lt;/code&gt;. Project groups also have more of their fields published.&lt;/p&gt;
&lt;p&gt;This week: more things published through the registry, hopefully some progress on bugs as well.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>This week in Launchpad&#39;s web API</title>
      <link>https://blog.launchpad.net/cool-new-stuff/this-week-in-launchpads-web-api/</link>
      <pubDate>Fri, 29 Aug 2008 15:45:44 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=119</guid>
      <description>&lt;p&gt;Last week the &lt;a href=&#34;https://help.launchpad.net/API&#34;&gt;Launchpad web service&lt;/a&gt; didn&amp;rsquo;t change, because the source tree was frozen pending a Launchpad release. But this week we landed the branches we wrote last week, as well as some new ones.&lt;/p&gt;
&lt;p&gt;The biggest change this week is client-side caching. Update your copy of &lt;a href=&#34;https://launchpad.net/launchpadlib&#34;&gt;launchpadlib&lt;/a&gt; to revision 17 and change your scripts to pass a directory name into the  Launchpad constructor. That directory will be used as a cache.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;  &amp;gt;&amp;gt;&amp;gt; cachedir = &amp;#34;/home/me/.launchpadlib/cache/&amp;#34;
  &amp;gt;&amp;gt;&amp;gt; launchpad = Launchpad(credentials, STAGING_SERVICE_ROOT, cachedir)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Without the cache, it takes several seconds just to start up launchpadlib. Every time you create a &lt;code&gt;Launchpad&lt;/code&gt; object, the library has to download information about how Launchpad&lt;br&gt;
works. With the cache in place, launchpadlib will download that information once and reuse it for every &lt;code&gt;Launchpad&lt;/code&gt; object you create. The cache will also store the bugs, people, and other objects you retrieve as you use launchpadlib. The more often you use the same Launchpad objects, the more time the cache will save you. When we change Launchpad, launchpadlib will notice and will download the documents that have changed.&lt;/p&gt;
&lt;p&gt;Second, Edwin Grubbs continued his work on publishing the Launchpad registry. &lt;code&gt;launchpad.projects&lt;/code&gt; is now open for business. You can get basic information about Launchpad projects, their milestones and branches.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;  &amp;gt;&amp;gt;&amp;gt; bzr = launchpad.projects[&amp;#39;bzr&amp;#39;]
  &amp;gt;&amp;gt;&amp;gt; bzr.title
  u&amp;#39;Bazaar Version Control System&amp;#39;
  &amp;gt;&amp;gt;&amp;gt; bzr.programming_language
  u&amp;#39;Python&amp;#39;
  &amp;gt;&amp;gt;&amp;gt; [milestone.name for milestone in bzr.all_milestones]
  [u&amp;#39;0.9a&amp;#39;, u&amp;#39;1.3.1rc1&amp;#39;, u&amp;#39;1.4rc2&amp;#39;, u&amp;#39;1.5&amp;#39;, u&amp;#39;1.6&amp;#39;, ...]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, I&amp;rsquo;ve given launchpadlib some code that uses the client-side cache to avoid the &lt;a href=&#34;http://www.w3.org/1999/04/Editing/&#34;&gt;&amp;ldquo;lost update problem.&amp;rdquo;&lt;/a&gt; This happens when two people modify the same object without coordinating, and the second one unknowingly overwrites the first person&amp;rsquo;s changes. If you use launchpadlib to make a change and it turns out someone else has changed the same object, you&amp;rsquo;ll get a chance to look at the new version of the object and see if your changes are still relevant.&lt;/p&gt;
&lt;p&gt;One thing we haven&amp;rsquo;t done yet is gotten the API HTML reference to be regenerated whenever we change the web service. I planned to work on this yesterday, but instead spent the day fixing bugs. I&amp;rsquo;m working on it now and we should have it up early next week.&lt;/p&gt;
&lt;p&gt;Next week we&amp;rsquo;ll see also more of the Launchpad registry exposed, and some long-awaited aspects of Launchpad&amp;rsquo;s bug tracker. And on Tuesday, Barry Warsaw and I will be talking about Launchpad&amp;rsquo;s web service API as part of &lt;a href=&#34;https://wiki.ubuntu.com/UbuntuDeveloperWeek&#34;&gt;Ubuntu Developer Week&lt;/a&gt;. That&amp;rsquo;s at 1900 UTC, in #ubuntu-classroom on irc.freenode.net.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>This week in Launchpad&#39;s web API</title>
      <link>https://blog.launchpad.net/general/this-week-in-launchpads-web-api-2008-08-15/</link>
      <pubDate>Fri, 15 Aug 2008 21:44:59 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=113</guid>
      <description>&lt;p&gt;Now that the Launchpad web service API has entered beta, I&amp;rsquo;ll be posting an update every week about the improvements we make to it. This way you&amp;rsquo;ll always know what&amp;rsquo;s going on, and you&amp;rsquo;ll see when something you want to do becomes possible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Web service improvements&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This week I made one major change to the web service itself. There&amp;rsquo;s now a special top-level resource that&amp;rsquo;s an alias to &amp;ldquo;you&amp;rdquo; on Launchpad. This is a nice convenience when you&amp;rsquo;re writing scripts for yourself, but it&amp;rsquo;s practically essential if other people are going to be running your program.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how to get a reference to the person who&amp;rsquo;s running the script, using  &lt;a href=&#34;https://www.launchpad.net/launchpadlib&#34;&gt;launchpadlib&lt;/a&gt;, our Python interface to the web service.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; me = launchpad.me
&amp;gt;&amp;gt;&amp;gt; print me.name
leonardr
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you&amp;rsquo;re not using launchpadlib, GET the service root at https://api.staging.launchpad.net/beta/, and you&amp;rsquo;ll see the URL to this resource as &amp;lsquo;me_link&amp;rsquo;. When you GET that URL you&amp;rsquo;ll be redirected to your own user account.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;launchpadlib improvements&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I spent most of my time working on launchpadlib. Apart from some bugfixes and performance improvements that you won&amp;rsquo;t even notice, I made three big improvements.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Introspection&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Previously, to see what capabilities a launchpadlib object had, you had to check the &lt;a href=&#34;http://people.ubuntu.com/~flacoste/launchpad-api-doc.html&#34;&gt;reference documentation&lt;/a&gt;. (That documentation is two weeks out of date, by the way; we&amp;rsquo;ll be fixing that next week.) Now you can just call &lt;code&gt;dir()&lt;/code&gt; on an object, and all of its Launchpad-derived attributes and methods will show up in the list. If you only want to see the Launchpad attributes or methods and not all the internal launchpadlib stuff, you can check &lt;code&gt;lp_attributes&lt;/code&gt; or &lt;code&gt;lp_operations&lt;/code&gt;. This code shows what you can do with a launchpadlib person object:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; me.lp_attributes
[&amp;#39;self_link&amp;#39;, &amp;#39;resource_type_link&amp;#39;, &amp;#39;longitude&amp;#39;, ... &amp;#39;homepage_content&amp;#39;]

&amp;gt;&amp;gt;&amp;gt; me.lp_operations
[&amp;#39;addMember&amp;#39;, ... &amp;#39;setLocation&amp;#39;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Slices&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The second new feature is the ability to slice Launchpad collections as though they were Python lists. Here&amp;rsquo;s some code that gets the 10 most recently filed bugs in Launchpad.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; recent_bugs = launchpad.bugs[:10]
&amp;gt;&amp;gt;&amp;gt; [bug.id for bug in recent_bugs]
[258042, 258041, 258040, 258039, 258038, 258037, 258036, 258033, 258032, 258030]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Previously, the only way to do this was to iterate over launchpad.bugs and insert a break statement when you&amp;rsquo;d had enough, which was very awkward.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loading from bookmarks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The third new feature is the ability to bookmark launchpadlib objects and go back to them later, the way you can bookmark web pages in your browser. Here&amp;rsquo;s launchpadlib code to acquire a bug.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a_bug = launchpad.bugs[251497]
&amp;gt;&amp;gt;&amp;gt; print a_bug.title
Make it possible to instantiate a resource from a URL
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I can play around with that bug all I want within a Python session, but if I exit the Python session the bug will disappear. If I want to get the bug back later, I&amp;rsquo;ll need to find it again from scratch. Unless I store the bug&amp;rsquo;s unique ID (also known as its URL).&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; print str(a_bug)
https://api.staging.launchpad.net/beta/bugs/251497
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At this point I can write that string to a file or database. Later on, a different process might come online and load the string back into memory. That process can get the bug object back by passing the bug&amp;rsquo;s URL into launchpad.load().&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; a_bug = launchpad.load(&amp;#34;https://api.staging.launchpad.net/beta/bugs/251497&amp;#34;)
&amp;gt;&amp;gt;&amp;gt; print a_bug.title
Make it possible to instantiate a resource from a URL
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pretty simple stuff&amp;ndash;people have been saving URLs and passing them around to each other for over fifteen years. The advantage of our web service&amp;rsquo;s design is that it gives you the same power in a scripted environment.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Upcoming work&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Next week I plan to spend most of my time on behind-the-scenes performance improvements. You won&amp;rsquo;t notice anything if you use launchpadlib. If you&amp;rsquo;re writing your own client, you&amp;rsquo;ll know what I&amp;rsquo;m talking about when I say &amp;ldquo;ETag support.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Meanwhile, Edwin Grubbs will be working to expose Launchpad&amp;rsquo;s project registry through the web service.&lt;/p&gt;
&lt;p&gt;See you next week!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Inside the new Launchpad web service API</title>
      <link>https://blog.launchpad.net/cool-new-stuff/inside-the-new-launchpad-web-service-api/</link>
      <pubDate>Sat, 09 Aug 2008 13:01:56 +0000</pubDate>
      <dc:creator>Leonard Richardson</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=110</guid>
      <description>&lt;p&gt;If you&amp;rsquo;ve been wanting to integrate Launchpad into your development tools, or create scripts that read and write Launchpad&amp;rsquo;s dataset, your wait is over. We&amp;rsquo;ve released the initial version of our &lt;a href=&#34;https://help.launchpad.net/API&#34;&gt;RESTful web service API&lt;/a&gt; to the beta testing team. Now you can integrate with Launchpad using &lt;a href=&#34;https://edge.launchpad.net/launchpadlib&#34;&gt;our Python library&lt;/a&gt; or by making simple HTTP requests.&lt;/p&gt;
&lt;p&gt;No longer will you need to screen-scrape or write scripts that pretend to be a web browser; your programs will be able to communicate directly with Launchpad. Our support for &lt;a href=&#34;http://oauth.net/&#34;&gt;OAuth&lt;/a&gt; means your users can delegate a subset of their Launchpad privileges to your program or website, without handing over their Launchpad pasword.&lt;/p&gt;
&lt;p&gt;Right now, the web service provides basic access to Launchpad&amp;rsquo;s people and bugs. We&amp;rsquo;re working now to expose more of Launchpad&amp;rsquo;s data&amp;ndash;projects, milestones, and so on&amp;ndash;and to improve the usability of the Python client. Once we&amp;rsquo;ve stabilized the framework, we&amp;rsquo;ll open up the web service API to everyone. In the meantime, you can try it out by &lt;a href=&#34;https://www.launchpad.net/~launchpad-beta-testers&#34;&gt;joining the Launchpad Beta Testers team&lt;/a&gt;. Once you&amp;rsquo;re on the team, you can get started by visiting &lt;a href=&#34;https://help.launchpad.net/API&#34;&gt;the help homepage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Our Python library, &lt;a href=&#34;https://edge.launchpad.net/launchpadlib&#34;&gt;launchpadlib&lt;/a&gt;, works as a &amp;ldquo;web service browser&amp;rdquo;. You can use it to navigate the web service from a Python script, the way you surf the Launchpad website from your web browser. You don&amp;rsquo;t need any special knowledge of web services to use launchpadlib; you can write natural-looking code like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;   &amp;gt;&amp;gt;&amp;gt; me = launchpad.people[&amp;#39;my-username&amp;#39;]
   &amp;gt;&amp;gt;&amp;gt; me.display_name = &amp;#39;My new display name&amp;#39;
   &amp;gt;&amp;gt;&amp;gt; me.lp_save()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We&amp;rsquo;ll be improving launchpadlib and the web service simultaneously; this is just the beginning.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
