Skip to content

Commit 3dd1b39

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

File tree

4 files changed

+238
-33
lines changed

4 files changed

+238
-33
lines changed

py/selenium/webdriver/remote/client_config.py

+112-2
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,17 +44,38 @@ 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:
73+
""":Returns: The address of the remote server."""
4774
return self._remote_server_addr
4875

4976
@remote_server_addr.setter
5077
def remote_server_addr(self, value: str) -> None:
78+
"""Provides the address of the remote server."""
5179
self._remote_server_addr = value
5280

5381
@property
@@ -73,45 +101,126 @@ def proxy(self) -> Proxy:
73101
def proxy(self, proxy: Proxy) -> None:
74102
"""Provides the information for communicating with the driver or
75103
server.
104+
For example: Proxy(raw={"proxyType": ProxyType.SYSTEM})
76105
77106
:Args:
78107
- value: the proxy information to use to communicate with the driver or server
79108
"""
80109
self._proxy = proxy
81110

111+
@property
112+
def ignore_certificates(self) -> bool:
113+
""":Returns: The ignore certificate check value."""
114+
return self._ignore_certificates
115+
116+
@ignore_certificates.setter
117+
def ignore_certificates(self, ignore_certificates: bool) -> None:
118+
"""Toggles the ignore certificate check.
119+
120+
:Args:
121+
- value: value of ignore certificate check
122+
"""
123+
self._ignore_certificates = ignore_certificates
124+
125+
@property
126+
def init_args_for_pool_manager(self) -> dict:
127+
""":Returns: The dictionary of arguments will be appended while
128+
initializing the pool manager."""
129+
return self._init_args_for_pool_manager
130+
131+
@init_args_for_pool_manager.setter
132+
def init_args_for_pool_manager(self, init_args_for_pool_manager: dict) -> None:
133+
"""Provides dictionary of arguments will be appended while initializing the pool manager.
134+
For example: {"init_args_for_pool_manager": {"retries": 3, "block": True}}
135+
136+
:Args:
137+
- value: the dictionary of arguments will be appended while initializing the pool manager
138+
"""
139+
self._init_args_for_pool_manager = init_args_for_pool_manager
140+
141+
@property
142+
def timeout(self) -> int:
143+
""":Returns: The timeout (in seconds) used for communicating to the
144+
driver/server."""
145+
return self._timeout
146+
147+
@timeout.setter
148+
def timeout(self, timeout: int) -> None:
149+
"""Provides the timeout (in seconds) for communicating with the driver
150+
or server.
151+
152+
:Args:
153+
- value: the timeout (in seconds) to use to communicate with the driver or server
154+
"""
155+
self._timeout = timeout
156+
157+
def reset_timeout(self) -> None:
158+
"""Resets the timeout to the default value of socket."""
159+
self._timeout = socket.getdefaulttimeout()
160+
161+
@property
162+
def ca_certs(self) -> str:
163+
""":Returns: The path to bundle of CA certificates."""
164+
return self._ca_certs
165+
166+
@ca_certs.setter
167+
def ca_certs(self, ca_certs: str) -> None:
168+
"""Provides the path to bundle of CA certificates for establishing
169+
secure connections.
170+
171+
:Args:
172+
- value: the path to bundle of CA certificates for establishing secure connections
173+
"""
174+
self._ca_certs = ca_certs
175+
82176
@property
83177
def username(self) -> str:
178+
"""Returns the username used for basic authentication to the remote
179+
server."""
84180
return self._username
85181

86182
@username.setter
87183
def username(self, value: str) -> None:
184+
"""Sets the username used for basic authentication to the remote
185+
server."""
88186
self._username = value
89187

90188
@property
91189
def password(self) -> str:
190+
"""Returns the password used for basic authentication to the remote
191+
server."""
92192
return self._password
93193

94194
@password.setter
95195
def password(self, value: str) -> None:
196+
"""Sets the password used for basic authentication to the remote
197+
server."""
96198
self._password = value
97199

98200
@property
99201
def auth_type(self) -> str:
202+
"""Returns the type of authentication to the remote server."""
100203
return self._auth_type
101204

102205
@auth_type.setter
103206
def auth_type(self, value: str) -> None:
207+
"""Sets the type of authentication to the remote server if it is not
208+
using basic with username and password."""
104209
self._auth_type = value
105210

106211
@property
107212
def token(self) -> str:
213+
"""Returns the token used for authentication to the remote server."""
108214
return self._token
109215

110216
@token.setter
111217
def token(self, value: str) -> None:
218+
"""Sets the token used for authentication to the remote server if
219+
auth_type is not basic."""
112220
self._token = value
113221

114222
def get_proxy_url(self) -> Optional[str]:
223+
"""Returns the proxy URL to use for the connection."""
115224
proxy_type = self.proxy.proxy_type
116225
remote_add = parse.urlparse(self.remote_server_addr)
117226
if proxy_type is ProxyType.DIRECT:
@@ -136,6 +245,7 @@ def get_proxy_url(self) -> Optional[str]:
136245
return None
137246

138247
def get_auth_header(self) -> Optional[dict]:
248+
"""Returns the authorization to add to the request headers."""
139249
auth_type = self.auth_type.lower()
140250
if auth_type == "basic" and self.username and self.password:
141251
credentials = f"{self.username}:{self.password}"

py/selenium/webdriver/remote/remote_connection.py

+61-25
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() in RemoteConnection 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() in RemoteConnection is deprecated, set timeout to ClientConfig instance in constructor 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() in RemoteConnection 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() in RemoteConnection is deprecated, get ca_certs 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() in RemoteConnection is deprecated, set ca_certs to ClientConfig instance in constructor 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"):
@@ -263,18 +282,21 @@ def _get_connection_manager(self):
263282

264283
def __init__(
265284
self,
266-
remote_server_addr: str,
285+
remote_server_addr: Optional[str] = None,
267286
keep_alive: Optional[bool] = True,
268287
ignore_proxy: Optional[bool] = False,
269288
ignore_certificates: Optional[bool] = False,
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+
299+
RemoteConnection._client_config = self._client_config
278300

279301
if remote_server_addr:
280302
warnings.warn(
@@ -290,6 +312,20 @@ def __init__(
290312
stacklevel=2,
291313
)
292314

315+
if ignore_certificates:
316+
warnings.warn(
317+
"setting ignore_certificates in RemoteConnection() is deprecated, set in ClientConfig instance instead",
318+
DeprecationWarning,
319+
stacklevel=2,
320+
)
321+
322+
if init_args_for_pool_manager:
323+
warnings.warn(
324+
"setting init_args_for_pool_manager in RemoteConnection() is deprecated, set in ClientConfig instance instead",
325+
DeprecationWarning,
326+
stacklevel=2,
327+
)
328+
293329
if ignore_proxy:
294330
warnings.warn(
295331
"setting ignore_proxy in RemoteConnection() is deprecated, set in ClientConfig instance instead",

py/selenium/webdriver/remote/webdriver.py

+5
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ def get_remote_connection(
104104
ignore_local_proxy: bool,
105105
client_config: Optional[ClientConfig] = None,
106106
) -> RemoteConnection:
107+
if isinstance(command_executor, str):
108+
client_config = client_config or ClientConfig(remote_server_addr=command_executor)
109+
client_config.remote_server_addr = command_executor
110+
command_executor = RemoteConnection(client_config=client_config)
107111
from selenium.webdriver.chrome.remote_connection import ChromeRemoteConnection
108112
from selenium.webdriver.edge.remote_connection import EdgeRemoteConnection
109113
from selenium.webdriver.firefox.remote_connection import FirefoxRemoteConnection
@@ -201,6 +205,7 @@ def __init__(
201205
- options - instance of a driver options.Options class
202206
- locator_converter - Custom locator converter to use. Defaults to None.
203207
- web_element_cls - Custom class to use for web elements. Defaults to WebElement.
208+
- client_config - Custom client configuration to use. Defaults to None.
204209
"""
205210

206211
if isinstance(options, list):

0 commit comments

Comments
 (0)