= Introduction = Natty now has a new version of launchpadlib, 1.9.3. The goal of the new version is to save your users trouble and to bring launchpadlib's security up to the standards of the rest of Ubuntu. Depending on how you've been using launchpadlib, you may need to make some changes to your scripts and applications. This email describes the new version and explains what kind of changes you might need to make. I've already contacted every developer who has launchpadlib code in Ubuntu, and done a little audit of their code for them. This message is for personal scripts and for applications you've written that aren't in Ubuntu. If you want to test out launchpadlib in Natty, you may need to manually install python-keyring, until bug 724327 is fixed. Please let me know if you have any questions or if this email is unclear.To see how the new version looks from the end-user's perspective, see this wiki page:
https://help.launchpad.net/API/ThirdPartyIntegration = Detailed list of changes = 1. The edge server is deprecated. You may have seen this blog post from November 2010: http://blog.launchpad.net/general/edge-is-deprecated In launchpadlib 1.9.3, if you try to use the 'edge' Launchpad instance, you'll get a deprecation warning and launchpadlib will actually use the 'production' instance. Instead of launchpadlib.launchpad.STAGING_SERVICE_ROOT and launchpadlib.launchpad.EDGE_SERVICE_ROOT, use the literal strings 'staging' and 'production'. Or, if you like importing constants, use launchpadlib.uris.STAGING_SERVICE_ROOT and launchpadlib.uris.LPNET_SERVICE_ROOT. If you're using the literal string 'edge' to designate the edge server, use 'production' instead. 2. Make sure you explicitly specify a Launchpad instance. This shouldn't affect anyone, but I want to make sure. This code will still work in 1.9.3: >>> Launchpad.login_with("my-app") It will run your code against the staging instance, which means that your changes won't be saved. You probably don't use this except for testing, which is why I don't think this will affect anyone. In the near future, I'll probably be changing Launchpad so that there is no default Launchpad instance. (See https://bugs.launchpad.net/launchpadlib/+bug/714043.) The code given above will fail, and you'll need to explicitly specify a Launchpad instance to use: >>> Launchpad.login_with("my-app", "production") >>> Launchpad.login_with("my-app", "staging") >>> Launchpad.login_with("my-app", "...") So, as long as you're looking through your code, make this change if necessary. 3. For interactive applications, integration is desktop-wide. In Maverick, each application that used launchpadlib had to get its own Launchpad credential, by launching a web browser and having the end-user authenticate with Launchpad. This was annoying to the end-user and was pretty useless from a security standpoint. In Natty, the end-user has a single desktop-wide credential which is shared by all applications. The web browser is still launched, but it's only launched _once_, for all interactive applications (see #5 for non-interactive applications). Unless your application is the very first one someone uses after upgrading to Natty, they won't get a browser open. In terms of your code, I suggest you replace calls to Launchpad() and Launchpad.get_token_and_login() with calls to Launchpad.login_with(). If you've got some custom code to store an app-specific credential, you can get rid of it. Launchpad.get_token_and_login() has been deprecated. Launchpad() is still around, but the order of arguments has been changed slightly, so if you're using it you should at least switch to using keyword arguments. The allow_access_levels argument to login_with() is still accepted, but it doesn't do anything for interactive applications. 4. For interactive applications, the credential is stored in the GNOME keyring In Maverick, credentials were stored unencrypted in files on disk. In Natty, credentials are stored in the GNOME keyring or KDE wallet. If neither is present, credentials are stored in an encrypted file in the user's home directory. (This is managed by the python-keyring library.) This is where I anticipate problems. Adding a GUI element makes everything more complicated. For instance, if you SSH into a machine where GNOME keyring is running and try to use a launchpadlib script, you'll get an error if you haven't run this command: export `gnome-keyring-daemon` (I've put that into my .bashrc.) It's possible we'll also run into problems with chroots, screen sessions, and other power-user setups. Let's find these problems now. 5. For non-interactive applications, credentials are stored in an unencrypted file By "non-interactive applications" I generally mean applications that run as cronjobs. For these applications, the keyring solution won't work, because no one is around to unlock the keyring. You need to keep the credentials in an unencrypted file. This syntax (which you may have seen before) will do what you want: >>> Launchpad.login_with("my-app", "production", ... credentials_file="/path/to/file") If /path/to/file doesn't exist, you'll get a browser open and be asked to authorize an application-specific credential, just like in Maverick. The credential will be written to /path/to/file, and on subsequent runs you won't get a browser open because the credential will be read from disk. Because of this, if you're running an application as a cronjob, you should either run it manually first to get the credential, or you should generate the credential on another computer and copy the file over to the sever that's running the cronjob. The allow_access_levels argument to login_with() doesn't do anything for interactive applications, but it works as before for non-interactive applications. 6. Credentials may expire Although the credential is used across the desktop, it may not be permanent. The end-user has the choice to try out integration before allowing it permanently. This means that your application may start up with an active credential, but that it may expire after a while. If a credential expires, launchpadlib will launch the end-user's browser again and ask them to authorize a new credential. This will not directly affect your code, but if you're writing an application for other people to use, you should know that in rare cases, your launchpadlib token might expire, causing control to shift to the user's browser. If your user refuses to grant you a new token, you just won't be able to use launchpadlib anymore. This isn't technically new: the end-user always had the ability to manually revoke your access token, and in Maverick, if they did that, launchpadlib would simply crash. But it's a lot more prominent now, because at least some users will choose to try out desktop integration before making it permanent. = Summary of changes = 1. Use 'production' instead of 'edge'. 2. Explicitly specify an instance to use, if you're not doing so already. 3. get_token_and_login is deprecated: use login_with() instead 4. Use login_with() instead of the Launchpad constructor. 5. If your script is not intended for interactive use, pass in a credentials_file argument to login_with() to avoid the keyring. 6. Code defensively: just because you have a valid credential when you start using launchpadlib doesn't mean you'll have one forever. Leonard
This is the launchpad-users mailing list archive — see also the general help for Launchpad.net mailing lists.
(Formatted by MHonArc.)