Skip to content

Commit 830ec3c

Browse files
committed
fix(kernel): validate request timeout
Signed-off-by: Vu Anh Phung <vu.phung@databricks.com>
1 parent 5886ffc commit 830ec3c

4 files changed

Lines changed: 33 additions & 3 deletions

File tree

CONNECTION_PARAMETERS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ to change without notice.
9999
100100
| Option | Type | Thrift | Kernel | Default Value | Note |
101101
| ------------------------------------ | ----------- | :----: | :----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
102-
| `_socket_timeout` | `float` (s) ||| `900` (Thrift); `120` (kernel) | Thrift: socket send/recv/connect timeout. Kernel: total HTTP request deadline from connect through response-body completion. A positive value is forwarded; unset or `0` selects the kernel's 120s default. On the kernel path, `0` is neither unlimited nor an immediate timeout. |
102+
| `_socket_timeout` | `float` (s) ||| `900` (Thrift); `120` (kernel) | Thrift: socket send/recv/connect timeout. Kernel: total HTTP request deadline from connect through response-body completion. A positive value is forwarded; unset or `0` selects the kernel's 120s default. On the kernel path, `0` is neither unlimited nor immediate; negative and non-finite values raise `ValueError`. |
103103
| `_pool_connections` | `int` || ⚠️ | `10` | Number of urllib3 connection pools. Configures the connector's shared Python HTTP client; the kernel's query transport is its own Rust stack. |
104104
| `_pool_maxsize` | `int` || ⚠️ | `20` | Max connections per pool on the shared Python HTTP client. Same kernel caveat as `_pool_connections`. |
105105
| `_proxy_auth_method` | `str` || ⚠️ | `None` | `basic` or `negotiate` (Kerberos). Applies to the shared Python HTTP client; not threaded to the kernel query transport. See [`docs/proxy.md`](docs/proxy.md). |

src/databricks/sql/backend/kernel/client.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from __future__ import annotations
2424

2525
import logging
26+
import math
2627
import threading
2728
import uuid
2829
from typing import Any, Dict, List, Optional, Set, TYPE_CHECKING, Union
@@ -219,7 +220,23 @@ def __init__(
219220
self._retry_options = kwargs.get("retry_options") or {}
220221
# The connector's ``_socket_timeout`` is already expressed in
221222
# seconds, matching the kernel's request-timeout binding.
222-
self._request_timeout_secs = kwargs.get("request_timeout_secs")
223+
request_timeout_secs = kwargs.get("request_timeout_secs")
224+
if request_timeout_secs is None:
225+
self._request_timeout_secs = None
226+
else:
227+
try:
228+
self._request_timeout_secs = float(request_timeout_secs)
229+
except (TypeError, ValueError, OverflowError) as exc:
230+
raise ValueError(
231+
"_socket_timeout must be a non-negative finite number of seconds"
232+
) from exc
233+
if (
234+
not math.isfinite(self._request_timeout_secs)
235+
or self._request_timeout_secs < 0
236+
):
237+
raise ValueError(
238+
"_socket_timeout must be a non-negative finite number of seconds"
239+
)
223240
self._catalog = catalog
224241
self._schema = schema
225242
# ``_use_arrow_native_complex_types`` is the connector-side

src/databricks/sql/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,8 @@ def read(self) -> Optional[OAuthToken]:
276276
# On Thrift, the timeout in seconds for socket send, recv and connect
277277
# operations. On the kernel path, a positive value is the total HTTP
278278
# request deadline. Kernel values of None or 0 select its 120-second
279-
# default; 0 is neither unlimited nor an immediate timeout.
279+
# default; 0 is neither unlimited nor an immediate timeout. Negative
280+
# and non-finite values are rejected.
280281
# _disable_pandas
281282
# In case the deserialisation through pandas causes any issues, it can be disabled with
282283
# this flag.

tests/unit/test_kernel_client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,18 @@ def fake_session(**kw):
371371
assert captured["request_timeout_secs"] == timeout
372372

373373

374+
@pytest.mark.parametrize("timeout", [-1, float("nan"), float("inf")])
375+
def test_request_timeout_rejects_invalid_values(timeout):
376+
with pytest.raises(ValueError, match="non-negative finite"):
377+
kernel_client.KernelDatabricksClient(
378+
server_hostname="example.cloud.databricks.com",
379+
http_path="/sql/1.0/warehouses/abc",
380+
auth_provider=AccessTokenAuthProvider("dapi-test"),
381+
ssl_options=None,
382+
request_timeout_secs=timeout,
383+
)
384+
385+
374386
def test_execute_command_forwards_parameters_to_bind_param():
375387
"""``execute_command(parameters=[...])`` routes each parameter
376388
through ``bind_tspark_params`` onto the kernel statement before

0 commit comments

Comments
 (0)