---
title: Charmhub | Deploy Observability Libs using Charmhub - The Open Operator Collection
description: Deploy the latest version of Observability Libs as a Kubernetes Operator
  on any cloud.
url: https://charmhub.io/observability-libs/libraries/juju_topology
---

# Observability Libs

[Jon Seager](https://charmhub.io/publisher/jnsgruk "View all packages from Jon Seager")

* [Jon Seager](https://charmhub.io/publisher/jnsgruk "View all packages from Jon Seager")

Platform:

edge 454c1f8

```
juju deploy observability-libs --channel edge
```

[Learn to deploy on juju >](https://juju.is/docs/juju/manage-applications)

[Toggle side navigation](https://charmhub.io/observability-libs/libraries/juju_topology#drawer)

## charms.observability\_libs.v0.juju\_topology

* [*Docstrings*Docstrings](https://charmhub.io/observability-libs/libraries/juju_topology)
  [*Code*Source code](https://charmhub.io/observability-libs/libraries/juju_topology/source-code)
* + Download

    Fetch library

    ```
    charmcraft fetch-lib charms.observability_libs.v0.juju_topology
    ```

    [Download juju\_topology.py](https://charmhub.io/observability-libs/libraries/juju_topology/download)
  + *Last updated* 14 Jul 2025
  + *Revision* Library version 0.7

##### Overview.

This document explains how to use the `JujuTopology` class to
create and consume topology information from Juju in a consistent manner.

The goal of the Juju topology is to uniquely identify a piece
of software running across any of your Juju-managed deployments.
This is achieved by combining the following four elements:

* Model name
* Model UUID
* Application name
* Unit identifier

For a more in-depth description of the concept, as well as a
walk-through of it's use-case in observability, see
[this blog post](https://juju.is/blog/model-driven-observability-part-2-juju-topology-metrics)
on the Juju blog.

##### Library Usage

This library may be used to create and consume `JujuTopology` objects.
The `JujuTopology` class provides three ways to create instances:

###### Using the `from_charm` method

Enables instantiation by supplying the charm as an argument. When
creating topology objects for the current charm, this is the recommended
approach.

```
topology = JujuTopology.from_charm(self)
```

###### Using the `from_dict` method

Allows for instantion using a dictionary of relation data, like the
`scrape_metadata` from Prometheus or the labels of an alert rule. When
creating topology objects for remote charms, this is the recommended
approach.

```
scrape_metadata = json.loads(relation.data[relation.app].get("scrape_metadata", "{}"))
topology = JujuTopology.from_dict(scrape_metadata)
```

###### Using the class constructor

Enables instantiation using whatever values you want. While this
is useful in some very specific cases, this is almost certainly not
what you are looking for as setting these values manually may
result in observability metrics which do not uniquely identify a
charm in order to provide accurate usage reporting, alerting,
horizontal scaling, or other use cases.

```
topology = JujuTopology(
    model="some-juju-model",
    model_uuid="00000000-0000-0000-0000-000000000001",
    application="fancy-juju-application",
    unit="fancy-juju-application/0",
    charm_name="fancy-juju-application-k8s",
)
```

---

Index

* [class InvalidUUIDError](https://charmhub.io/observability-libs/libraries/juju_topology#invaliduuiderror)
* + [def \_\_init\_\_(
    self,
    uuid)](https://charmhub.io/observability-libs/libraries/juju_topology#invaliduuiderror-__init__)
* [class JujuTopology](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology)
* + [def \_\_init\_\_(
    self,
    model,
    model\_uuid,
    application,
    unit,
    charm\_name)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-__init__)
* + [def is\_valid\_uuid(
    self,
    uuid)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-is_valid_uuid)
* + [def from\_charm(
    cls,
    charm)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-from_charm)
* + [def from\_dict(
    cls,
    data)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-from_dict)
* + [def as\_dict(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-as_dict)
* + [def identifier(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-identifier)
* + [def label\_matcher\_dict(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-label_matcher_dict)
* + [def label\_matchers(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-label_matchers)
* + [def model(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-model)
* + [def model\_uuid(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-model_uuid)
* + [def model\_uuid\_short(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-model_uuid_short)
* + [def application(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-application)
* + [def charm\_name(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-charm_name)
* + [def unit(
    self)](https://charmhub.io/observability-libs/libraries/juju_topology#jujutopology-unit)

#### class InvalidUUIDError

Description

Invalid UUID was provided. None

Methods

InvalidUUIDError.
\_\_init\_\_(

*self*

,
uuid: str
)

#### class JujuTopology

JujuTopology is used for storing, generating and formatting juju topology information.

Description

DEPRECATED: This class is deprecated. Use `pip install cosl` and
`from cosl.juju_topology import JujuTopology` instead.

Methods

JujuTopology.
\_\_init\_\_(

*self*

,
model: str

,
model\_uuid: str

,
application: str

,
unit

,
charm\_name
)

Build a JujuTopology object.

Arguments

model

a string name of the Juju model

model\_uuid

a globally unique string identifier for the Juju model

application

an application name as a string

unit

a unit name as a string

charm\_name

name of charm as a string

Description

A `JujuTopology` object is used for storing and transforming
Juju topology information. This information is used to
annotate Prometheus scrape jobs and alert rules. Such
annotation when applied to scrape jobs helps in identifying
the source of the scrapped metrics. On the other hand when
applied to alert rules topology information ensures that
evaluation of alert expressions is restricted to the source
(charm) from which the alert rules were obtained.

JujuTopology.
is\_valid\_uuid(

*self*

,
uuid
)

Validate the supplied UUID against the Juju Model UUID pattern.

Arguments

uuid

string that needs to be checked if it is valid v4 UUID.

Returns

True if parameter is a valid v4 UUID, False otherwise.

JujuTopology.
from\_charm(

cls

,
charm
)

Creates a JujuTopology instance by using the model data available on a charm object.

Arguments

charm

a `CharmBase` object for which the `JujuTopology` will be constructed

Returns

a `JujuTopology` object.

JujuTopology.
from\_dict(

cls

,
data: dict
)

Factory method for creating `JujuTopology` children from a dictionary.

Arguments

data

a dictionary with five keys providing topology information. The keys are

* "model"
* "model\_uuid"
* "application"
* "unit"
* "charm\_name"
  `unit` and `charm_name` may be empty, but will result in more limited
  labels. However, this allows us to support charms without workloads.

Returns

a `JujuTopology` object.

JujuTopology.
as\_dict(

*self*
)

Format the topology information into an ordered dict.

Arguments

remapped\_keys

A dictionary mapping old key names to new key names,
which will be substituted when invoked.

excluded\_keys

A list of key names to exclude from the returned dict.

uuid\_length

The length to crop the UUID to.

Description

Keeping the dictionary ordered is important to be able to
compare dicts without having to resort to deep comparisons.

JujuTopology.
identifier(

*self*
)

Format the topology information into a terse string.

Description

This crops the model UUID, making it unsuitable for comparisons against
anything but other identifiers. Mainly to be used as a display name or file
name where long strings might become an issue.

> > > JujuTopology( model = "a-model", model\_uuid = "00000000-0000-4000-8000-000000000000", application = "some-app", unit = "some-app/1" ).identifier
> > > 'a-model\_00000000\_some-app'

JujuTopology.
label\_matcher\_dict(

*self*
)

Format the topology information into a dict with keys having 'juju\_' as prefix.

Description

Relabelled topology never includes the unit as it would then only match
the leader unit (ie. the unit that produced the dict).

JujuTopology.
label\_matchers(

*self*
)

Format the topology information into a promql/logql label matcher string.

Description

Topology label matchers should never include the unit as it
would then only match the leader unit (ie. the unit that
produced the matchers).

JujuTopology.
model(

*self*
)

Description

Getter for the juju model value. None

JujuTopology.
model\_uuid(

*self*
)

Description

Getter for the juju model uuid value. None

JujuTopology.
model\_uuid\_short(

*self*
)

Description

Getter for the juju model value, truncated to the first eight letters. None

JujuTopology.
application(

*self*
)

Description

Getter for the juju application value. None

JujuTopology.
charm\_name(

*self*
)

Description

Getter for the juju charm name value. None

JujuTopology.
unit(

*self*
)

Description

Getter for the juju unit value. None
