Component: huawei-lte: cannot connect through a proxy

device : Huawei E3372
cannot connect through a proxy
resource : connect_with_proxy.py
tried to implement the functionality w/o succes, well, I’m bad in python :frowning:
it seems the requests_session isn’t propagated, any idea ?

homeassistant-home-assistant-copy:/usr/src/homeassistant/homeassistant/components/huawei_lte# diff -u __init__.py.bak __init__.py; diff -u config_flow.py.bak config_flow.py
--- __init__.py.bak
+++ __init__.py
@@ -20,6 +20,7 @@
     ResponseErrorLoginRequiredException,
     ResponseErrorNotSupportedException,
 )
+import requests
 from requests.exceptions import Timeout
 import voluptuous as vol

@@ -101,6 +102,9 @@
     ),
 )

+# should be in const.py
+CONF_PROXY_URL: Final = "proxy_url"
+
 CONFIG_SCHEMA = vol.Schema(
     {
         DOMAIN: vol.All(
@@ -111,6 +115,7 @@
                         vol.Required(CONF_URL): cv.url,
                         vol.Optional(CONF_USERNAME): cv.string,
                         vol.Optional(CONF_PASSWORD): cv.string,
+                        vol.Optional(CONF_PROXY_URL): cv.url,
                         vol.Optional(NOTIFY_DOMAIN): NOTIFY_SCHEMA,
                     }
                 )
@@ -120,7 +125,7 @@
     extra=vol.ALLOW_EXTRA,
 )

-SERVICE_SCHEMA = vol.Schema({vol.Optional(CONF_URL): cv.url})
+SERVICE_SCHEMA = vol.Schema({vol.Optional(CONF_URL): cv.url, vol.Optional(CONF_PROXY_URL): cv.url})

 PLATFORMS = [
     Platform.BINARY_SENSOR,
@@ -323,18 +328,25 @@
 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
     """Set up Huawei LTE component from config entry."""
     url = entry.data[CONF_URL]
+    proxy_url = entry.data[CONF_PROXY_URL] or ""
+    session = requests.Session()
+    if proxy_url != "":
+      session.proxies = { proxy_url }

     def get_connection() -> Connection:
         """Set up a connection."""
         if entry.options.get(CONF_UNAUTHENTICATED_MODE):
             _LOGGER.debug("Connecting in unauthenticated mode, reduced feature set")
-            connection = Connection(url, timeout=CONNECTION_TIMEOUT)
+            connection = Connection(
+                url, timeout=CONNECTION_TIMEOUT, requests_session=session
+            )
         else:
             _LOGGER.debug("Connecting in authenticated mode, full feature set")
             username = entry.data.get(CONF_USERNAME) or ""
             password = entry.data.get(CONF_PASSWORD) or ""
             connection = Connection(
-                url, username=username, password=password, timeout=CONNECTION_TIMEOUT
+                url, username=username, password=password,
+                timeout=CONNECTION_TIMEOUT, requests_session=session
             )
         return connection

--- config_flow.py.bak
+++ config_flow.py
@@ -16,6 +16,7 @@
     LoginErrorUsernameWrongException,
     ResponseErrorException,
 )
+import requests
 from requests.exceptions import Timeout
 from url_normalize import url_normalize
 import voluptuous as vol
@@ -33,6 +34,9 @@
 from homeassistant.core import callback
 from homeassistant.data_entry_flow import FlowResult

+# should be in const.py
+CONF_PROXY_URL: Final = "proxy_url"
+
 from .const import (
     CONF_TRACK_WIRED_CLIENTS,
     CONF_UNAUTHENTICATED_MODE,
@@ -85,6 +89,9 @@
                     vol.Optional(
                         CONF_PASSWORD, default=user_input.get(CONF_PASSWORD) or ""
                     ): str,
+                    vol.Optional(
+                        CONF_PROXY_URL, default=user_input.get(CONF_PROXY_URL) or ""
+                    ): str,
                 }
             ),
             errors=errors or {},
@@ -116,6 +123,10 @@
         """Try connecting with given data."""
         username = user_input.get(CONF_USERNAME) or ""
         password = user_input.get(CONF_PASSWORD) or ""
+        proxy_url = user_input.get(CONF_PROXY_URL) or ""
+        session = requests.Session()
+        if proxy_url != "":
+          session.proxies = { proxy_url }

         def _get_connection() -> Connection:
             return Connection(
@@ -123,6 +134,7 @@
                 username=username,
                 password=password,
                 timeout=CONNECTION_TIMEOUT,
+                requests_session=session,
             )

         conn = None
@@ -173,6 +185,17 @@
                 user_input=user_input, errors=errors
             )

+        if user_input[CONF_PROXY_URL] is not None:
+          # Normalize PROXY URL
+          user_input[CONF_PROXY_URL] = url_normalize(
+              user_input[CONF_PROXY_URL], default_scheme="http"
+          )
+          if "://" not in user_input[CONF_PROXY_URL]:
+              errors[CONF_PROXY_URL] = "invalid_proxy_url"
+              return await self._async_show_user_form(
+                  user_input=user_input, errors=errors
+              )
+
         def get_device_info(
             conn: Connection,
         ) -> tuple[GetResponseType, GetResponseType]:

traceback

2023-01-28 04:04:42.495 WARNING (MainThread) [homeassistant.components.huawei_lte.config_flow] Unknown error connecting to device
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/urllib3/connection.py", line 174, in _new_conn
    conn = connection.create_connection(
  File "/usr/local/lib/python3.10/site-packages/urllib3/util/connection.py", line 95, in create_connection
    raise err
  File "/usr/local/lib/python3.10/site-packages/urllib3/util/connection.py", line 85, in create_connection
    sock.connect(sa)
OSError: [Errno 113] Host is unreachable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 703, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 398, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/local/lib/python3.10/site-packages/urllib3/connection.py", line 239, in request
    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
  File "/usr/local/lib/python3.10/http/client.py", line 1282, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1328, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/local/lib/python3.10/http/client.py", line 1037, in _send_output
    self.send(msg)
  File "/usr/local/lib/python3.10/http/client.py", line 975, in send
    self.connect()
  File "/usr/local/lib/python3.10/site-packages/urllib3/connection.py", line 205, in connect
    conn = self._new_conn()
  File "/usr/local/lib/python3.10/site-packages/urllib3/connection.py", line 186, in _new_conn
    raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7ff8dfab16c0>: Failed to establish a new connection: [Errno 113] Host is unreachable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/requests/adapters.py", line 489, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    retries = retries.increment(
  File "/usr/local/lib/python3.10/site-packages/urllib3/util/retry.py", line 592, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.8.1', port=80): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7ff8dfab16c0>: Failed to establish a new connection: [Errno 113] Host is unreachable'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/huawei_lte/config_flow.py", line 142, in _try_connect
    conn = await self.hass.async_add_executor_job(_get_connection)
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/huawei_lte/config_flow.py", line 132, in _get_connection
    return Connection(
  File "/usr/local/lib/python3.10/site-packages/huawei_lte_api/Connection.py", line 30, in __init__
    super().__init__(url, timeout=timeout, requests_session=requests_session)
  File "/usr/local/lib/python3.10/site-packages/huawei_lte_api/Session.py", line 75, in __init__
    self._initialize_csrf_tokens_and_session()
  File "/usr/local/lib/python3.10/site-packages/huawei_lte_api/Session.py", line 169, in _initialize_csrf_tokens_and_session
    response = self.requests_session.get(self.url, timeout=self.timeout)
  File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 600, in get
    return self.request("GET", url, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 587, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/sessions.py", line 701, in send
    r = adapter.send(request, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/requests/adapters.py", line 565, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.8.1', port=80): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7ff8dfab16c0>: Failed to establish a new connection: [Errno 113] Host is unreachable'))