<a id="using-launchpadlib"></a>

# Using launchpadlib

This document shows how to use a Python client to read and write Launchpad’s
data using the launchpadlib library. It doesn’t cover the HTTP requests and
responses that go back and forth behind the scenes: for that, see the
[“hacking” document](https://ubuntu.com/docs/launchpad/developer/explanation/developing-for-launchpad/index.html.md#developing-the-launchpad-project). This
document also doesn’t cover the full range of what’s possible with Launchpad’s
web service: for that, see the
[web service reference documentation](http://launchpad.net/+apidoc/). Check
out the [API examples page](https://ubuntu.com/docs/launchpad/user/how-to/launchpadlib/python-api/index.html.md#use-the-python-api) if you would like to see
more sample code.

## Installation

### Ubuntu

If you have the latest version of Ubuntu, you can install launchpadlib from
the Ubuntu repositories using apt-get:

```default
sudo apt-get install python3-launchpadlib
```

If you have an older version of Ubuntu, some parts of the instructions below may
not work with the version from the repositories. However, you should be able to
install the latest version of launchpadlib manually.

### pip

On any platform with Python and pip, you can install launchpadlib
using the pip command:

```default
pip install launchpadlib
```

## Getting started

The first step towards using Launchpad’s web service is to choose a cache
directory. The documents you retrieve from Launchpad will be stored here, which
will save you a lot of time. Run this code in a Python session, substituting an
appropriate directory on your computer:

```default
cachedir = "/home/me/.launchpadlib/cache/"
```

The next step is to set up credentials for your client. For quick read-only
access to Launchpad data, you can get anonymous access.  Otherwise, you’ll need
to authenticate with Launchpad using OAuth.

### Anonymous access

#### NOTE
`login_anonymously()` is only available with launchpadlib version 1.5.4 or higher

The `Launchpad.login_anonymously()` method gives you automatic read-only
access to public Launchpad data.

```default
from launchpadlib.launchpad import Launchpad
launchpad = Launchpad.login_anonymously('just testing', 'production', cachedir, version='devel')
```

- `Launchpad.login_anonymously()` is a string that  identifies the web
  service client. We use this string to gauge client  popularity and detect
  buggy or inefficient clients. Here, though, we’re just  testing.
- The second argument tells launchpadlib which Launchpad instance to run against.
  Here, we’re using `production`, which is mapped to the web service root on the
  production Launchpad server: [https://api.launchpad.net/](https://api.launchpad.net/). Anonymous access
  cannot change the Launchpad dataset, so there’s no concern about a bad test
  program accidentally overwriting data. (If you want to play it safe, you could
  use ‘staging’ instead - though staging is sometimes down for extended periods.)
- `version` specifies the API version to use. For historical
  reasons the default is `'1.0'`, and you may want to use this in certain
  circumstances, but in most cases you should use `'devel'` so that you
  get a reasonably complete and current interface.
- The `login_anonymously()` method automatically negotiates a read-only
  credential with Launchpad. You can use your `Launchpad` object right away.

```default
bug_one = launchpad.bugs[1]
print(bug_one.title)
# Microsoft has a majority market share
```

You’ll get an error if you try to modify the dataset, access private
data, or access objects like `launchpad.me` which assume a particular
user is logged in.

Note that `login_anonymously()` is only available in launchpadlib
starting in version 1.5.4.

### Authenticated access

To get read-write access to Launchpad, or to see a user’s private data, you’ll
need to get an OAuth credential for that user. If you’re writing an application
need to get an OAuth credential for that user. If you’re writing an application
that the user will run on their own computer, just call the
`Launchpad.login_with()` method.

This method takes two important arguments: the name of your application, and
the name of the Launchpad server you want to run against.

```default
from launchpadlib.launchpad import Launchpad
launchpad = Launchpad.login_with('My Application', 'staging', version='devel')
```

The default server name is ‘staging’, so that you don’t destroy data by
accident while developing. When you do a release, you can change this to
‘production’.

*If this code complains that ‘staging’ isn’t a URL, then you’re not running the
most up-to-date launchpadlib. You can replace ‘staging’ with
\`\`launchpadlib.launchpad.STAGING_SERVICE_ROOT\`\` to make it work in Ubuntu
9.10’s launchpadlib.*
.. note::
If this code complains that ‘staging’ isn’t a URL, it means you’re not running
a recent version of launchpadlib. To make it work in Ubuntu 9.10’s
launchpadlib, replace ‘staging’ with `launchpadlib.launchpad.STAGING_SERVICE_ROOT`.
If you have an existing desktop-wide Launchpad credential, launchpadlib will
find it and use it. If there’s no existing desktop credential (because you’ve
never used a launchpadlib application on this computer, or because you had a
If you have an existing desktop-wide Launchpad credential, launchpadlib will
find it and use it. If there’s no existing desktop credential, launchpadlib will
guide you through authorizing a new
credential, as seen in [Application integration](https://ubuntu.com/docs/launchpad/user/how-to/account-management/application-integration/index.html.md#application-integration).

For `login_with()`, you can also pass in a callback function as
`credential_save_failed`. That function will be invoked if a desktop
credential can’t be created - either because the end-user refused to perform
the authorization, or because there was a problem storing the credential after
authorization.

```default
import sys
from launchpadlib.launchpad import Launchpad

def no_credential():
    print("Can't proceed without Launchpad credential.")
sys.exit()

launchpad = Launchpad.login_with(
    'My Application', 'staging', credential_save_failed=no_credential, version='devel')
```
