| A Python library for Juju |
| ========================= |
| |
| Source code: https://github.com/juju/python-libjuju |
| |
| Bug reports: https://github.com/juju/python-libjuju/issues |
| |
| Documentation: https://pythonlibjuju.readthedocs.io/en/latest/ |
| |
| |
| Requirements |
| ------------ |
| |
| * Python 3.5+ |
| * Juju 2.0+ |
| |
| |
| Design Notes |
| ------------ |
| |
| * Asynchronous - uses asyncio and async/await features of python 3.5 |
| * Websocket-level bindings are programmatically generated (indirectly) from the |
| Juju golang code, ensuring full api coverage |
| * Provides an OO layer which encapsulates much of the websocket api and |
| provides familiar nouns and verbs (e.g. Model.deploy(), Application.add_unit(), |
| etc.) |
| |
| |
| Installation |
| ------------ |
| |
| .. code:: bash |
| |
| pip3 install juju |
| |
| |
| Quickstart |
| ---------- |
| Here's a simple example that shows basic usage of the library. The example |
| connects to the currently active Juju model, deploys a single unit of the |
| ubuntu charm, then exits: |
| |
| |
| .. code:: python |
| |
| #!/usr/bin/python3 |
| |
| import logging |
| import sys |
| |
| from juju import loop |
| from juju.model import Model |
| |
| |
| async def deploy(): |
| # Create a Model instance. We need to connect our Model to a Juju api |
| # server before we can use it. |
| model = Model() |
| |
| # Connect to the currently active Juju model |
| await model.connect_current() |
| |
| try: |
| # Deploy a single unit of the ubuntu charm, using the latest revision |
| # from the stable channel of the Charm Store. |
| ubuntu_app = await model.deploy( |
| 'ubuntu', |
| application_name='ubuntu', |
| series='xenial', |
| channel='stable', |
| ) |
| |
| if '--wait' in sys.argv: |
| # optionally block until the application is ready |
| await model.block_until(lambda: ubuntu_app.status == 'active') |
| finally: |
| # Disconnect from the api server and cleanup. |
| await model.disconnect() |
| |
| |
| def main(): |
| logging.basicConfig(level=logging.INFO) |
| |
| # If you want to see everything sent over the wire, set this to DEBUG. |
| ws_logger = logging.getLogger('websockets.protocol') |
| ws_logger.setLevel(logging.INFO) |
| |
| # Run the deploy coroutine in an asyncio event loop, using a helper |
| # that abstracts loop creation and teardown. |
| loop.run(deploy()) |
| |
| |
| if __name__ == '__main__': |
| main() |
| |
| |
| More examples can be found in the docs, as well as in the ``examples/`` |
| directory of the source tree which can be run using ``tox``. For |
| example, to run ``examples/connect_current_model.py``, use: |
| |
| .. code:: bash |
| |
| tox -e example -- examples/connect_current_model.py |