Skip to content

Commit 14d103a

Browse files
NickCrewscpcloud
authored andcommitted
feat: make Backend._from_url() consistently use kwargs as overrides
1 parent 15df443 commit 14d103a

File tree

13 files changed

+190
-340
lines changed

13 files changed

+190
-340
lines changed

ibis/backends/bigquery/__init__.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,12 +328,14 @@ def read_json(
328328
)
329329
return self._read_file(path, table_name=table_name, job_config=job_config)
330330

331-
def _from_url(self, url: ParseResult, **kwargs):
332-
return self.connect(
333-
project_id=url.netloc or kwargs.get("project_id", [""])[0],
334-
dataset_id=url.path[1:] or kwargs.get("dataset_id", [""])[0],
335-
**kwargs,
336-
)
331+
def _from_url(self, url: ParseResult, **kwarg_overrides):
332+
kwargs = {}
333+
if url.netloc:
334+
kwargs["project_id"] = url.netloc
335+
if url.path:
336+
kwargs["dataset_id"] = url.path[1:]
337+
kwargs.update(kwarg_overrides)
338+
return self.connect(**kwargs)
337339

338340
def do_connect(
339341
self,

ibis/backends/clickhouse/__init__.py

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -69,36 +69,20 @@ def _register_in_memory_table(self, op: ops.InMemoryTable) -> None:
6969
def _finalize_memtable(self, name: str) -> None:
7070
"""No-op."""
7171

72-
def _from_url(self, url: ParseResult, **kwargs) -> BaseBackend:
73-
"""Connect to a backend using a URL `url`.
74-
75-
Parameters
76-
----------
77-
url
78-
URL with which to connect to a backend.
79-
kwargs
80-
Additional keyword arguments
81-
82-
Returns
83-
-------
84-
BaseBackend
85-
A backend instance
86-
87-
"""
88-
database = url.path[1:]
89-
90-
connect_args = {
91-
"user": url.username,
92-
"password": unquote_plus(url.password or ""),
93-
"host": url.hostname,
94-
"database": database or "",
95-
"port": url.port,
96-
**kwargs,
97-
}
98-
99-
kwargs.update(connect_args)
72+
def _from_url(self, url: ParseResult, **kwarg_overrides) -> BaseBackend:
73+
kwargs = {}
74+
if url.username:
75+
kwargs["user"] = url.username
76+
if url.password:
77+
kwargs["password"] = unquote_plus(url.password)
78+
if url.hostname:
79+
kwargs["host"] = url.hostname
80+
if url.port:
81+
kwargs["port"] = url.port
82+
if database := url.path[1:]:
83+
kwargs["database"] = database
84+
kwargs.update(kwarg_overrides)
10085
self._convert_kwargs(kwargs)
101-
10286
return self.connect(**kwargs)
10387

10488
def _convert_kwargs(self, kwargs):

ibis/backends/druid/__init__.py

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,35 +44,20 @@ def version(self) -> str:
4444
[(version,)] = result.fetchall()
4545
return version
4646

47-
def _from_url(self, url: ParseResult, **kwargs):
48-
"""Connect to a backend using a URL `url`.
49-
50-
Parameters
51-
----------
52-
url
53-
URL with which to connect to a backend.
54-
kwargs
55-
Additional keyword arguments
56-
57-
Returns
58-
-------
59-
BaseBackend
60-
A backend instance
61-
62-
"""
63-
kwargs = {
64-
"user": url.username,
65-
"password": unquote_plus(url.password)
66-
if url.password is not None
67-
else None,
68-
"host": url.hostname,
69-
"path": url.path,
70-
"port": url.port,
71-
**kwargs,
72-
}
73-
47+
def _from_url(self, url: ParseResult, **kwarg_overrides):
48+
kwargs = {}
49+
if url.username:
50+
kwargs["user"] = url.username
51+
if url.password:
52+
kwargs["password"] = unquote_plus(url.password)
53+
if url.hostname:
54+
kwargs["host"] = url.hostname
55+
if url.path:
56+
kwargs["path"] = url.path
57+
if url.port:
58+
kwargs["port"] = url.port
59+
kwargs.update(kwarg_overrides)
7460
self._convert_kwargs(kwargs)
75-
7661
return self.connect(**kwargs)
7762

7863
@property

ibis/backends/exasol/__init__.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -151,21 +151,20 @@ def _post_connect(self, timezone: str = "UTC") -> None:
151151
with self.begin() as con:
152152
con.execute(f"ALTER SESSION SET TIME_ZONE = {timezone!r}")
153153

154-
def _from_url(self, url: ParseResult, **kwargs) -> BaseBackend:
155-
"""Construct an ibis backend from a URL."""
156-
kwargs = {
157-
"user": url.username,
158-
"password": unquote_plus(url.password)
159-
if url.password is not None
160-
else None,
161-
"schema": url.path[1:] or None,
162-
"host": url.hostname,
163-
"port": url.port,
164-
**kwargs,
165-
}
166-
154+
def _from_url(self, url: ParseResult, **kwarg_overrides) -> BaseBackend:
155+
kwargs = {}
156+
if url.username:
157+
kwargs["user"] = url.username
158+
if url.password:
159+
kwargs["password"] = unquote_plus(url.password)
160+
if url.hostname:
161+
kwargs["host"] = url.hostname
162+
if schema := url.path[1:]:
163+
kwargs["schema"] = schema
164+
if url.port:
165+
kwargs["port"] = url.port
166+
kwargs.update(kwarg_overrides)
167167
self._convert_kwargs(kwargs)
168-
169168
return self.connect(**kwargs)
170169

171170
@contextlib.contextmanager

ibis/backends/impala/__init__.py

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,36 +55,41 @@ class Backend(SQLBackend, CanCreateDatabase, NoExampleLoader):
5555
name = "impala"
5656
compiler = sc.impala.compiler
5757

58-
def _from_url(self, url: ParseResult, **kwargs: Any) -> Backend:
59-
"""Connect to a backend using a URL `url`.
60-
61-
Parameters
62-
----------
63-
url
64-
URL with which to connect to a backend.
65-
kwargs
66-
Additional keyword arguments passed to the `connect` method.
67-
68-
Returns
69-
-------
70-
BaseBackend
71-
A backend instance
72-
73-
"""
74-
for name in ("username", "hostname", "port", "password"):
75-
if value := (
76-
getattr(url, name, None)
77-
or os.environ.get(f"{self.name.upper()}_{name.upper()}")
78-
):
79-
kwargs[name] = value
80-
81-
with contextlib.suppress(KeyError):
82-
kwargs["host"] = kwargs.pop("hostname")
83-
84-
(database,) = url.path[1:].split("/", 1)
85-
if database:
58+
def _from_url(self, url: ParseResult, **kwarg_overrides: Any) -> Backend:
59+
def _get_env(attr: str) -> str | None:
60+
return os.environ.get(f"{self.name.upper()}_{attr.upper()}")
61+
62+
kwargs = {}
63+
if (username := _get_env("username")) is not None:
64+
kwargs["user"] = username
65+
if url.username:
66+
kwargs["user"] = url.username
67+
68+
if (password := _get_env("password")) is not None:
69+
kwargs["password"] = password
70+
if url.password:
71+
kwargs["password"] = url.password
72+
73+
if (host := _get_env("hostname")) is not None:
74+
kwargs["host"] = host
75+
if (host := _get_env("host")) is not None:
76+
kwargs["host"] = host
77+
if url.hostname:
78+
kwargs["host"] = url.hostname
79+
if host := kwarg_overrides.get("hostname"):
80+
kwargs["host"] = host
81+
82+
if (port := _get_env("port")) is not None:
83+
kwargs["port"] = port
84+
if url.port:
85+
kwargs["port"] = url.port
86+
87+
if (database := _get_env("path")) is not None:
88+
kwargs["database"] = database
89+
if database := url.path[1:].split("/", 1)[0]:
8690
kwargs["database"] = database
8791

92+
kwargs.update(kwarg_overrides)
8893
self._convert_kwargs(kwargs)
8994
return self.connect(**kwargs)
9095

ibis/backends/mssql/__init__.py

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -213,38 +213,20 @@ def _post_connect(self):
213213
with closing(self.con.cursor()) as cur:
214214
cur.execute("SET DATEFIRST 1")
215215

216-
def _from_url(self, url: ParseResult, **kwargs):
217-
database, *_ = url.path[1:].split("/", 1)
218-
kwargs.update(
219-
{
220-
"user": url.username,
221-
"password": unquote_plus(url.password or ""),
222-
"host": url.hostname,
223-
"database": database or "",
224-
"port": url.port or None,
225-
}
226-
)
227-
216+
def _from_url(self, url: ParseResult, **kwarg_overrides):
217+
kwargs = {}
218+
if url.username:
219+
kwargs["user"] = url.username
220+
if url.password:
221+
kwargs["password"] = unquote_plus(url.password)
222+
if url.hostname:
223+
kwargs["host"] = url.hostname
224+
if url.port:
225+
kwargs["port"] = url.port
226+
if database := url.path[1:].split("/")[0]:
227+
kwargs["database"] = database
228+
kwargs.update(kwarg_overrides)
228229
self._convert_kwargs(kwargs)
229-
230-
if "host" in kwargs and not kwargs["host"]:
231-
del kwargs["host"]
232-
233-
if "user" in kwargs and not kwargs["user"]:
234-
del kwargs["user"]
235-
236-
if "password" in kwargs and kwargs["password"] is None:
237-
del kwargs["password"]
238-
239-
if "port" in kwargs and kwargs["port"] is None:
240-
del kwargs["port"]
241-
242-
if "database" in kwargs and not kwargs["database"]:
243-
del kwargs["database"]
244-
245-
if "driver" in kwargs and not kwargs["driver"]:
246-
del kwargs["driver"]
247-
248230
return self.connect(**kwargs)
249231

250232
def get_schema(

ibis/backends/mysql/__init__.py

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -40,49 +40,20 @@ class Backend(SQLBackend, CanCreateDatabase, PyArrowExampleLoader):
4040
compiler = sc.mysql.compiler
4141
supports_create_or_replace = False
4242

43-
def _from_url(self, url: ParseResult, **kwargs):
44-
"""Connect to a backend using a URL `url`.
45-
46-
Parameters
47-
----------
48-
url
49-
URL with which to connect to a backend.
50-
kwargs
51-
Additional keyword arguments
52-
53-
Returns
54-
-------
55-
BaseBackend
56-
A backend instance
57-
58-
"""
59-
database, *_ = url.path[1:].split("/", 1)
60-
connect_args = {
61-
"user": url.username,
62-
"password": unquote_plus(url.password or ""),
63-
"host": url.hostname,
64-
"database": database or "",
65-
"port": url.port or None,
66-
}
67-
68-
kwargs.update(connect_args)
43+
def _from_url(self, url: ParseResult, **kwarg_overrides):
44+
kwargs = {}
45+
if url.username:
46+
kwargs["user"] = url.username
47+
if url.password:
48+
kwargs["password"] = unquote_plus(url.password)
49+
if url.hostname:
50+
kwargs["host"] = url.hostname
51+
if database := url.path[1:].split("/", 1)[0]:
52+
kwargs["database"] = database
53+
if url.port:
54+
kwargs["port"] = url.port
55+
kwargs.update(kwarg_overrides)
6956
self._convert_kwargs(kwargs)
70-
71-
if "user" in kwargs and not kwargs["user"]:
72-
del kwargs["user"]
73-
74-
if "host" in kwargs and not kwargs["host"]:
75-
del kwargs["host"]
76-
77-
if "database" in kwargs and not kwargs["database"]:
78-
del kwargs["database"]
79-
80-
if "password" in kwargs and kwargs["password"] is None:
81-
del kwargs["password"]
82-
83-
if "port" in kwargs and kwargs["port"] is None:
84-
del kwargs["port"]
85-
8657
return self.connect(**kwargs)
8758

8859
@cached_property

ibis/backends/oracle/__init__.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -206,16 +206,21 @@ def _post_connect(self) -> None:
206206
# Set to ensure decimals come back as decimals
207207
oracledb.defaults.fetch_decimals = True
208208

209-
def _from_url(self, url: ParseResult, **kwargs):
210-
self.do_connect(
211-
user=url.username,
212-
password=unquote_plus(url.password) if url.password is not None else None,
213-
database=url.path.removeprefix("/"),
214-
port=url.port,
215-
**kwargs,
216-
)
217-
218-
return self
209+
def _from_url(self, url: ParseResult, **kwarg_overrides):
210+
kwargs = {}
211+
if url.username:
212+
kwargs["user"] = url.username
213+
if url.password:
214+
kwargs["password"] = unquote_plus(url.password)
215+
if url.hostname:
216+
kwargs["host"] = url.hostname
217+
if database := url.path.removeprefix("/"):
218+
kwargs["database"] = database
219+
if url.port:
220+
kwargs["port"] = url.port
221+
kwargs.update(kwarg_overrides)
222+
self._convert_kwargs(kwargs)
223+
return self.connect(**kwargs)
219224

220225
@property
221226
def current_catalog(self) -> str:

0 commit comments

Comments
 (0)