Skip to content

Commit 2f18791

Browse files
committed
Update ClientConfig with more kwargs
Signed-off-by: Viet Nguyen Duc <[email protected]>
1 parent dbe23c5 commit 2f18791

File tree

3 files changed

+182
-31
lines changed

3 files changed

+182
-31
lines changed

py/selenium/webdriver/remote/client_config.py

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
# under the License.
1717
import base64
1818
import os
19+
import socket
1920
from typing import Optional
2021
from urllib import parse
2122

23+
import certifi
24+
2225
from selenium.webdriver.common.proxy import Proxy
2326
from selenium.webdriver.common.proxy import ProxyType
2427

@@ -27,8 +30,12 @@ class ClientConfig:
2730
def __init__(
2831
self,
2932
remote_server_addr: str,
30-
keep_alive: bool = True,
31-
proxy: Proxy = Proxy(raw={"proxyType": ProxyType.SYSTEM}),
33+
keep_alive: Optional[bool] = True,
34+
proxy: Optional[Proxy] = Proxy(raw={"proxyType": ProxyType.SYSTEM}),
35+
ignore_certificates: Optional[bool] = False,
36+
init_args_for_pool_manager: Optional[dict] = None,
37+
timeout: Optional[int] = None,
38+
ca_certs: Optional[str] = None,
3239
username: Optional[str] = None,
3340
password: Optional[str] = None,
3441
auth_type: Optional[str] = "Basic",
@@ -37,11 +44,30 @@ def __init__(
3744
self.remote_server_addr = remote_server_addr
3845
self.keep_alive = keep_alive
3946
self.proxy = proxy
47+
self.ignore_certificates = ignore_certificates
48+
self.init_args_for_pool_manager = init_args_for_pool_manager or {}
49+
self.timeout = timeout
4050
self.username = username
4151
self.password = password
4252
self.auth_type = auth_type
4353
self.token = token
4454

55+
self.timeout = (
56+
(
57+
float(os.getenv("GLOBAL_DEFAULT_TIMEOUT", str(socket.getdefaulttimeout())))
58+
if os.getenv("GLOBAL_DEFAULT_TIMEOUT") is not None
59+
else socket.getdefaulttimeout()
60+
)
61+
if timeout is None
62+
else timeout
63+
)
64+
65+
self.ca_certs = (
66+
(os.getenv("REQUESTS_CA_BUNDLE") if "REQUESTS_CA_BUNDLE" in os.environ else certifi.where())
67+
if ca_certs is None
68+
else ca_certs
69+
)
70+
4571
@property
4672
def remote_server_addr(self) -> str:
4773
return self._remote_server_addr
@@ -79,6 +105,69 @@ def proxy(self, proxy: Proxy) -> None:
79105
"""
80106
self._proxy = proxy
81107

108+
@property
109+
def ignore_certificates(self) -> bool:
110+
""":Returns: The proxy used for communicating to the driver/server."""
111+
return self._ignore_certificates
112+
113+
@ignore_certificates.setter
114+
def ignore_certificates(self, ignore_certificates: bool) -> None:
115+
"""Provides the information for communicating with the driver or
116+
server.
117+
118+
:Args:
119+
- value: the proxy information to use to communicate with the driver or server
120+
"""
121+
self._ignore_certificates = ignore_certificates
122+
123+
@property
124+
def init_args_for_pool_manager(self) -> dict:
125+
""":Returns: The proxy used for communicating to the driver/server."""
126+
return self._init_args_for_pool_manager
127+
128+
@init_args_for_pool_manager.setter
129+
def init_args_for_pool_manager(self, init_args_for_pool_manager: dict) -> None:
130+
"""Provides the information for communicating with the driver or
131+
server.
132+
133+
:Args:
134+
- value: the proxy information to use to communicate with the driver or server
135+
"""
136+
self._init_args_for_pool_manager = init_args_for_pool_manager
137+
138+
@property
139+
def timeout(self) -> int:
140+
""":Returns: The proxy used for communicating to the driver/server."""
141+
return self._timeout
142+
143+
@timeout.setter
144+
def timeout(self, timeout: int) -> None:
145+
"""Provides the information for communicating with the driver or
146+
server.
147+
148+
:Args:
149+
- value: the proxy information to use to communicate with the driver or server
150+
"""
151+
self._timeout = timeout
152+
153+
def reset_timeout(self) -> None:
154+
self._timeout = socket.getdefaulttimeout()
155+
156+
@property
157+
def ca_certs(self) -> str:
158+
""":Returns: The proxy used for communicating to the driver/server."""
159+
return self._ca_certs
160+
161+
@ca_certs.setter
162+
def ca_certs(self, ca_certs: str) -> None:
163+
"""Provides the information for communicating with the driver or
164+
server.
165+
166+
:Args:
167+
- value: the proxy information to use to communicate with the driver or server
168+
"""
169+
self._ca_certs = ca_certs
170+
82171
@property
83172
def username(self) -> str:
84173
return self._username

py/selenium/webdriver/remote/remote_connection.py

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616
# under the License.
1717

1818
import logging
19-
import os
2019
import platform
21-
import socket
2220
import string
2321
import warnings
2422
from base64 import b64encode
2523
from typing import Optional
2624
from urllib import parse
2725

28-
import certifi
2926
import urllib3
3027

3128
from selenium import __version__
@@ -139,12 +136,7 @@ class RemoteConnection:
139136
"""
140137

141138
browser_name = None
142-
_timeout = (
143-
float(os.getenv("GLOBAL_DEFAULT_TIMEOUT", str(socket.getdefaulttimeout())))
144-
if os.getenv("GLOBAL_DEFAULT_TIMEOUT") is not None
145-
else socket.getdefaulttimeout()
146-
)
147-
_ca_certs = os.getenv("REQUESTS_CA_BUNDLE") if "REQUESTS_CA_BUNDLE" in os.environ else certifi.where()
139+
_client_config: ClientConfig = None
148140

149141
system = platform.system().lower()
150142
if system == "darwin":
@@ -161,7 +153,12 @@ def get_timeout(cls):
161153
Timeout value in seconds for all http requests made to the
162154
Remote Connection
163155
"""
164-
return None if cls._timeout == socket._GLOBAL_DEFAULT_TIMEOUT else cls._timeout
156+
warnings.warn(
157+
"get_timeout is deprecated, get timeout from ClientConfig instance instead",
158+
DeprecationWarning,
159+
stacklevel=2,
160+
)
161+
return cls._client_config.timeout
165162

166163
@classmethod
167164
def set_timeout(cls, timeout):
@@ -170,12 +167,22 @@ def set_timeout(cls, timeout):
170167
:Args:
171168
- timeout - timeout value for http requests in seconds
172169
"""
173-
cls._timeout = timeout
170+
warnings.warn(
171+
"set_timeout is deprecated, set timeout in ClientConfig instance instead",
172+
DeprecationWarning,
173+
stacklevel=2,
174+
)
175+
cls._client_config.timeout = timeout
174176

175177
@classmethod
176178
def reset_timeout(cls):
177179
"""Reset the http request timeout to socket._GLOBAL_DEFAULT_TIMEOUT."""
178-
cls._timeout = socket._GLOBAL_DEFAULT_TIMEOUT
180+
warnings.warn(
181+
"reset_timeout is deprecated, use reset_timeout in ClientConfig instance instead",
182+
DeprecationWarning,
183+
stacklevel=2,
184+
)
185+
cls._client_config.reset_timeout()
179186

180187
@classmethod
181188
def get_certificate_bundle_path(cls):
@@ -185,7 +192,12 @@ def get_certificate_bundle_path(cls):
185192
command executor. Defaults to certifi.where() or
186193
REQUESTS_CA_BUNDLE env variable if set.
187194
"""
188-
return cls._ca_certs
195+
warnings.warn(
196+
"get_certificate_bundle_path is deprecated, get certificate bundle path from ClientConfig instance instead",
197+
DeprecationWarning,
198+
stacklevel=2,
199+
)
200+
return cls._client_config.ca_certs
189201

190202
@classmethod
191203
def set_certificate_bundle_path(cls, path):
@@ -196,7 +208,12 @@ def set_certificate_bundle_path(cls, path):
196208
:Args:
197209
- path - path of a .pem encoded certificate chain.
198210
"""
199-
cls._ca_certs = path
211+
warnings.warn(
212+
"set_certificate_bundle_path is deprecated, set certificate bundle path in ClientConfig instance instead",
213+
DeprecationWarning,
214+
stacklevel=2,
215+
)
216+
cls._client_config.ca_certs = path
200217

201218
@classmethod
202219
def get_remote_connection_headers(cls, parsed_url, keep_alive=False):
@@ -239,15 +256,17 @@ def _separate_http_proxy_auth(self):
239256
return proxy_without_auth, auth
240257

241258
def _get_connection_manager(self):
242-
pool_manager_init_args = {"timeout": self.get_timeout()}
243-
pool_manager_init_args.update(self._init_args_for_pool_manager.get("init_args_for_pool_manager", {}))
259+
pool_manager_init_args = {"timeout": self._client_config.timeout}
260+
pool_manager_init_args.update(
261+
self._client_config.init_args_for_pool_manager.get("init_args_for_pool_manager", {})
262+
)
244263

245-
if self._ignore_certificates:
264+
if self._client_config.ignore_certificates:
246265
pool_manager_init_args["cert_reqs"] = "CERT_NONE"
247266
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
248-
elif self._ca_certs:
267+
elif self._client_config.ca_certs:
249268
pool_manager_init_args["cert_reqs"] = "CERT_REQUIRED"
250-
pool_manager_init_args["ca_certs"] = self._ca_certs
269+
pool_manager_init_args["ca_certs"] = self._client_config.ca_certs
251270

252271
if self._proxy_url:
253272
if self._proxy_url.lower().startswith("sock"):
@@ -270,18 +289,23 @@ def __init__(
270289
init_args_for_pool_manager: Optional[dict] = None,
271290
client_config: Optional[ClientConfig] = None,
272291
):
273-
self.keep_alive = keep_alive
274-
self._url = remote_server_addr
275-
self._ignore_certificates = ignore_certificates
276-
self._init_args_for_pool_manager = init_args_for_pool_manager or {}
277-
self._client_config = client_config or ClientConfig(remote_server_addr, keep_alive)
292+
self._client_config = client_config or ClientConfig(
293+
remote_server_addr=remote_server_addr,
294+
keep_alive=keep_alive,
295+
ignore_certificates=ignore_certificates,
296+
init_args_for_pool_manager=init_args_for_pool_manager,
297+
)
298+
RemoteConnection._client_config = self._client_config
278299

279300
if remote_server_addr:
280301
warnings.warn(
281302
"setting remote_server_addr in RemoteConnection() is deprecated, set in ClientConfig instance instead",
282303
DeprecationWarning,
283304
stacklevel=2,
284305
)
306+
self._url = remote_server_addr
307+
else:
308+
self._url = self._client_config.remote_server_addr
285309

286310
if not keep_alive:
287311
warnings.warn(
@@ -290,6 +314,20 @@ def __init__(
290314
stacklevel=2,
291315
)
292316

317+
if ignore_certificates:
318+
warnings.warn(
319+
"setting ignore_certificates in RemoteConnection() is deprecated, set in ClientConfig instance instead",
320+
DeprecationWarning,
321+
stacklevel=2,
322+
)
323+
324+
if init_args_for_pool_manager:
325+
warnings.warn(
326+
"setting init_args_for_pool_manager in RemoteConnection() is deprecated, set in ClientConfig instance instead",
327+
DeprecationWarning,
328+
stacklevel=2,
329+
)
330+
293331
if ignore_proxy:
294332
warnings.warn(
295333
"setting ignore_proxy in RemoteConnection() is deprecated, set in ClientConfig instance instead",

py/test/unit/selenium/webdriver/remote/remote_connection_tests.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,10 @@ def test_get_connection_manager_without_proxy(mock_proxy_settings_missing):
127127
assert isinstance(conn, urllib3.PoolManager)
128128

129129

130-
def test_get_connection_manager_for_certs_and_timeout(monkeypatch):
131-
monkeypatch.setattr(RemoteConnection, "get_timeout", lambda _: 10) # Class state; leaks into subsequent tests.
130+
def test_get_connection_manager_for_certs_and_timeout():
132131
remote_connection = RemoteConnection("http://remote", keep_alive=False)
132+
remote_connection.set_timeout(10)
133+
assert remote_connection.get_timeout() == 10
133134
conn = remote_connection._get_connection_manager()
134135
assert conn.connection_pool_kw["timeout"] == 10
135136
assert conn.connection_pool_kw["cert_reqs"] == "CERT_REQUIRED"
@@ -306,19 +307,42 @@ def test_register_extra_headers(mock_request, remote_connection):
306307
assert headers["Foo"] == "bar"
307308

308309

310+
def test_get_connection_manager_with_timeout_from_client_config():
311+
client_config = ClientConfig("http://remote", timeout=300)
312+
remote_connection = RemoteConnection(None, client_config=client_config)
313+
conn = remote_connection._get_connection_manager()
314+
assert conn.connection_pool_kw["timeout"] == 300
315+
assert isinstance(conn, urllib3.PoolManager)
316+
317+
318+
def test_get_connection_manager_with_ca_certs_from_client_config():
319+
client_config = ClientConfig("http://remote", ca_certs="/path/to/cacert.pem")
320+
remote_connection = RemoteConnection(None, client_config=client_config)
321+
conn = remote_connection._get_connection_manager()
322+
assert conn.connection_pool_kw["timeout"] is None
323+
assert conn.connection_pool_kw["cert_reqs"] == "CERT_REQUIRED"
324+
assert conn.connection_pool_kw["ca_certs"] == "/path/to/cacert.pem"
325+
assert isinstance(conn, urllib3.PoolManager)
326+
327+
309328
def test_get_connection_manager_ignores_certificates(monkeypatch):
310-
monkeypatch.setattr(RemoteConnection, "get_timeout", lambda _: 10)
311-
remote_connection = RemoteConnection("http://remote", ignore_certificates=True)
329+
client_config = ClientConfig("http://remote", ignore_certificates=True)
330+
remote_connection = RemoteConnection(None, client_config=client_config)
331+
remote_connection.set_timeout(10)
312332
conn = remote_connection._get_connection_manager()
313333

314334
assert conn.connection_pool_kw["timeout"] == 10
315335
assert conn.connection_pool_kw["cert_reqs"] == "CERT_NONE"
316336
assert isinstance(conn, urllib3.PoolManager)
317337

338+
remote_connection.reset_timeout()
339+
assert remote_connection.get_timeout() is None
340+
318341

319342
def test_get_connection_manager_with_custom_args():
320343
custom_args = {"init_args_for_pool_manager": {"retries": 3, "block": True}}
321-
remote_connection = RemoteConnection("http://remote", keep_alive=False, init_args_for_pool_manager=custom_args)
344+
client_config = ClientConfig("http://remote", keep_alive=False, init_args_for_pool_manager=custom_args)
345+
remote_connection = RemoteConnection(None, client_config=client_config)
322346
conn = remote_connection._get_connection_manager()
323347

324348
assert isinstance(conn, urllib3.PoolManager)

0 commit comments

Comments
 (0)