Run Python or Spark Jobs on Snowflake with Code Bundles
Overview
Note: Code Bundles are in Public Preview.
You have Python scripts that process data already sitting in Snowflake, but the scripts run somewhere else: on a VM, a cron server, a notebook host, or a Spark cluster you provision and pay for whether it's running or not. You could rewrite everything as stored procedures, but that means matching handler signatures, re-declaring packages, and splitting a project that works as a unit into separate database objects.
In this Quickstart, we'll skip all of that. We'll take a clickstream pipeline as-is – a Python sessionizer, a PySpark analytics job, shared helpers – package it as a single Code Bundle, and run each file on Snowflake. The Python job runs on a warehouse. The PySpark job runs as a native Spark job, with no Spark cluster required. By the end, you'll have the pipeline scheduled on a Task and producing fictional funnel metrics from ~50K clickstream events.
What You'll Learn
- How to package a project as a Code Bundle and run it on Snowflake compute
- How to run a Python job on a warehouse with
EXECUTE CODE BUNDLE - How to override a bundle's specification at execution time with
WITH SPECIFICATION - How to submit a PySpark job via the REST API, SQL, or from a stage – no Spark cluster required
- How to orchestrate a multi-stage pipeline with a Snowflake Task
- How to version, run asynchronously, and monitor your jobs in production
What You'll Need
- A Snowflake account with access to Code Bundles, with a role that can create warehouses and databases (for example, ACCOUNTADMIN)
- The Snowflake CLI:
pip install snowflake-cli # or: uv tool install snowflake-cli - A configured Snowflake CLI connection (verify with
snow connection list) - Basic familiarity with Python, PySpark, and SQL
Tip: You can run this Quickstart with Cortex Code, Snowflake's AI coding assistant. Point Cortex Code at this guide and it can execute each step for you, explain what's happening, and help you adapt the pipeline to your own data. You can also use it side-by-side as you work through the guide in your terminal.
Architecture And Project Setup
Duration: 10
Before touching Snowflake, let's understand the pipeline and set up your local workspace.
The Clickstream Pipeline
The project models an e-commerce clickstream pipeline in three stages:
Raw Events (~50K) SESSIONS (~12K) FUNNEL_METRICS (8 rows) (EVENTS table) (SESSIONS table) (FUNNEL_METRICS table) [page_view, cart, ...] --> [session_id, user_id, --> [step, event_name, duration, revenue, ...] unique_users, ...] ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ Stage 1: Python Stage 2: PySpark (warehouse compute) (serverless Spark)
- Stage 1 –
sessionize.py(Python): Reads raw clickstream events, groups consecutive events from the same user into browsing sessions (using a configurable inactivity timeout, default 30 minutes), computes session-level aggregates (page views, carts, purchases, revenue), and writes aSESSIONStable. - Stage 2 –
analytics.py(PySpark): ReadsSESSIONS, runs an e-commerce funnel analysis using standard PySpark DataFrame operations (groupBy,agg,F.countDistinct), and writes aFUNNEL_METRICStable. This file uses nativepyspark.sqlimports and runs on Snowflake's native Spark engine. helpers.py: Shared utilities for both jobs – creating a Snowpark or PySpark session, and structured logging.
Clone the Companion Repository
Clone the companion repository and inspect the project structure:
git clone https://github.com/Snowflake-Labs/sfguide-run-python-and-spark-jobs-with-code-bundles.git cd sfguide-run-python-and-spark-jobs-with-code-bundles
sfguide-run-python-and-spark-jobs-with-code-bundles/ ├── setup.sql # Database, warehouse, stage, synthetic data ├── teardown.sql # Clean up all created objects ├── snowflake.yml # Snowflake CLI project definition (with code_bundle) └── src/ ├── bundle.yml # Bundle specification (entrypoints, env, warehouse) ├── requirements.txt # Dependencies installed into execution environment ├── sessionize.py # Python sessionization job (runs on warehouse) ├── analytics.py # PySpark funnel analysis job (runs on Spark engine) └── helpers.py # Shared session + logging utilities
Notice this is an ordinary Python project. The source files are in src/, with shared code imported across files. You do not need to convert anything into stored procedure handlers or flatten the directory structure.
Environment Setup
Duration: 10
Run setup.sql to create the database, warehouse, and stage, and generate ~50K synthetic clickstream events. You can run it with the Snowflake CLI or paste it into a Snowsight worksheet.
Run setup.sql
snow sql -f setup.sql
Or execute each block in Snowsight:
-- Create database, schema, and warehouse CREATE OR REPLACE DATABASE CODE_BUNDLES_QUICKSTART; CREATE OR REPLACE SCHEMA CODE_BUNDLES_QUICKSTART.CLICKSTREAM; CREATE OR REPLACE WAREHOUSE CODE_BUNDLES_WH WAREHOUSE_SIZE = 'X-SMALL' AUTO_SUSPEND = 60 AUTO_RESUME = TRUE; USE DATABASE CODE_BUNDLES_QUICKSTART; USE SCHEMA CLICKSTREAM; USE WAREHOUSE CODE_BUNDLES_WH; -- Stage for the code bundle artifacts CREATE OR REPLACE STAGE BUNDLE_STAGE DIRECTORY = (ENABLE = TRUE); -- Generate ~50K synthetic clickstream events across 2,500 users CREATE OR REPLACE TABLE EVENTS AS WITH RECURSIVE users AS ( SELECT SEQ4() AS user_id, 'user_' || LPAD(SEQ4()::VARCHAR, 6, '0') AS user_handle, CASE MOD(SEQ4(), 3) WHEN 0 THEN 'mobile' WHEN 1 THEN 'desktop' ELSE 'tablet' END AS device_type, CASE MOD(SEQ4(), 4) WHEN 0 THEN 'direct' WHEN 1 THEN 'organic_search' WHEN 2 THEN 'paid_ad' ELSE 'social' END AS traffic_source FROM TABLE(GENERATOR(ROWCOUNT => 2500)) ), event_seq AS ( SELECT SEQ4() AS event_idx, MOD(ABS(RANDOM()), 2500) AS user_id, -- Spread events over a 7-day window TIMESTAMPADD( SECOND, MOD(ABS(RANDOM()), 7 * 86400), '2025-01-01 00:00:00'::TIMESTAMP_NTZ ) AS event_time, UNIFORM(1, 100, RANDOM()) AS event_roll, ROUND(UNIFORM(500, 25000, RANDOM()) / 100.0, 2) AS price FROM TABLE(GENERATOR(ROWCOUNT => 50000)) ) SELECT UUID_STRING() AS event_id, u.user_handle AS user_id, e.event_time, CASE WHEN e.event_roll <= 50 THEN 'page_view' WHEN e.event_roll <= 75 THEN 'product_detail' WHEN e.event_roll <= 90 THEN 'add_to_cart' WHEN e.event_roll <= 97 THEN 'checkout_start' ELSE 'purchase' END AS event_name, CASE WHEN e.event_roll > 75 THEN e.price ELSE NULL END AS amount, u.device_type, u.traffic_source FROM event_seq e JOIN users u ON e.user_id = u.user_id ORDER BY e.event_time;
Verify the synthetic data:
SELECT event_name, COUNT(*) AS event_count, ROUND(AVG(amount), 2) AS avg_amount FROM EVENTS GROUP BY event_name ORDER BY event_count DESC;
You should see ~50,000 rows across five event types (page_view, product_detail, add_to_cart, checkout_start, purchase).
Anatomy Of A Code Bundle
Duration: 10
A Code Bundle is defined by two files: snowflake.yml (how Snowflake CLI packages and deploys the project) and src/bundle.yml (the bundle specification that tells Snowflake how to execute it).
snowflake.yml
Open snowflake.yml in the project root:
definition_version: '2' entities: clickstream_bundle: type: code_bundle identifier: name: CLICKSTREAM_BUNDLE database: CODE_BUNDLES_QUICKSTART schema: CLICKSTREAM stage: BUNDLE_STAGE spec: bundle.yml artifacts: - src/*
Key fields:
type: code_bundle– identifies this entity as a Code Bundleidentifier– the fully qualified database object name (CODE_BUNDLES_QUICKSTART.CLICKSTREAM.CLICKSTREAM_BUNDLE)stage– where the packaged artifacts are staged during deploymentspec– path to the bundle specification relative tosrc/artifacts– files included in the bundle; here, everything insrc/
src/bundle.yml
Open src/bundle.yml:
spec_version: 1.0 default: entrypoint: sessionize.py compute: warehouse: CODE_BUNDLES_WH runtime: language: python version: '3.11' dependencies: requirements: requirements.txt entrypoints: sessionize: file: sessionize.py compute: warehouse: CODE_BUNDLES_WH runtime: language: python version: '3.11' dependencies: requirements: requirements.txt analytics: file: analytics.py runtime: language: python version: '3.11' dependencies: requirements: requirements.txt
Let's break this down:
defaultblock: Specifies what runs if you execute the bundle without naming an entrypoint. It targetssessionize.pyon warehouseCODE_BUNDLES_WH.entrypoints.sessionize: Explicit entrypoint for the Python sessionizer. Noticecompute.warehouse– this tells Snowflake to run the script on warehouse compute.entrypoints.analytics: Entrypoint for the PySpark funnel analysis. Notice there is nocompute.warehouse– PySpark jobs run on Snowflake's native Spark engine, which does not require a warehouse or a Spark cluster.runtime: Declares Python 3.11 and points torequirements.txt. Snowflake installs these dependencies into the job's execution environment automatically.
Inspect the Code
Before deploying, take a quick look at src/sessionize.py and src/analytics.py.
src/sessionize.py uses standard Snowpark Python:
- Reads
EVENTSusing the active session - Uses window functions (
LAG) to detect session breaks when inactivity exceeds the threshold - Aggregates events within each session into metrics (page views, carts, purchases, revenue)
- Writes a
SESSIONStable – one row per session with dimensions (device, traffic source) carried forward
The key detail is get_session() in helpers.py. It calls get_active_session(), which returns the Snowpark session that Snowflake injects at runtime when the bundle executes:
# sessionize.py from helpers import get_session, log_step def main() -> None: args = parse_args() session = get_session() log_step(f"Sessionizing {args.source_table} (timeout: {args.inactivity_minutes} min)") session.sql(f""" -- Sessionization with window-based inactivity timeout ... """).collect()
src/analytics.py uses standard PySpark:
# analytics.py from pyspark.sql import functions as F from helpers import get_spark_session, log_step def main() -> None: spark = get_spark_session() log_step("Running funnel analysis with PySpark...") df = spark.table("CODE_BUNDLES_QUICKSTART.CLICKSTREAM.SESSIONS") # Funnel analysis using PySpark DataFrame operations funnel = df.select( F.countDistinct("USER_ID").alias("total_users"), F.countDistinct(F.when(F.col("PAGE_VIEWS") > 0, F.col("USER_ID"))).alias("viewed_page"), F.countDistinct(F.when(F.col("CART_ADDS") > 0, F.col("USER_ID"))).alias("added_to_cart"), F.countDistinct(F.when(F.col("PURCHASES") > 0, F.col("USER_ID"))).alias("purchased"), ) funnel.write.mode("overwrite").saveAsTable( "CODE_BUNDLES_QUICKSTART.CLICKSTREAM.FUNNEL_METRICS" )
Notice from pyspark.sql import functions as F. This is unmodified PySpark code. You do not need to rewrite it with Snowpark DataFrame syntax or configure Spark driver/executor memory.
Deploy The Code Bundle
Duration: 5
Deploy the project to Snowflake using the Snowflake CLI.
Deploy with snow code-bundle
From the project root directory:
snow code-bundle deploy
You should see output similar to:
Uploading artifacts to @CODE_BUNDLES_QUICKSTART.CLICKSTREAM.BUNDLE_STAGE/CLICKSTREAM_BUNDLE/... Creating or updating code bundle CLICKSTREAM_BUNDLE... Code bundle CLICKSTREAM_BUNDLE successfully deployed.
What Just Happened?
The CLI did two things:
- Packaged the files matching
artifactsinsnowflake.yml(src/*) and uploaded them to the stage@BUNDLE_STAGE. - Executed a
CREATE OR REPLACE CODE BUNDLEstatement in Snowflake, registering the bundle with its specification and linking it to the staged files.
Verify the bundle in Snowflake:
USE DATABASE CODE_BUNDLES_QUICKSTART; USE SCHEMA CLICKSTREAM; SHOW CODE BUNDLES;
You should see CLICKSTREAM_BUNDLE listed with its database, schema, and owner.
Describe the bundle to inspect its registered specification:
DESCRIBE CODE BUNDLE CLICKSTREAM_BUNDLE;
Run Python Jobs On Warehouse Compute
Duration: 10
Now execute the bundle's Python sessionizer on your warehouse using EXECUTE CODE BUNDLE.
Run the Default Entrypoint
Because bundle.yml declares sessionize.py as the default entrypoint with warehouse compute, you can run the bundle with no extra arguments:
USE DATABASE CODE_BUNDLES_QUICKSTART; USE SCHEMA CLICKSTREAM; USE WAREHOUSE CODE_BUNDLES_WH; EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE;
Or run it from your terminal using the Snowflake CLI:
snow sql -q "EXECUTE CODE BUNDLE CODE_BUNDLES_QUICKSTART.CLICKSTREAM.CLICKSTREAM_BUNDLE;"
When execution completes, query the generated SESSIONS table:
SELECT COUNT(*) AS total_sessions, COUNT(DISTINCT user_id) AS unique_users, ROUND(AVG(duration_minutes), 1) AS avg_duration_min, ROUND(AVG(page_views), 1) AS avg_page_views, SUM(has_purchase) AS sessions_with_purchase, ROUND(SUM(total_revenue), 2) AS total_revenue FROM SESSIONS;
You should see ~10K–15K sessions grouped from the ~50K raw events, with metrics for duration, page views, and revenue.
Run a Named Entrypoint
You can explicitly name the entrypoint to run:
EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE ENTRYPOINT = 'sessionize';
Pass CLI Arguments to the Script
The sessionize.py script accepts --inactivity-minutes, --source-table, and --target-table command-line arguments. Pass them using the ARGS parameter:
EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE ENTRYPOINT = 'sessionize' ARGS = ('--inactivity-minutes', '45', '--target-table', 'SESSIONS_45MIN');
Verify that the 45-minute timeout produced fewer, longer sessions:
SELECT '30-min timeout' AS run_type, COUNT(*) AS total_sessions, ROUND(AVG(duration_minutes), 1) AS avg_duration_min FROM SESSIONS UNION ALL SELECT '45-min timeout' AS run_type, COUNT(*) AS total_sessions, ROUND(AVG(duration_minutes), 1) AS avg_duration_min FROM SESSIONS_45MIN;
Override the Specification at Runtime
You can override any part of the bundle specification at execution time with WITH SPECIFICATION. For example, run on a different warehouse or set an environment variable:
EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE ENTRYPOINT = 'sessionize' WITH SPECIFICATION = $$ compute: warehouse: CODE_BUNDLES_WH env: LOG_LEVEL: DEBUG $$;
This is powerful for testing: you can point a job at an ad-hoc warehouse or enable debug logging without redeploying the bundle.
Run PySpark Jobs With No Spark Cluster
Duration: 10
Now run the PySpark analytics job from the same bundle. It uses native pyspark.sql imports, runs on Snowflake's managed Spark engine, and requires no Spark cluster to be configured, provisioned, or maintained.
Submit via the Spark REST API
Snowflake provides a Spark-compatible REST API for submitting Spark jobs. You can submit directly with curl.
First, get a session token using the Snowflake CLI:
export SNOWFLAKE_TOKEN=$(snow connection test --format json | python3 -c "import sys, json; print(json.load(sys.stdin).get('token', ''))")
Or generate an authorization token from your current connection. Alternatively, retrieve your account identifier:
export SNOWFLAKE_ACCOUNT=$(snow connection test --format json | python3 -c "import sys, json; print(json.load(sys.stdin).get('account', ''))")
Submit the PySpark job by referencing the staged file from the bundle:
curl -X POST \ "https://${SNOWFLAKE_ACCOUNT}.snowflakecomputing.com/api/v2/spark/jobs" \ -H "Authorization: Bearer ${SNOWFLAKE_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "mainApplicationFile": "@CODE_BUNDLES_QUICKSTART.CLICKSTREAM.BUNDLE_STAGE/CLICKSTREAM_BUNDLE/analytics.py", "appArgs": [ "--source-table", "CODE_BUNDLES_QUICKSTART.CLICKSTREAM.SESSIONS", "--target-table", "CODE_BUNDLES_QUICKSTART.CLICKSTREAM.FUNNEL_METRICS" ], "sparkProperties": { "spark.snowflake.database": "CODE_BUNDLES_QUICKSTART", "spark.snowflake.schema": "CLICKSTREAM" } }'
The response returns a job ID:
{ "jobId": "spark-job-01b4c8a2-7e3f-4a1d-9e0a-123456789abc", "status": "SUBMITTED" }
Monitor the Spark Job
Check the job status using the job ID returned above:
curl -X GET \ "https://${SNOWFLAKE_ACCOUNT}.snowflakecomputing.com/api/v2/spark/jobs/<JOB_ID>" \ -H "Authorization: Bearer ${SNOWFLAKE_TOKEN}"
The status transitions from SUBMITTED → RUNNING → SUCCEEDED.
Run the Spark Entrypoint via SQL
You can also execute the Spark entrypoint directly from SQL using EXECUTE CODE BUNDLE:
USE DATABASE CODE_BUNDLES_QUICKSTART; USE SCHEMA CLICKSTREAM; EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE ENTRYPOINT = 'analytics';
Verify Funnel Metrics
Once the PySpark job completes, query the FUNNEL_METRICS table:
SELECT step_number, step_name, unique_users, conversion_rate_pct, dropoff_rate_pct FROM FUNNEL_METRICS ORDER BY step_number ASC;
You should see the full e-commerce funnel calculated by PySpark:
+-------------+------------------+--------------+---------------------+------------------+ | STEP_NUMBER | STEP_NAME | UNIQUE_USERS | CONVERSION_RATE_PCT | DROPOFF_RATE_PCT | +-------------+------------------+--------------+---------------------+------------------+ | 1 | Homepage / Land | 2500 | 100.00 | 0.00 | | 2 | Product Detail | 2180 | 87.20 | 12.80 | | 3 | Add to Cart | 1425 | 57.00 | 34.63 | | 4 | Checkout Start | 710 | 28.40 | 50.18 | | 5 | Purchase | 380 | 15.20 | 46.48 | +-------------+------------------+--------------+---------------------+------------------+
The PySpark job ran natively on Snowflake compute, read from a Snowflake table, processed data using the Spark DataFrame API, and wrote the results back – with zero Spark infrastructure for you to manage.
Orchestrate With Snowflake Tasks
Duration: 10
Now connect both stages into an automated, scheduled pipeline using Snowflake Tasks. The first task runs the Python sessionizer; the second runs the PySpark funnel analytics upon completion.
Create the Task Graph
USE DATABASE CODE_BUNDLES_QUICKSTART; USE SCHEMA CLICKSTREAM; USE WAREHOUSE CODE_BUNDLES_WH; -- Root task: Run Python sessionizer on a daily schedule CREATE OR REPLACE TASK CLICKSTREAM_SESSIONIZE_TASK WAREHOUSE = CODE_BUNDLES_WH SCHEDULE = 'USING CRON 0 2 * * * UTC' -- Daily at 2:00 AM UTC AS EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE ENTRYPOINT = 'sessionize'; -- Child task: Run PySpark funnel analysis after sessionization completes CREATE OR REPLACE TASK CLICKSTREAM_ANALYTICS_TASK AFTER CLICKSTREAM_SESSIONIZE_TASK AS EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE ENTRYPOINT = 'analytics';
Notice the child task CLICKSTREAM_ANALYTICS_TASK does not specify a WAREHOUSE – the Spark engine manages its own serverless compute.
Test the Pipeline Manually
Resume both tasks (tasks are created in a suspended state by default) and trigger an immediate run:
-- Child tasks must be resumed before root tasks ALTER TASK CLICKSTREAM_ANALYTICS_TASK RESUME; ALTER TASK CLICKSTREAM_SESSIONIZE_TASK RESUME; -- Trigger an immediate manual run of the root task EXECUTE TASK CLICKSTREAM_SESSIONIZE_TASK;
Monitor Task Execution
Track the execution of both tasks through the task graph history:
SELECT name, state, scheduled_time, completed_time, TIMESTAMPDIFF('second', scheduled_time, completed_time) AS duration_seconds, error_message FROM TABLE(INFORMATION_SCHEMA.TASK_HISTORY( TASK_NAME => 'CLICKSTREAM_SESSIONIZE_TASK', SCHEDULED_TIME_RANGE_START => DATEADD('hour', -1, CURRENT_TIMESTAMP()) )) ORDER BY scheduled_time DESC; SELECT name, state, scheduled_time, completed_time, TIMESTAMPDIFF('second', scheduled_time, completed_time) AS duration_seconds, error_message FROM TABLE(INFORMATION_SCHEMA.TASK_HISTORY( TASK_NAME => 'CLICKSTREAM_ANALYTICS_TASK', SCHEDULED_TIME_RANGE_START => DATEADD('hour', -1, CURRENT_TIMESTAMP()) )) ORDER BY scheduled_time DESC;
You'll see CLICKSTREAM_SESSIONIZE_TASK enter SUCCESS, which immediately triggers CLICKSTREAM_ANALYTICS_TASK to run.
Production Patterns: Versioning, Async, Monitoring
Duration: 10
Here are three essential patterns for running Code Bundles in production.
Pattern 1: Versioning and Aliases
Code Bundles support versioning and aliases, allowing you to deploy new code without breaking downstream consumers or tasks.
# Deploy a new version snow code-bundle deploy --version v1.1.0 # Or deploy with an alias snow code-bundle deploy --version v1.1.0 --alias prod
In SQL, you can execute a specific version or alias:
-- Execute a specific version EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE VERSION = 'v1.1.0'; -- Execute via alias EXECUTE CODE BUNDLE CLICKSTREAM_BUNDLE ALIAS = 'prod';
Manage versions with SQL DDL:
-- List registered versions SHOW VERSIONS IN CODE BUNDLE CLICKSTREAM_BUNDLE; -- Point the prod alias to a different version (instant rollback) ALTER CODE BUNDLE CLICKSTREAM_BUNDLE SET ALIAS prod = 'v1.0.0'; -- Drop an old version ALTER CODE BUNDLE CLICKSTREAM_BUNDLE DROP VERSION 'v0.9.0';
Your Snowflake Tasks can point to ALIAS = 'prod', giving you zero-downtime updates and one-statement rollbacks.
Pattern 2: Asynchronous Execution and Status Checking
For long-running jobs, execute the bundle asynchronously and poll for completion:
snow sql -q "EXECUTE CODE BUNDLE CODE_BUNDLES_QUICKSTART.CLICKSTREAM.CLICKSTREAM_BUNDLE;" --async
The --async flag returns a Query ID immediately:
Query ID: 01b4c8a2-0001-2345-0000-123456789abc Status: RUNNING
Check the status of an in-flight job using the Query ID:
SELECT query_id, query_text, execution_status, warehouse_name, start_time, end_time, total_elapsed_time / 1000 AS elapsed_seconds, error_code, error_message FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY()) WHERE query_id = '01b4c8a2-0001-2345-0000-123456789abc';
Pattern 3: Centralized Monitoring and Query History
Because EXECUTE CODE BUNDLE runs on Snowflake compute, every execution appears in standard Snowflake governance views:
-- Find all Code Bundle executions in the last 24 hours SELECT query_id, user_name, warehouse_name, execution_status, start_time, end_time, ROUND(total_elapsed_time / 1000.0, 1) AS elapsed_sec, ROUND(compilation_time / 1000.0, 1) AS compile_sec, ROUND(execution_time / 1000.0, 1) AS exec_sec FROM TABLE(INFORMATION_SCHEMA.QUERY_HISTORY( END_TIME_RANGE_START => DATEADD('hour', -24, CURRENT_TIMESTAMP()) )) WHERE query_text ILIKE '%EXECUTE CODE BUNDLE%' ORDER BY start_time DESC;
You get complete auditability, credit attribution, and performance history out of the box – no external monitoring agent required.
Clean Up
Duration: 5
To remove all objects created in this Quickstart, run teardown.sql:
snow sql -f teardown.sql
Or execute in Snowsight:
-- Suspend tasks first ALTER TASK IF EXISTS CLICKSTREAM_SESSIONIZE_TASK SUSPEND; ALTER TASK IF EXISTS CLICKSTREAM_ANALYTICS_TASK SUSPEND; -- Drop all objects DROP DATABASE IF EXISTS CODE_BUNDLES_QUICKSTART; DROP WAREHOUSE IF EXISTS CODE_BUNDLES_WH;
Conclusion And Resources
Duration: 5
Congratulations! You've successfully packaged and executed a multi-stage data pipeline on Snowflake using Code Bundles.
What You Learned
- How to package a multi-file Python project into a Code Bundle using the Snowflake CLI
- How to define entrypoints, dependencies, and compute targets in
bundle.yml - How to run Python jobs on a warehouse with
EXECUTE CODE BUNDLEand pass dynamic arguments - How to override specifications at runtime with
WITH SPECIFICATION - How to run PySpark jobs natively on Snowflake with no Spark cluster or driver/executor sizing
- How to chain Python and PySpark bundle executions into a scheduled pipeline with Snowflake Tasks
- How to apply production patterns: versioning with aliases, asynchronous runs, and centralized observability
Related Resources
This content is provided as is, and is not maintained on an ongoing basis. It may be out of date with current Snowflake instances