---
title: "Charmhub | Deploy Traefik Ingress Operator for Kubernetes\n using Charmhub\
  \ - The Open Operator Collection"
description: "Deploy the latest version of Traefik Ingress Operator for Kubernetes\n\
  \ as a Kubernetes Operator on any cloud."
url: https://charmhub.io/traefik-k8s/libraries/ingress_per_unit
---

# Traefik Ingress Operator for Kubernetes

[Canonical IS DevOps](https://charmhub.io/publisher/canonical-is-devops "View all packages from Canonical IS DevOps")

* [Canonical IS DevOps](https://charmhub.io/publisher/canonical-is-devops "View all packages from Canonical IS DevOps")

Platform:

stable 32bad7a

```
juju deploy traefik-k8s
```

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

[Toggle side navigation](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#drawer)

## charms.traefik\_k8s.v1.ingress\_per\_unit

* [*Docstrings*Docstrings](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit)
  [*Code*Source code](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit/source-code)
* + Download

    Fetch library

    ```
    charmcraft fetch-lib charms.traefik_k8s.v1.ingress_per_unit
    ```

    [Download ingress\_per\_unit.py](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit/download)
  + *Last updated* 26 Feb 2026
  + *Revision* Library version 1.23

#### Interface Library for ingress\_per\_unit.

This library wraps relation endpoints using the `ingress_per_unit` interface
and provides a Python API for both requesting and providing per-unit
ingress.

##### Getting Started

To get started using the library, you just need to fetch the library using `charmcraft`.

```
charmcraft fetch-lib charms.traefik_k8s.v1.ingress_per_unit
```

Add the `jsonschema` dependency to the `requirements.txt` of your charm.

```
requires:
    ingress:
        interface: ingress_per_unit
        limit: 1
```

Then, to initialise the library:

```
from charms.traefik_k8s.v1.ingress_per_unit import (IngressPerUnitRequirer,
  IngressPerUnitReadyForUnitEvent, IngressPerUnitRevokedForUnitEvent)

class SomeCharm(CharmBase):
  def __init__(self, *args):
    # ...
    self.ingress_per_unit = IngressPerUnitRequirer(self, port=80)
    # The following event is triggered when the ingress URL to be used
    # by this unit of `SomeCharm` is ready (or changes).
    self.framework.observe(
        self.ingress_per_unit.on.ready_for_unit, self._on_ingress_ready
    )
    self.framework.observe(
        self.ingress_per_unit.on.revoked_for_unit, self._on_ingress_revoked
    )

    def _on_ingress_ready(self, event: IngressPerUnitReadyForUnitEvent):
        # event.url is the same as self.ingress_per_unit.url
        logger.info("This unit's ingress URL: %s", event.url)

    def _on_ingress_revoked(self, event: IngressPerUnitRevokedForUnitEvent):
        logger.info("This unit no longer has ingress")
```

If you wish to be notified also (or instead) when another unit's ingress changes
(e.g. if you're the leader and you're doing things with your peers' ingress),
you can pass `listen_to = "all-units" | "both"` to `IngressPerUnitRequirer`
and observe `self.ingress_per_unit.on.ready` and `self.ingress_per_unit.on.revoked`.

---

Index

* [class DataValidationError](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#datavalidationerror)
* [class RelationException](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#relationexception)
* + [def \_\_init\_\_(
    self,
    relation,
    entity)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#relationexception-__init__)
* [class RelationDataMismatchError](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#relationdatamismatcherror)
* [class RelationPermissionError](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#relationpermissionerror)
* + [def \_\_init\_\_(
    self,
    relation,
    entity,
    message)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#relationpermissionerror-__init__)
* [class IngressDataReadyEvent](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressdatareadyevent)
* [class IngressDataRemovedEvent](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressdataremovedevent)
* [class IngressEndpointsUpdatedEvent](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressendpointsupdatedevent)
* [class IngressPerUnitProviderEvents](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitproviderevents)
* [class IngressPerUnitProvider](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitprovider)
* + [def is\_ready(
    self,
    relation)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitprovider-is_ready)
* + [def validate(
    self,
    relation)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitprovider-validate)
* + [def is\_unit\_ready(
    self,
    relation,
    unit)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitprovider-is_unit_ready)
* + [def get\_data(
    self,
    relation,
    unit)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitprovider-get_data)
* + [def publish\_url(
    self,
    relation,
    unit\_name,
    url)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitprovider-publish_url)
* + [def wipe\_ingress\_data(
    self,
    relation)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitprovider-wipe_ingress_data)
* + [def proxied\_endpoints(
    self)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitprovider-proxied_endpoints)
* [class IngressPerUnitReadyEvent](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitreadyevent)
* [class IngressPerUnitReadyForUnitEvent](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitreadyforunitevent)
* [class IngressPerUnitRevokedEvent](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrevokedevent)
* [class IngressPerUnitRevokedForUnitEvent](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrevokedforunitevent)
* [class IngressPerUnitRequirerEvents](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrequirerevents)
* [class IngressPerUnitRequirer](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrequirer)
* + [def \_\_init\_\_(
    self,
    charm,
    relation\_name)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrequirer-__init__)
* + [def relation(
    self)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrequirer-relation)
* + [def is\_ready(
    self)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrequirer-is_ready)
* + [def provide\_ingress\_requirements(
    self)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrequirer-provide_ingress_requirements)
* + [def urls(
    self)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrequirer-urls)
* + [def url(
    self)](https://charmhub.io/traefik-k8s/libraries/ingress_per_unit#ingressperunitrequirer-url)

#### class DataValidationError

Description

Raised when data validation fails on IPU relation data. None

#### class RelationException

Base class for relation exceptions from this library.

Attributes

relation

The Relation which caused the exception.

entity

The Application or Unit which caused the exception.

Methods

RelationException.
\_\_init\_\_(

*self*

,
relation: Relation

,
entity
)

Initialize the relation exception base class.

Arguments

relation

Relation instance.

entity

Application and Unit.

#### class RelationDataMismatchError

Description

Data from different units do not match where they should. None

#### class RelationPermissionError

Description

Ingress is requested to do something for which it lacks permissions. None

Methods

RelationPermissionError.
\_\_init\_\_(

*self*

,
relation: Relation

,
entity

,
message: str
)

Initialize the exception.

Arguments

relation

Relation instance.

entity

Application and Unit.

message

Exception message.

#### class IngressDataReadyEvent

Event triggered when the requirer has provided valid ingress data.

Description

Also emitted when the data has changed.
If you receive this, you should handle it as if the data being
provided was new.

#### class IngressDataRemovedEvent

Event triggered when a requirer has wiped its ingress data.

Description

Also emitted when the requirer data has become incomplete or invalid.
If you receive this, you should handle it as if the remote unit no longer
wishes to receive ingress.

#### class IngressEndpointsUpdatedEvent

Description

Event triggered when the proxied endpoints change. None

#### class IngressPerUnitProviderEvents

Description

Container for events for IngressPerUnit. None

#### class IngressPerUnitProvider

Description

Implementation of the provider of ingress\_per\_unit. None

Methods

IngressPerUnitProvider.
is\_ready(

*self*

,
relation
)

Checks whether the given relation is ready.

Description

Or any relation if not specified.
A given relation is ready if SOME remote side has sent valid data.

IngressPerUnitProvider.
validate(

*self*

,
relation: Relation
)

Checks whether the given relation is failed.

Description

Or any relation if not specified.

IngressPerUnitProvider.
is\_unit\_ready(

*self*

,
relation: Relation

,
unit: Unit
)

Description

Report whether the given unit has shared data in its unit data bag. None

IngressPerUnitProvider.
get\_data(

*self*

,
relation: Relation

,
unit: Unit
)

Description

Fetch the data shared by the specified unit on the relation (Requirer side). None

IngressPerUnitProvider.
publish\_url(

*self*

,
relation: Relation

,
unit\_name: str

,
url: str
)

Place the ingress url in the application data bag for the units on the requirer side.

Description

Assumes that this unit is leader.

IngressPerUnitProvider.
wipe\_ingress\_data(

*self*

,
relation: Relation
)

Remove all published ingress data.

Description

Assumes that this unit is leader.

IngressPerUnitProvider.
proxied\_endpoints(

*self*
)

The ingress settings provided to units by this provider.

Description

For example, when this IngressPerUnitProvider has provided the
`http://foo.bar/my-model.my-app-1` and
`http://foo.bar/my-model.my-app-2` URLs to the two units of the
my-app application, the returned dictionary will be:

```
{
    "my-app/1": {
        "url": "http://foo.bar/my-model.my-app-1"
    },
    "my-app/2": {
        "url": "http://foo.bar/my-model.my-app-2"
    }
}
```

#### class IngressPerUnitReadyEvent

Ingress is ready (or has changed) for some unit.

Description

Attrs:
`unit_name`: name of the unit for which ingress has been
provided/has changed.
`url`: the (new) url for that unit.

#### class IngressPerUnitReadyForUnitEvent

Ingress is ready (or has changed) for this unit.

Description

Is only fired on the unit(s) for which ingress has been provided or
has changed.
Attrs:
`url`: the (new) url for this unit.

#### class IngressPerUnitRevokedEvent

Ingress is revoked (or has changed) for some unit.

Description

Attrs:
`unit_name`: the name of the unit whose ingress has been revoked.
this could be "THIS" unit, or a peer.

#### class IngressPerUnitRevokedForUnitEvent

Ingress is revoked (or has changed) for this unit.

Description

Is only fired on the unit(s) for which ingress has changed.

#### class IngressPerUnitRequirerEvents

Description

Container for IUP events. None

#### class IngressPerUnitRequirer

Description

Implementation of the requirer of ingress\_per\_unit. None

Methods

IngressPerUnitRequirer.
\_\_init\_\_(

*self*

,
charm: CharmBase

,
relation\_name: str
)

Constructor for IngressPerUnitRequirer.

Arguments

charm

the charm that is instantiating the library.

relation\_name

the name of the relation name to bind to
(defaults to "ingress-per-unit"; relation must be of interface
type "ingress\_per\_unit" and have "limit: 1").

host

Hostname to be used by the ingress provider to address the
requirer unit; if unspecified, the FQDN of the unit will be
used instead.

port

port to be used by the ingress provider to address the
requirer unit.

mode

mode to be used between "tcp" and "http".

listen\_to

Choose which events should be fired on this unit:
"only-this-unit": this unit will only be notified when ingress
is ready/revoked for this unit.
"all-units": this unit will be notified when ingress is
ready/revoked for any unit of this application, including
itself.
"all": this unit will receive both event types (which means it
will be notified *twice* of changes to this unit's ingress!).

strip\_prefix

remove prefixes from the URL path.

redirect\_https

redirect incoming requests to HTTPS

scheme

callable returning the scheme to use when constructing the ingress url.

Description

The request args can be used to specify the ingress properties when the
instance is created. If any are set, at least `port` is required, and
they will be sent to the ingress provider as soon as it is available.
All request args must be given as keyword args.

IngressPerUnitRequirer.
relation(

*self*
)

Description

The established Relation instance, or None if still unrelated. None

IngressPerUnitRequirer.
is\_ready(

*self*
)

Checks whether the given relation is ready.

Description

Or any relation if not specified.
A given relation is ready if the remote side has sent valid data.

IngressPerUnitRequirer.
provide\_ingress\_requirements(

*self*
)

Publishes the data that Traefik needs to provide ingress.

Arguments

scheme

Scheme to be used; if unspecified, use the one used by **init**.

host

Hostname to be used by the ingress provider to address the
requirer unit; if unspecified, FQDN will be used instead

port

the port of the service (required)

IngressPerUnitRequirer.
urls(

*self*
)

The full ingress URLs to reach every unit.

Description

May return an empty dict if the URLs aren't available yet.

IngressPerUnitRequirer.
url(

*self*
)

The full ingress URL to reach the current unit.

Description

May return None if the URL isn't available yet.
