===================== How to Use lp-shell ===================== lp-shell is a CLI tool in the form of an interactive Python API client, providing connection to Launchpad through the Launchpad API for developers and users in a quick and easy way. It is especially useful for providing support to users, as well as to automate and fasten various Launchpad tasks and it is practically necessary for some features that do not provide a UI alternative, especially when they are early in their life-cycle. Installation ------------ The way to install lp-shell is pretty straight forward. Only package needed is “lptools”: .. code-block:: shell-session $ sudo apt install lptools “lp-shell” resides in lptools, so this is all we need to connect to Launchpad. [Optional, Recommended] Install IPython _______________________________________ If we enter the lp-shell now, we will see that it is a python interpreter environment. As a result, we can ease its use with some classic python tools like IPython. This will provide command history, auto-fill and easier exploration when inside the lp-shell. .. code-block:: shell-session $ sudo apt install ipython3 How to Connect -------------- After installation, we can enter into lp-shell using: .. code-block:: shell-session $ lp-shell Thus, we are in, and free to do whatever we want as long as we have the permissions. .. note:: When it is your first time entering into lp-shell, depending on whether you authorized your computer previously on Launchpad for other tasks or not, it may ask for an authorization which should promptly and automatically open a Browser tab for it. If it doesn't login automatically, we can use “lp.login_with()” method to manually trigger the authorization. Once done, the launchpad will cache the authorization information for future use. All the resources open to API can be found in the `API Documentation `_. Other Options _____________ The simple ``$ lp-shell`` command implicitly defaults two options: the environment to connect as ``production`` and the version/branch of the API as ``devel``. Thus we can denote the initial command as: .. code-block:: shell-session $ lp-shell production devel Alternatively, we have other options in regards to what environment we connect to and the version of API as well. The options for environment follow the development environments of Launchpad: ``staging`` and ``qastaging``. So, we can instead use: .. code-block:: shell-session $ lp-shell staging Or .. code-block:: shell-session $ lp-shell qastaging Alternatively, we can also connect to local development/test environments on our personal systems with ``dev``. However, this requires the deactivation of SSL certification checks on lp-shell which is done through the environment variable ``LP_DISABLE_SSL_CERTIFICATE_VALIDATION`` to ``True``, either by setting the variable throughout the development environment or in the command itself with: .. code-block:: shell-session $ LP_DISABLE_SSL_CERTIFICATE_VALIDATION=True lp-shell dev In contrast, the second set of options we have, i.e. which API version/branch we connect to is less crippling since we only support the use of ``devel`` as the remaining options which are ``1.0`` and ``beta`` are currently deprecated and not in use. Inside of lp-shell ------------------ Special object: “``lp``” ________________________ lp-shell provides a built-in, out-of-the-box object to connect to Launchpad called “lp”. It is the main Launchpad object we use as a base for all further operations within the shell. .. code-block:: text In [1]: lp Out[1]: Special object: “``lp.me``” ___________________________ Another built-in object, residing in “lp". As a shortcut, it stores the user's own account Person object. Making it easier to acquire the user account or use it on other parts of the API. .. code-block:: text In [1]: lp.me Out[1]: Special method: “``lp.load()``” _______________________________ lp.load() accepts a URL as its parameter. It accepts both absolute and relative paths. But we recommend the use of relative paths, that come after “launchpad.net/”, as the absolute paths the API accepts are easy to mess, with no discernible difference from relative path approach even when done correctly. When the method is triggered, it returns an object that represents whatever object is stored in that URL. .. code-block:: text In [1]: lp.load('ubuntu') Out[1]: In [2]: lp.load('launchpad/+bug/102455') Out[2]: In [3]: lp.load('~launchpad') Out[3]: Special collections: ____________________ There are also special look-up sets reachable from the ``lp`` object. These let us access entries that we know about easily. They are: .. code-block:: text # Get a distribution by its name In [1]: lp.distributions["ubuntu"] Out[1]: # Get a project by its name In [2]: lp.projects["launchpad"] Out[2]: # Get a bug by its ID In [3]: lp.bugs[1] Out[3]: # Get a user by their name In [4]: lp.people["[a_user_name]"] Out[4]: # Or get a team by their name In [5]: lp.people["launchpad"] Out[5]: How to navigate lp-shell ------------------------ While there are multiple ways to navigate and explore around lp-shell some of the most useful are: Using ``dir(object)`` _____________________ This is a standard python way to check the properties and the methods of objects, and is especially useful if we are unsure of what can we do or see with any given Launchpad object. As a result, it will also show us the other exploration paths we can take. .. code-block:: text In [1]: dir(lp) Out[1]: [...] In [2]:dir(lp.me) Out[2]: [...] Using Special LP Object Entries _______________________________ In the resultant list, we can find some of the more readily useful exploration tools/attributes that every object on lp-shell have: - lp_attributes: Name this resource's scalar attributes. - lp_collections: Name the collections this resource links to.. - lp_entries: Name the entries this resource links to. - lp_operations: Name all of this resource's custom operations. .. note:: These will return property lists of the original object. If we wish to reach into one of the elements of these lists, we must call it on the object that we called the above lists from. .. code-block:: text In [1]: project = lp.load("lpci") In [2]: project.lp_attributes Out[2]: [ … 'reviewer_whiteboard', 'screenshots_url', 'sourceforge_project', 'specification_sharing_policy', 'summary', 'title', 'translationpermission', 'translations_usage', … ] In [3]: project.summary Out[3]: 'Runner for Launchpad CI jobs.' Saving changes ______________ If we make any changes to the entries of Launchpad, it is best to save them manually using lp_save() .. code-block:: text In [1]: lp.me.lp_save() [Optional] IPython commands to know ___________________________________ If you decide to use lp-shell with IPython (which is recommended). Some IPython commands that will be immensely useful are: .. code-block:: text In [1]: object? Details about the object. The name, parameters and the docstring. .. note:: Methods, callables to be specific, need to be called without their parentheses. For example: lp?, lp.me?, lp.me.lp_save? .. code-block:: text In [1]: object?? Verbose details about the object. Includes the code as well. For example: lp??, lp.me??, lp.me.lp_save?? .. code-block:: text In [1]: ? Introduction and overview of IPython features. .. code-block:: text In [1]: %quickref Quick Reference Card of IPython.