{"id":8250,"library":"juju","title":"Juju Python Library","description":"The `juju` library provides a Pythonic interface for interacting with Juju controllers and models, allowing programmatic control over Juju deployments. As of version 3.6.1.3, the library is not under active development and primarily receives critical bug fixes. Releases are infrequent and typically address specific issues rather than introducing new features.","status":"maintenance","version":"3.6.1.3","language":"en","source_language":"en","source_url":"https://github.com/juju/python-libjuju","tags":["juju","orchestration","cloud","charm","devops","automation"],"install":[{"cmd":"pip install juju","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Used for communication with Juju controller. Specific version ranges required for compatibility.","package":"websockets","optional":false}],"imports":[{"symbol":"Model","correct":"from juju.model import Model"},{"symbol":"Controller","correct":"from juju.controller import Controller"},{"note":"juju.jasyncio.run was deprecated in 3.6.1.0; use juju.loop.run or asyncio.run directly.","wrong":"from juju.jasyncio import run","symbol":"run","correct":"from juju.loop import run"}],"quickstart":{"code":"import asyncio\nimport os\nfrom juju.model import Model\n\nasync def main():\n    model_name = os.environ.get('JUJU_MODEL', 'controller:default') # e.g., 'controller:my-model'\n    \n    model = Model()\n    try:\n        # Connect to a specific Juju model\n        await model.connect(model_name=model_name)\n        print(f\"Connected to Juju model: {model.name}\")\n        \n        # Example: Get applications\n        applications = await model.get_applications()\n        print(f\"Applications in model: {[app.name for app in applications]}\")\n        \n    except Exception as e:\n        print(f\"Error connecting to Juju: {e}\")\n    finally:\n        if model.is_connected:\n            await model.disconnect()\n            print(\"Disconnected from Juju model.\")\n\nif __name__ == '__main__':\n    # Ensure you have a Juju controller running and are logged in (e.g., via 'juju login')\n    # Optionally set JUJU_MODEL environment variable to connect to a specific model\n    asyncio.run(main())\n","lang":"python","description":"This quickstart demonstrates how to connect to a Juju model using the `juju` library and retrieve information about deployed applications. It uses `asyncio` for asynchronous operations, which is the native way to interact with `libjuju`. Ensure you have a Juju controller configured and are logged in via the `juju` CLI."},"warnings":[{"fix":"Upgrade `python-libjuju` to version 3.5.2.1 or newer, or explicitly pin `websockets<14.0,>=8.1` in your project dependencies if you must use an older `libjuju`.","message":"Direct dependency `websockets` version 14.0 breaks `python-libjuju` versions below 3.5.2.1 due to internal API changes and dropped Python 3.8 support.","severity":"breaking","affected_versions":"<3.5.2.1"},{"fix":"Replace imports and calls to `juju.jasyncio.run` with `from juju.loop import run` or `asyncio.run`.","message":"The `juju.jasyncio` module, particularly `juju.jasyncio.run`, was deprecated in favor of `juju.loop.run` or using `asyncio.run` directly.","severity":"deprecated","affected_versions":">=3.6.1.0"},{"fix":"Upgrade to `juju` version 3.6.1.3 or newer to resolve the secret value corruption issue.","message":"A bug in earlier versions incorrectly stripped trailing 'P', 'Q', and '=' characters from secret values when fetched or processed.","severity":"gotcha","affected_versions":"<3.6.1.3"},{"fix":"Consider migrating integration tests to the `jubilant` library as per the official recommendations.","message":"The library is in maintenance mode, receiving only critical bug fixes. For Juju charm integration testing, it's recommended to migrate from `pytest-operator` to `jubilant` for better future compatibility and support.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Upgrade `python-libjuju` to 3.5.2.1 or newer. Alternatively, restrict `websockets` to version `<14.0,>=8.1` in your `requirements.txt`.","cause":"Using `python-libjuju` version older than 3.5.2.1 with `websockets` version 14.0 or higher.","error":"AttributeError: '_WebSocketConnection' object has no attribute 'open' (or similar during connection)"},{"fix":"Update your import statement to `from juju.loop import run` or use `asyncio.run` directly for running async functions.","cause":"Attempting to import `run` from `juju.jasyncio` after it was deprecated and potentially removed or refactored.","error":"ImportError: cannot import name 'run' from 'juju.jasyncio'"},{"fix":"Upgrade `python-libjuju` to version 3.6.1.3 or a later release.","cause":"A bug in `python-libjuju` versions prior to 3.6.1.3 incorrectly stripped certain trailing characters from secret values.","error":"Secret value appears truncated or modified (e.g., ends in 'P', 'Q', or '=')"}]}