Python
Add a python panel when SQL cannot express the compute: a statistics routine, a custom transform, or a chart matplotlib can draw and ECharts cannot.
The code runs on your own warehouse under the connection's identity. No dvt surface renders a python panel yet; the in-app renderer lands with DVT-4260, so this is an illustration.
What you can do
codeis Python that definesdef main(session, <params…>); dvt runs it on your Snowflake warehouse as an anonymous Snowpark procedure under the connection's own identity (the viewer's rights under caller's rights, the shared service identity on a service connection), never owner's rights, so it grants no privilege a SQL panel on that connection lacks.paramsdeclarestring,number, orbooleanarguments, bound by name from filter and drill values exactly like a SQL panel'sdata.params, one CALL argument each in declared order; a python panel accepts noonClickbut can be a filter or drill target through its ownparams.packagesis a closed allow-list (pandas,numpy,matplotlib,scipy,pyarrow,openpyxl);snowflake-snowpark-pythonis implicit.codeis capped at 1 MiB of UTF-8 bytes and may not contain$$.outputistable(default, a DataFrame),value(a scalar), orimage(a base64 PNG);presentationreuses the existing table-column and KPI-tile vocabulary and adds no keys of its own.- Authoring needs the
python:authorcapability and a Snowflakedata.sourceId; viewing needs onlydashboard:read. Execution sits behind thepythonPanelsdeployment switch, on in every edition as an operator kill switch, with a floor of roughly four to six seconds per run.
Applies to a python panel on a Snowflake source only. POST /v1/data/query executes the code and returns a real table, value, or image result today; the in-app renderer and code editor land with DVT-4260, so until then a python panel shows nothing on the SPA, exports, and renders.
Spec
View spec
{
"id": "revenue-by-category",
"type": "python",
"title": "Revenue by category, orders over the floor",
"data": {
"sourceId": "snowflake_db"
},
"spec": {
"code": "def main(session, min_amount): return session.sql('SELECT category, SUM(amount) AS revenue FROM analytics.public.orders WHERE amount >= ? GROUP BY 1 ORDER BY 2 DESC', params=[min_amount]).to_pandas()",
"params": {
"min_amount": {
"type": "number"
}
},
"packages": [
"pandas"
],
"output": "table"
}
}main takes session first and then one argument per declared params key; min_amount arrives as a CALL argument, so the SQL inside uses a ? bind rather than string formatting.
Build it in dvt
Every block on this page is a few lines of the same declarative JSON spec. Read the full spec format, or connect an AI agent to your warehouse and build one live in the quickstart.
Follow the build
dvt is in founding research. Leave your email and we'll reach out when there's something to see — no newsletters, no noise.