Jubilant, the joyful library for driving Juju
Jubilant is a Python library that wraps the Juju CLI, primarily for use in charm integration tests. It provides methods that map 1:1 to Juju CLI commands, but with a type-annotated, Pythonic interface.
You should consider switching to Jubilant if your integration tests currently use pytest-operator (and they probably do). Jubilant has an API you'll pick up quickly, and it avoids some of the pain points of python-libjuju, such as websocket failures and having to use async. Read our design goals.
Jubilant 1.0.0 was released in April 2025. We'll avoid making breaking changes to the API after this point.
Using Jubilant
Jubilant is published to PyPI, so you can install and use it with your favorite Python package manager:
$ pip install jubilant
# or
$ uv add jubilant
Because Jubilant calls the Juju CLI, you'll also need to install Juju.
To use Jubilant in Python code:
import jubilant
juju = jubilant.Juju()
juju.deploy('snappass-test')
juju.wait(jubilant.all_active)
# Or only wait for specific applications:
juju.wait(lambda status: jubilant.all_active(status, 'snappass-test', 'another-app'))
Below is an example of a charm integration test. First we define a module-scoped pytest fixture named juju which creates a temporary model and runs the test with a Juju instance pointing at that model. Jubilant'stemp_model context manager creates the model during test setup and destroys it during teardown:
# conftest.py
@pytest.fixture(scope='module')
def juju():
with jubilant.temp_model() as juju:
yield juju
# test_deploy.py
def test_deploy(juju: jubilant.Juju): # Use the "juju" fixture
juju.deploy('snappass-test') # Deploy the charm
status = juju.wait(jubilant.all_active) # Wait till the app and unit are 'active'
# Hit the Snappass HTTP endpoint to ensure it's up and running.
address = status.apps['snappass-test'].units['snappass-test/0'].address
response = requests.get(f'http://{address}:5000/', timeout=10)
response.raise_for_status()
assert 'snappass' in response.text.lower()
You don't have to use pytest with Jubilant, but it's what we recommend. Pytest's assert-based approach is a straight-forward way to write tests, and its fixtures are helpful for structuring setup and teardown.
Metadata
Release files for jubilant 1.14.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jubilant-1.14.0.tar.gz | 37.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jubilant-1.14.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 76.7 kB
Release files / jubilant-1.14.0.tar.gz
| Download URL | jubilant-1.14.0.tar.gz |
|---|---|
| Size | 37.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d7fb046c716640ccd39c072dc1471de84cc54d78e331cc18d422ca7a5b72b378
|
|
BLAKE2b-256 checksum How to use checksums |
1df1f9d7581e6bea4ca89bb1c9aca3309629047f3bb0c49ddb0cabe33889d9fd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / jubilant-1.14.0-py3-none-any.whl
| Download URL | jubilant-1.14.0-py3-none-any.whl |
|---|---|
| Size | 39.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2a631fb2363cdd26c0dea52659b5a8946e36f57fec922895521ab59bda6398e8
|
|
BLAKE2b-256 checksum How to use checksums |
23d46effc16acb9fff30603c46270ab58f48c812ba1f567025f22ab5eb96c91a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log