Skip to content

Commit 3d0e55b

Browse files
committed
Update Databricks sdk helpers to be more explicit about fallback options
1 parent a6894dd commit 3d0e55b

File tree

8 files changed

+170
-409
lines changed

8 files changed

+170
-409
lines changed

examples/connect/databricks/dash/app.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
import pandas as pd
77
from dash import Dash, Input, Output, dash_table, html
88
from databricks import sql
9-
from databricks.sdk.core import ApiClient, Config, databricks_cli
9+
from databricks.sdk.core import ApiClient
1010
from databricks.sdk.service.iam import CurrentUserAPI
1111

12-
from posit.connect.external.databricks import PositCredentialsStrategy
12+
from posit.connect.external.databricks import (
13+
new_config,
14+
sql_credentials,
15+
ConnectStrategy,
16+
)
1317

1418
DATABRICKS_HOST = os.getenv("DATABRICKS_HOST")
1519
DATABRICKS_HOST_URL = f"https://{DATABRICKS_HOST}"
@@ -37,15 +41,10 @@ def update_page(_):
3741
the first few rows from a table hosted in Databricks.
3842
"""
3943
session_token = flask.request.headers.get("Posit-Connect-User-Session-Token")
40-
posit_strategy = PositCredentialsStrategy(
41-
local_strategy=databricks_cli,
42-
user_session_token=session_token,
43-
)
44-
cfg = Config(
45-
host=DATABRICKS_HOST_URL,
46-
# uses Posit's custom credential_strategy if running on Connect,
47-
# otherwise falls back to the strategy defined by local_strategy
48-
credentials_strategy=posit_strategy,
44+
cfg = new_config(
45+
posit_connect_strategy=ConnectStrategy(
46+
user_session_token=session_token,
47+
),
4948
)
5049

5150
def get_greeting():
@@ -61,8 +60,7 @@ def get_table():
6160
with sql.connect(
6261
server_hostname=DATABRICKS_HOST,
6362
http_path=SQL_HTTP_PATH,
64-
# https://github.com/databricks/databricks-sql-python/issues/148#issuecomment-2271561365
65-
credentials_provider=posit_strategy.sql_credentials_provider(cfg),
63+
credentials_provider=sql_credentials(cfg),
6664
) as connection:
6765
with connection.cursor() as cursor:
6866
cursor.execute(query)

examples/connect/databricks/fastapi/app.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
import os
66

77
from databricks import sql
8-
from databricks.sdk.core import Config, databricks_cli
98
from fastapi import FastAPI, Header
109
from typing_extensions import TYPE_CHECKING, Annotated
1110

12-
from posit.connect.external.databricks import PositCredentialsStrategy
11+
from posit.connect.external.databricks import (
12+
new_config,
13+
sql_credentials,
14+
ConnectStrategy,
15+
)
1316

1417
if TYPE_CHECKING:
1518
from fastapi.responses import JSONResponse
@@ -32,15 +35,10 @@ async def get_fares(
3235
"""
3336
global rows
3437

35-
posit_strategy = PositCredentialsStrategy(
36-
local_strategy=databricks_cli,
37-
user_session_token=posit_connect_user_session_token,
38-
)
39-
cfg = Config(
40-
host=DATABRICKS_HOST_URL,
41-
# uses Posit's custom credential_strategy if running on Connect,
42-
# otherwise falls back to the strategy defined by local_strategy
43-
credentials_strategy=posit_strategy,
38+
cfg = new_config(
39+
posit_connect_strategy=ConnectStrategy(
40+
user_session_token=posit_connect_user_session_token,
41+
),
4442
)
4543

4644
if rows is None:
@@ -49,8 +47,7 @@ async def get_fares(
4947
with sql.connect(
5048
server_hostname=DATABRICKS_HOST,
5149
http_path=SQL_HTTP_PATH,
52-
# https://github.com/databricks/databricks-sql-python/issues/148#issuecomment-2271561365
53-
credentials_provider=posit_strategy.sql_credentials_provider(cfg),
50+
credentials_provider=sql_credentials(cfg),
5451
) as connection:
5552
with connection.cursor() as cursor:
5653
cursor.execute(query)

examples/connect/databricks/flask/app.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
import os
44

55
from databricks import sql
6-
from databricks.sdk.core import Config, databricks_cli
76
from flask import Flask, request
87

9-
from posit.connect.external.databricks import PositCredentialsStrategy
8+
from posit.connect.external.databricks import (
9+
new_config,
10+
sql_credentials,
11+
ConnectStrategy,
12+
)
1013

1114
DATABRICKS_HOST = os.getenv("DATABRICKS_HOST")
1215
DATABRICKS_HOST_URL = f"https://{DATABRICKS_HOST}"
@@ -30,15 +33,10 @@ def get_fares():
3033
global rows
3134

3235
session_token = request.headers.get("Posit-Connect-User-Session-Token")
33-
posit_strategy = PositCredentialsStrategy(
34-
local_strategy=databricks_cli,
35-
user_session_token=session_token,
36-
)
37-
cfg = Config(
38-
host=DATABRICKS_HOST_URL,
39-
# uses Posit's custom credential_strategy if running on Connect,
40-
# otherwise falls back to the strategy defined by local_strategy
41-
credentials_strategy=posit_strategy,
36+
cfg = new_config(
37+
posit_connect_strategy=ConnectStrategy(
38+
user_session_token=session_token
39+
),
4240
)
4341

4442
if rows is None:
@@ -47,8 +45,7 @@ def get_fares():
4745
with sql.connect(
4846
server_hostname=DATABRICKS_HOST,
4947
http_path=SQL_HTTP_PATH,
50-
# https://github.com/databricks/databricks-sql-python/issues/148#issuecomment-2271561365
51-
credentials_provider=posit_strategy.sql_credentials_provider(cfg),
48+
credentials_provider=sql_credentials(cfg),
5249
) as connection:
5350
with connection.cursor() as cursor:
5451
cursor.execute(query)

examples/connect/databricks/shiny/app.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@
44

55
import pandas as pd
66
from databricks import sql
7-
from databricks.sdk.core import ApiClient, Config, databricks_cli
7+
from databricks.sdk.core import ApiClient
88
from databricks.sdk.service.iam import CurrentUserAPI
99
from shiny import App, Inputs, Outputs, Session, render, ui
1010

11-
from posit.connect.external.databricks import PositCredentialsStrategy
11+
from posit.connect.external.databricks import (
12+
new_config,
13+
sql_credentials,
14+
ConnectStrategy,
15+
)
1216

1317
DATABRICKS_HOST = os.getenv("DATABRICKS_HOST")
1418
DATABRICKS_HOST_URL = f"https://{DATABRICKS_HOST}"
@@ -23,15 +27,10 @@ def server(i: Inputs, o: Outputs, session: Session):
2327
the first few rows from a table hosted in Databricks.
2428
"""
2529
session_token = session.http_conn.headers.get("Posit-Connect-User-Session-Token")
26-
posit_strategy = PositCredentialsStrategy(
27-
local_strategy=databricks_cli,
28-
user_session_token=session_token,
29-
)
30-
cfg = Config(
31-
host=DATABRICKS_HOST_URL,
32-
# uses Posit's custom credential_strategy if running on Connect,
33-
# otherwise falls back to the strategy defined by local_strategy
34-
credentials_strategy=posit_strategy,
30+
cfg = new_config(
31+
posit_connect_strategy=ConnectStrategy(
32+
user_session_token=session_token
33+
),
3534
)
3635

3736
@render.data_frame
@@ -41,8 +40,7 @@ def result():
4140
with sql.connect(
4241
server_hostname=DATABRICKS_HOST,
4342
http_path=SQL_HTTP_PATH,
44-
# https://github.com/databricks/databricks-sql-python/issues/148#issuecomment-2271561365
45-
credentials_provider=posit_strategy.sql_credentials_provider(cfg),
43+
credentials_provider=sql_credentials(cfg),
4644
) as connection:
4745
with connection.cursor() as cursor:
4846
cursor.execute(query)

examples/connect/databricks/streamlit/app.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,24 @@
55
import pandas as pd
66
import streamlit as st
77
from databricks import sql
8-
from databricks.sdk.core import ApiClient, Config, databricks_cli
8+
from databricks.sdk.core import ApiClient
99
from databricks.sdk.service.iam import CurrentUserAPI
1010

11-
from posit.connect.external.databricks import PositCredentialsStrategy
11+
from posit.connect.external.databricks import (
12+
new_config,
13+
sql_credentials,
14+
ConnectStrategy,
15+
)
1216

1317
DATABRICKS_HOST = os.getenv("DATABRICKS_HOST")
1418
DATABRICKS_HOST_URL = f"https://{DATABRICKS_HOST}"
1519
SQL_HTTP_PATH = os.getenv("DATABRICKS_PATH")
1620

1721
session_token = st.context.headers.get("Posit-Connect-User-Session-Token")
18-
posit_strategy = PositCredentialsStrategy(
19-
local_strategy=databricks_cli,
20-
user_session_token=session_token,
21-
)
22-
cfg = Config(
23-
host=DATABRICKS_HOST_URL,
24-
# uses Posit's custom credential_strategy if running on Connect,
25-
# otherwise falls back to the strategy defined by local_strategy
26-
credentials_strategy=posit_strategy,
22+
cfg = new_config(
23+
posit_connect_strategy=ConnectStrategy(
24+
user_session_token=session_token
25+
),
2726
)
2827

2928
databricks_user = CurrentUserAPI(ApiClient(cfg)).me()
@@ -32,8 +31,7 @@
3231
with sql.connect(
3332
server_hostname=DATABRICKS_HOST,
3433
http_path=SQL_HTTP_PATH,
35-
# https://github.com/databricks/databricks-sql-python/issues/148#issuecomment-2271561365
36-
credentials_provider=posit_strategy.sql_credentials_provider(cfg),
34+
credentials_provider=sql_credentials(cfg),
3735
) as connection:
3836
with connection.cursor() as cursor:
3937
cursor.execute("SELECT * FROM samples.nyctaxi.trips LIMIT 10;")

pyproject.toml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,15 @@ exclude = ".*"
131131
[dependency-groups]
132132
build = ["build"]
133133
coverage = ["coverage"]
134-
examples = ["rsconnect-python", "pandas", "databricks", "shiny"]
134+
examples = [
135+
"databricks-sdk>=0.29.0",
136+
"databricks-sql-connector>=3.3.0",
137+
"pandas",
138+
"rsconnect-python",
139+
"shiny",
140+
"streamlit>=1.37.0"
141+
]
142+
external = ["databricks-sdk"]
135143
git = ["pre-commit"]
136144
lint = ["ruff", "pyright"]
137145
test = ["rsconnect-python", "responses", "pytest", "pyjson5"]
@@ -143,6 +151,7 @@ dev = [
143151
# # `numpy==1.24.4` requires `distutils`, which is not available in python3.12
144152
# # `numpy>1.24.4` does not require `distutils`
145153
# { include-group = "examples" },
154+
{ include-group = "external" },
146155
{ include-group = "git" },
147156
{ include-group = "lint" },
148157
{ include-group = "test" },

src/posit/connect/_utils.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,25 @@ def update_dict_values(obj: dict[str, Any], /, **kwargs: Any) -> None:
3232
dict.update(obj, **kwargs)
3333

3434

35-
def is_local() -> bool:
36-
"""Returns true if called from a piece of content running on a Connect server.
35+
def is_workbench() -> bool:
36+
"""Attempts to return true if called from a piece of content running on Posit Workbench.
37+
38+
There is not yet a definitive way to determine if the content is running on Workbench. This method is best-effort.
39+
"""
40+
return "RSW_LAUNCHER" in os.environ or \
41+
"RSTUDIO_MULTI_SESSION" in os.environ or \
42+
"RS_SERVER_ADDRESS" in os.environ or \
43+
"RS_SERVER_URL" in os.environ
44+
3745

38-
The connect server will always set the environment variable `RSTUDIO_PRODUCT=CONNECT`.
39-
We can use this environment variable to determine if the content is running locally
40-
or on a Connect server.
46+
def is_connect() -> bool:
47+
"""Returns true if called from a piece of content running on Posit Connect.
48+
49+
The Connect content will always set the environment variable `RSTUDIO_PRODUCT=CONNECT`.
4150
"""
42-
return os.getenv("RSTUDIO_PRODUCT") != "CONNECT"
51+
return os.getenv("RSTUDIO_PRODUCT") == "CONNECT"
52+
53+
54+
def is_local() -> bool:
55+
"""Returns true if called from a piece of content running locally."""
56+
return not is_connect() and not is_workbench()

0 commit comments

Comments
 (0)