---
title: Charmhub | Deploy Squid Forward Proxy using Charmhub - The Open Operator Collection
description: Deploy the latest version of Squid Forward Proxy on any cloud.
url: https://charmhub.io/squid-forward-proxy/libraries/http_proxy
---

# Squid Forward Proxy

[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:

24.04

edge cb154dc9

```
juju deploy squid-forward-proxy --channel edge
```

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

[Toggle side navigation](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#drawer)

## charms.squid\_forward\_proxy.v0.http\_proxy

* [*Docstrings*Docstrings](https://charmhub.io/squid-forward-proxy/libraries/http_proxy)
  [*Code*Source code](https://charmhub.io/squid-forward-proxy/libraries/http_proxy/source-code)
* + Download

    Fetch library

    ```
    charmcraft fetch-lib charms.squid_forward_proxy.v0.http_proxy
    ```

    [Download http\_proxy.py](https://charmhub.io/squid-forward-proxy/libraries/http_proxy/download)
  + *Last updated* 26 Sep 2025
  + *Revision* Library version 0.2

Library to manage the http-proxy relation.

This library contains the Requirer and Provider classes for handling the
http-proxy interface.

##### Getting Started

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

```
cd some-charm
charmcraft fetch-lib charms.http_proxy.v0.http_proxy
```

###### Using library as a requirer

In the `metadata.yaml` of the charm, add the following:

```
requires:
  http-proxy:
    interface: http-proxy
    limit: 1
```

There are three ways to initialize the requirer class. For requirers that need to issue only
a single request, they must either use the `HttpProxyRequirer` class or the
`HttpProxyDynamicRequirer` class. `HttpProxyRequirer` class is used when the requirer parameters
are known at initialization time. `HttpProxyDynamicRequirer` class is used when the requirer
parameters are not known at initialization time and will be provided later through the
`request_http_proxy` method. The main use case for the `HttpProxyDynamicRequirer` class
is when the list of domains requiring proxy is dynamic. For requirers that need to issue
multiple requests, they must use the `HttpProxyPolyRequirer` class.

1. To initialize the requirer with parameters using the `HttpProxyRequirer` class:

```
from charms.http_proxy.v0.http_proxy import {
    HTTPProxyNotAvailableError,
    HttpProxyRequirer
    DEFAULT_HTTP_PROXY_INTEGRATION_NAME
)

class FooCharm(ops.CharmBase):
    def __init__(self, *args):
        ...
         self.http_proxy_requirer = HttpProxyRequirer(
            self,
             relation_name=DEFAULT_HTTP_PROXY_INTEGRATION_NAME,
            domains=["example.com", "example.org"],
            auth=["userpass", "none", "srcip", "srcip+userpass"],
            src_ips=[],
        )
        self.framework.observe(
            self.on[DEFAULT_HTTP_PROXY_INTEGRATION_NAME].relation_changed, self.get_proxies
        )
        self.framework.observe(self.on.secret_changed, self.get_proxies)

    def get_proxies(self, _: ops.EventBase):
        try:
            proxies = self.http_proxy_requirer.fetch_proxies()
        except HTTPProxyUnavailableError as e:
            logging.error(f"HTTP proxy not available. Proxy status: {e.status}")
            return None
        return (proxies.http_proxy, proxies.https_proxy)
```

2. To initialize the requirer with no parameters using the `HttpProxyDynamicRequirer` class:

```
# This will simply initialize the requirer class and it won't perform any action.
# Later provide the requirer data through the request_http_proxy method.

from charms.http_proxy.v0.http_proxy import {
    HTTPProxyNotAvailableError,
    HttpProxyDynamicRequirer,
    DEFAULT_HTTP_PROXY_INTEGRATION_NAME
)

class FooCharmDynamic(ops.CharmBase):
    def __init__(self, *args):
        ...
        self.http_proxy_dynamic_requirer = HttpProxyDynamicRequirer(
            self,
            relation_name=DEFAULT_HTTP_PROXY_INTEGRATION_NAME,
        )
        self.framework.observe(
            self.on[DEFAULT_HTTP_PROXY_INTEGRATION_NAME].relation_changed, self.get_proxies
        )
        self.framework.observe(self.on.config_changed, self.provide_proxy)
        ...

    def provide_proxy(self, _: ops.EventBase):
        # If you have initialized the HttpProxyDynamicRequirer class
        # you can call the request_http_proxy method anywhere in your charm
        # to request proxy.
        if not self.model.unit.is_leader():
            return
        self.http_proxy_dynamic_requirer.request_http_proxy(
            domains=["example.com", "example.org"],
            auth=["userpass", "none", "srcip", "srcip+userpass"],
            src_ips=[],
        )

    def get_proxies(self, _: ops.EventBase):
        try:
            proxies = self.http_proxy_requirer.fetch_proxies()
        except HTTPProxyUnavailableError as e:
            logging.error(f"HTTP proxy not available. Proxy status: {e.status}")
            return None
        return (proxies.http_proxy, proxies.https_proxy)
```

3. To initialize the requirer with multiple requests using the `HttpProxyPolyRequirer` class,
   refer to the implementation in [http-proxy-policy-operator](https://github.com/canonical/http-proxy-operators/blob/main/http-proxy-policy-operator/src/charm.py). This class is for more advanced use
   cases where developers want to issue multiple requests with different parameters.

###### Using library as a provider

In the `metadata.yaml` of the charm, add the following:

```
provides:
  http-proxy:
    interface: http-proxy
```

Import HTTPProxyPolyProvider in your charm by adding the following to `src/charm.py`:

```
from charms.http_proxy.v0.http_proxy import (
    DEFAULT_HTTP_PROXY_INTEGRATION_NAME,
    HttpProxyPolyProvider,
)
```

The provider class must be instantiated as follows:

```
class FooCharm:
    def __init__(self, *args):
        super().__init__(*args, **kwargs)
        ...
        self._http_proxy_provider = HttpProxyPolyProvider(self)
        # This will simply initialize the requirer class and it won't perform any action.
        self.framework.observe(
            self.on[DEFAULT_HTTP_PROXY_INTEGRATION_NAME].relation_changed, self.provide_proxy
        )
        ...

    def provide_proxy(self, event: ops.EventBase) -> None:
        if not self.model.unit.is_leader():
            return
        relation = self.model.get_relation(DEFAULT_HTTP_PROXY_INTEGRATION_NAME)
        proxy_requests = self._http_proxy_provider.open_request_list(relation.id)
        responses = self._http_proxy_provider.open_response_list(relation.id)
        for requirer in proxy_requests.get_requirer_ids():
            request = proxy_requests.get(requirer)
            responses.add_or_replace(
                requirer_id=request.id,
                status=http_proxy.PROXY_STATUS_READY,
                auth=request.auth[0],
                http_proxy="http://proxy.test",
                https_proxy="https://proxy.test",
                user=None,
            )
```

---

Index

* [class ProxyConfig](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#proxyconfig)
* [class HTTPProxyUnavailableError](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyunavailableerror)
* + [def \_\_init\_\_(
    self,
    message,
    status)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyunavailableerror-__init__)
* [def dedup(
  input\_list
  )](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#dedup)
* [class HttpProxySpec](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyspec)
* + [def parse\_domain(
    domain)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyspec-parse_domain)
* [class HttpProxyRequest](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyrequest)
* [class HttpProxyUser](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyuser)
* + [def dump(
    self)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyuser-dump)
* [class HttpProxyResponse](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyresponse)
* [class IntegrationDataError](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#integrationdataerror)
* [class HttpProxyPolyProvider](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxypolyprovider)
* + [def \_\_init\_\_(
    self,
    charm,
    integration\_name)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxypolyprovider-__init__)
* + [def open\_request\_list(
    self,
    integration\_id)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxypolyprovider-open_request_list)
* + [def open\_response\_list(
    self,
    integration\_id)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxypolyprovider-open_response_list)
* [class HttpProxyPolyRequirer](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxypolyrequirer)
* + [def \_\_init\_\_(
    self,
    charm,
    integration\_name)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxypolyrequirer-__init__)
* + [def open\_request\_list(
    self,
    integration\_id)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxypolyrequirer-open_request_list)
* + [def open\_response\_list(
    self,
    integration\_id)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxypolyrequirer-open_response_list)
* [class HttpProxyRequirer](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyrequirer)
* + [def \_\_init\_\_(
    self,
    charm,
    relation\_name)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxyrequirer-__init__)
* [class HttpProxyDynamicRequirer](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxydynamicrequirer)
* + [def request\_http\_proxy(
    self,
    domains,
    auth,
    src\_ips)](https://charmhub.io/squid-forward-proxy/libraries/http_proxy#httpproxydynamicrequirer-request_http_proxy)

#### class ProxyConfig

Proxy configuration.

Attributes

http\_proxy

HTTP proxy.

https\_proxy

HTTPS proxy.

#### class HTTPProxyUnavailableError

Description

Raised when HTTP proxy is not available. None

Methods

HTTPProxyUnavailableError.
\_\_init\_\_(

*self*

,
message: str

,
status
)

Initialize the exception.

Arguments

message

The exception message.

status

The HTTP proxy status.

#### def dedup(input\_list)

Deduplicate a list without changing the order.

Arguments

input\_list

The input list.

Returns

The deduplicated list.

#### class HttpProxySpec

HTTP proxy model.

Attributes

group

group id. Along with id, uniquely identifies the proxy request within a charm scope.

id

id. Along with group, uniquely identifies the proxy request within a charm scope.

domains

HTTP proxy destination domains.

auth

HTTP proxy authentication methods.

src\_ips

HTTP proxy source IPs.

Methods

HttpProxySpec.
parse\_domain(

domain: str
)

Parse a domain string in the form of host[:port].

Arguments

domain

The domain string.

Returns

A (host, port) tuple. Port is 0 if not specified.

#### class HttpProxyRequest

HTTP proxy request model.

Attributes

implicit\_src\_ips

src\_ips is provided implicitly.

#### class HttpProxyUser

HTTP proxy user model.

Attributes

username

username.

password

password.

Methods

HttpProxyUser.
dump(

*self*
)

Dump the model with secret revealed.

Returns

Dictionary representation of the model with secret revealed.

#### class HttpProxyResponse

HTTP proxy response model.

Attributes

model\_config

pydantic model config.

group

group id. Along with id, uniquely identifies the proxy request within a charm scope.

id

id. Along with group, uniquely identifies the proxy request within a charm scope.

status

HTTP proxy status.

auth

HTTP proxy authentication method.

http\_proxy

HTTP proxy.

https\_proxy

HTTPS proxy.

user

HTTP proxy user.

Methods

#### class IntegrationDataError

Description

Integration contains ill-formed data. None

#### class HttpProxyPolyProvider

Description

HTTP proxy provider. None

Methods

HttpProxyPolyProvider.
\_\_init\_\_(

*self*

,
charm

,
integration\_name: str
)

Initialize the object.

Arguments

charm

the charm instance.

integration\_name

HTTP proxy integration name.

HttpProxyPolyProvider.
open\_request\_list(

*self*

,
integration\_id: int
)

Start reading the request list in the integration data.

Arguments

integration\_id

integration id.

Returns

A instance of HttpProxyRequestListReader.

HttpProxyPolyProvider.
open\_response\_list(

*self*

,
integration\_id: int
)

Start reading/writing the response list in the integration data.

Arguments

integration\_id

integration id.

Returns

A instance of HttpProxyResponseListReadWriter.

#### class HttpProxyPolyRequirer

Description

HTTP proxy requirer. None

Methods

HttpProxyPolyRequirer.
\_\_init\_\_(

*self*

,
charm

,
integration\_name: str
)

Initialize the object.

Arguments

charm

the charm instance.

integration\_name

HTTP proxy integration name.

HttpProxyPolyRequirer.
open\_request\_list(

*self*

,
integration\_id: int
)

Start reading/writing the request list in the integration data.

Arguments

integration\_id

integration id.

Returns

A instance of HttpProxyRequestListReadWriter.

HttpProxyPolyRequirer.
open\_response\_list(

*self*

,
integration\_id: int
)

Start reading the response list in the integration data.

Arguments

integration\_id

integration id.

Returns

A instance of HttpProxyResponseListReader.

#### class HttpProxyRequirer

Description

HTTP proxy static requirer. None

Methods

HttpProxyRequirer.
\_\_init\_\_(

*self*

,
charm

,
relation\_name: str
)

Initialize the HttpProxyRequirer class.

Arguments

charm

The charm instance.

relation\_name

The name of the relation to use for the HTTP proxy.

domains

Sequence of domains to request proxy access for.

auth

Sequence of authentication modes supported by the application.
See AUTH\_METHODS for valid values.

src\_ips

Sequence of source IPs to override the source IP addresses
provided by the Juju integration binding information.

#### class HttpProxyDynamicRequirer

Description

HTTP proxy dynamic requirer. None

Methods

HttpProxyDynamicRequirer.
request\_http\_proxy(

*self*

,
domains

,
auth

,
src\_ips
)

Request a HTTP proxy.

Arguments

domains

Sequence of domains to request proxy access for.

auth

Sequence of authentication modes supported by the application.
See AUTH\_METHODS for valid values.

src\_ips

Sequence of source IPs to override the source IP addresses
provided by the Juju integration binding information.
