mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-13 16:02:59 +00:00
feat: add the viewer's roles to a data table connection that names none
The default role of a data table under roles is now a floor: a connection naming no role also holds the roles its viewer is a tenant of, unless the default is admin. This replaces the explicit as=viewer option, which is removed from the reference parser, the executors and both clients. The roles drawer warns while the default is admin and confirms before removing the default role. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
949ce49365
commit
85e73ae4f1
@@ -1456,9 +1456,7 @@ class Windmill:
|
||||
},
|
||||
)
|
||||
|
||||
def datatable(
|
||||
self, name: str = "main", *, role: Optional[str] = None, as_viewer: bool = False
|
||||
):
|
||||
def datatable(self, name: str = "main", *, role: Optional[str] = None):
|
||||
"""Get a DataTable client for SQL queries.
|
||||
|
||||
Args:
|
||||
@@ -1466,14 +1464,11 @@ class Windmill:
|
||||
role: Connect as this data table role instead of the data table's default one.
|
||||
Only meaningful on a data table under roles, and only for a role you are a
|
||||
tenant of.
|
||||
as_viewer: Connect with every role of the job's viewer at once: the user of the
|
||||
app the job runs for, or whoever ran the script. The server resolves who that
|
||||
is. Cannot be combined with role.
|
||||
|
||||
Returns:
|
||||
DataTableClient instance
|
||||
"""
|
||||
return DataTableClient(self, name, role=role, as_viewer=as_viewer)
|
||||
return DataTableClient(self, name, role=role)
|
||||
|
||||
def ducklake(self, name: str = "main"):
|
||||
"""Get a DuckLake client for DuckDB queries.
|
||||
@@ -2330,21 +2325,17 @@ def username_to_email(username: str) -> str:
|
||||
|
||||
|
||||
@init_global_client
|
||||
def datatable(
|
||||
name: str = "main", *, role: Optional[str] = None, as_viewer: bool = False
|
||||
) -> DataTableClient:
|
||||
def datatable(name: str = "main", *, role: Optional[str] = None) -> DataTableClient:
|
||||
"""Get a DataTable client for SQL queries.
|
||||
|
||||
Args:
|
||||
name: Database name (default: "main")
|
||||
role: Connect as this data table role instead of the data table's default one.
|
||||
as_viewer: Connect with every role of the job's viewer at once: the user of the app
|
||||
the job runs for, or whoever ran the script. Cannot be combined with role.
|
||||
|
||||
Returns:
|
||||
DataTableClient instance
|
||||
"""
|
||||
return _client.datatable(name, role=role, as_viewer=as_viewer)
|
||||
return _client.datatable(name, role=role)
|
||||
|
||||
@init_global_client
|
||||
def ducklake(name: str = "main") -> DucklakeClient:
|
||||
@@ -2427,30 +2418,20 @@ _ROLE_NAME_RE = re.compile(r"^[A-Za-z0-9_-]{1,63}$")
|
||||
class DataTableClient:
|
||||
"""Client for executing SQL queries against Windmill DataTables."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
client: Windmill,
|
||||
name: str,
|
||||
role: Optional[str] = None,
|
||||
as_viewer: bool = False,
|
||||
):
|
||||
def __init__(self, client: Windmill, name: str, role: Optional[str] = None):
|
||||
"""Initialize DataTableClient.
|
||||
|
||||
Args:
|
||||
client: Windmill client instance
|
||||
name: DataTable name
|
||||
role: Data table role to connect as, or None for the data table's default
|
||||
as_viewer: Connect with every role of the job's viewer instead of one role
|
||||
"""
|
||||
if role is not None and not _ROLE_NAME_RE.match(role):
|
||||
raise ValueError(
|
||||
f"Invalid data table role '{role}': only letters, digits, '_' and '-' are allowed"
|
||||
)
|
||||
if as_viewer and role is not None:
|
||||
raise ValueError("A data table is used as a role or as the viewer, not both")
|
||||
self.client = client
|
||||
self.role = role
|
||||
self.as_viewer = as_viewer
|
||||
self.name, self.schema = parse_sql_client_name(name)
|
||||
def query(self, sql: str, *args) -> SqlQuery:
|
||||
"""Execute a SQL query against the DataTable.
|
||||
@@ -2479,13 +2460,7 @@ class DataTableClient:
|
||||
lambda sql: self.client.run_inline_script_preview(
|
||||
content=sql,
|
||||
language="postgresql",
|
||||
# In the reference rather than an annotation: a worker that does not know `?as=`
|
||||
# refuses the reference, where it would skip an annotation and connect as the
|
||||
# default role.
|
||||
args={
|
||||
"database": f"datatable://{self.name}{'?as=viewer' if self.as_viewer else ''}",
|
||||
**args_dict,
|
||||
},
|
||||
args={"database": f"datatable://{self.name}", **args_dict},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user