From 82ad19883cc2b3e9da4ead1e8b9c8dbe1763e0b6 Mon Sep 17 00:00:00 2001 From: Alex Strick van Linschoten Date: Thu, 12 Jun 2025 14:29:58 +0000 Subject: [PATCH 01/16] Clean up docstrings --- pipelines/fanOut/fan_pipeline.py | 8 -------- pipelines/retries/robust_pipeline.py | 5 ----- pipelines/tagging/tagged_pipeline.py | 9 --------- 3 files changed, 22 deletions(-) diff --git a/pipelines/fanOut/fan_pipeline.py b/pipelines/fanOut/fan_pipeline.py index c2f92a9..35c1a20 100644 --- a/pipelines/fanOut/fan_pipeline.py +++ b/pipelines/fanOut/fan_pipeline.py @@ -1,11 +1,3 @@ -""" -Shows parallel fan-out (multiple identical steps) and a fan-in step that -gathers all their outputs via the Client API. - -Run it once and observe the printed summary. Re-run: cache is OFF so you -see the steps execute every time. -""" - from typing_extensions import Annotated from zenml import get_step_context, pipeline, step from zenml.client import Client diff --git a/pipelines/retries/robust_pipeline.py b/pipelines/retries/robust_pipeline.py index 69efa63..24d4b5f 100644 --- a/pipelines/retries/robust_pipeline.py +++ b/pipelines/retries/robust_pipeline.py @@ -1,8 +1,3 @@ -""" -Demonstrates automatic retries *and* a failure hook. -Run it a few times – roughly half will need 1–2 retries. -""" - import random import time diff --git a/pipelines/tagging/tagged_pipeline.py b/pipelines/tagging/tagged_pipeline.py index d2b86c9..e353c49 100644 --- a/pipelines/tagging/tagged_pipeline.py +++ b/pipelines/tagging/tagged_pipeline.py @@ -1,12 +1,3 @@ -""" -Artifact Tagging Demonstration -This example shows different ways to tag artifacts in ZenML: -1. Regular tags on artifacts using ArtifactConfig -2. Cascade tags from pipeline to artifacts -3. Dynamic tagging within steps -4. Filtering artifacts by tags -""" - from typing import Annotated import pandas as pd From 4be8ed533b3ec73f67625b749d43e46264d84edb Mon Sep 17 00:00:00 2001 From: Alex Strick van Linschoten Date: Thu, 12 Jun 2025 14:31:42 +0000 Subject: [PATCH 02/16] Update congratulations text --- pipelines/completion/completion.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipelines/completion/completion.md b/pipelines/completion/completion.md index 1f7d7a0..afebd6d 100644 --- a/pipelines/completion/completion.md +++ b/pipelines/completion/completion.md @@ -14,7 +14,7 @@ You Completed the Tutorial -You've successfully completed the **ZenML Interactive Tutorial** and mastered the fundamentals of MLOps with ZenML! +You've successfully completed the **ZenML Interactive Tutorial** and mastered the fundamentals of using ZenML for MLOps!
From aff6bae1f130d82cd2bc841e2e90bc869d33710b Mon Sep 17 00:00:00 2001 From: Alex Strick van Linschoten Date: Thu, 12 Jun 2025 14:47:58 +0000 Subject: [PATCH 03/16] Increase tutorial header title font size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Increased the font size from 1rem to 1.25rem to make the tutorial title more prominent in the header while maintaining visual balance with the description text. šŸ¤– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- assets/main.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/main.css b/assets/main.css index ac44b1d..25e05c5 100644 --- a/assets/main.css +++ b/assets/main.css @@ -319,7 +319,7 @@ header { } .tutorial-title h2 { - font-size: 1rem; + font-size: 1.25rem; font-weight: 600; color: var(--zenml-dark); margin: 0; From 155064d95d5ce3c02d4dfadafed81da800002b63 Mon Sep 17 00:00:00 2001 From: Alex Strick van Linschoten Date: Thu, 12 Jun 2025 14:51:02 +0000 Subject: [PATCH 04/16] Remove h1 headers from tutorial markdown files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed the h1 headers and top-level descriptions from all tutorial markdown files to avoid duplication with the tutorial header display in the VSCode extension. šŸ¤– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- pipelines/caching/caching.md | 7 ++----- pipelines/fanOut/fanOut.md | 7 ++----- pipelines/helloWorld/helloWorld.md | 5 ++--- pipelines/metadata/metadata.md | 6 +----- pipelines/parameters/parameters.md | 6 +----- pipelines/retries/retries.md | 7 ++----- pipelines/stepIO/stepIO.md | 7 ++----- pipelines/tagging/tagging.md | 7 ++----- pipelines/visualizations/visualizations.md | 7 ++----- pipelines/welcome/welcome.md | 2 +- 10 files changed, 17 insertions(+), 44 deletions(-) diff --git a/pipelines/caching/caching.md b/pipelines/caching/caching.md index 1d89a4f..06ad35b 100644 --- a/pipelines/caching/caching.md +++ b/pipelines/caching/caching.md @@ -1,7 +1,3 @@ -# Caching - Smart Re-runs - -Learn how ZenML's caching system can save you time by avoiding redundant computations. - ## What you'll learn - How to enable caching on steps @@ -28,4 +24,5 @@ def slow_step() -> Annotated[int, "answer"]: ## Try it yourself -Run this pipeline twice! The first run takes ~3 seconds, the second is instant thanks to caching. \ No newline at end of file +Run this pipeline twice! The first run takes ~3 seconds, the second is instant +thanks to caching. diff --git a/pipelines/fanOut/fanOut.md b/pipelines/fanOut/fanOut.md index 2a981dc..c15ffa5 100644 --- a/pipelines/fanOut/fanOut.md +++ b/pipelines/fanOut/fanOut.md @@ -1,7 +1,3 @@ -# Fan-out/Fan-in - Parallel Processing - -Learn how to create parallel workflows that split work across multiple steps and then combine the results. - ## What you'll learn - How to create parallel processing patterns @@ -29,4 +25,5 @@ def fan_pipeline(parallel: int = 4): ## Try it yourself -Run this pipeline to see how it processes data in parallel across multiple steps, then combines the results! \ No newline at end of file +Run this pipeline to see how it processes data in parallel across multiple +steps, then combines the results! diff --git a/pipelines/helloWorld/helloWorld.md b/pipelines/helloWorld/helloWorld.md index e510199..a3edffe 100644 --- a/pipelines/helloWorld/helloWorld.md +++ b/pipelines/helloWorld/helloWorld.md @@ -1,5 +1,3 @@ -# Hello World - Steps & Pipelines - Welcome to your first ZenML pipeline! This tutorial introduces the fundamental concepts of **steps** and **pipelines**. ## What you'll learn @@ -30,4 +28,5 @@ def hello_pipeline(): ## Try it yourself -Click the **Run Pipeline** button to execute your first ZenML pipeline and see the output! \ No newline at end of file +Click the **Run Pipeline** button to execute your first ZenML pipeline and see +the output! diff --git a/pipelines/metadata/metadata.md b/pipelines/metadata/metadata.md index 36d9674..a5238ce 100644 --- a/pipelines/metadata/metadata.md +++ b/pipelines/metadata/metadata.md @@ -1,7 +1,3 @@ -# Metadata - Recording Useful Facts - -Learn how to log metadata to track important information about your pipeline runs. - ## What you'll learn - How to use `log_metadata()` to record key information @@ -29,4 +25,4 @@ def compute_accuracy() -> Annotated[float, "accuracy_metric"]: ## Try it yourself -Run this pipeline and check the ZenML dashboard to see the metadata card! \ No newline at end of file +Run this pipeline and check the ZenML dashboard to see the metadata card! diff --git a/pipelines/parameters/parameters.md b/pipelines/parameters/parameters.md index 64fc8d0..ac05558 100644 --- a/pipelines/parameters/parameters.md +++ b/pipelines/parameters/parameters.md @@ -1,7 +1,3 @@ -# Parameters - Configurable Behavior - -Learn how to make your pipelines configurable with parameters. - ## What you'll learn - How to add parameters to steps and pipelines @@ -31,4 +27,4 @@ def param_pipeline(number: int = 3, factor: int = 2): ## Try it yourself -Run this pipeline to see how parameters control the multiplication operation! \ No newline at end of file +Run this pipeline to see how parameters control the multiplication operation! diff --git a/pipelines/retries/retries.md b/pipelines/retries/retries.md index 59aaef6..80affb7 100644 --- a/pipelines/retries/retries.md +++ b/pipelines/retries/retries.md @@ -1,7 +1,3 @@ -# Retries & Hooks - Robust Pipelines - -Learn how to build resilient pipelines that can handle failures gracefully with automatic retries and hooks. - ## What you'll learn - How to configure automatic retries for flaky steps @@ -32,4 +28,5 @@ def flaky() -> Annotated[str, "result"]: ## Try it yourself -Run this pipeline multiple times! Sometimes it succeeds immediately, sometimes it needs retries to handle the random failures. \ No newline at end of file +Run this pipeline multiple times! Sometimes it succeeds immediately, sometimes +it needs retries to handle the random failures. diff --git a/pipelines/stepIO/stepIO.md b/pipelines/stepIO/stepIO.md index 5a70396..1c3058f 100644 --- a/pipelines/stepIO/stepIO.md +++ b/pipelines/stepIO/stepIO.md @@ -1,7 +1,3 @@ -# Step I/O - Typed Inputs and Outputs - -Now let's learn how to pass data between steps with proper type annotations. - ## What you'll learn - How to define typed step outputs using `Annotated` types @@ -37,4 +33,5 @@ def count_rows( ## Try it yourself -Run this pipeline to see how data flows from the `load_data` step to the `count_rows` step! \ No newline at end of file +Run this pipeline to see how data flows from the `load_data` step to the +`count_rows` step! diff --git a/pipelines/tagging/tagging.md b/pipelines/tagging/tagging.md index aea40f2..098dfbe 100644 --- a/pipelines/tagging/tagging.md +++ b/pipelines/tagging/tagging.md @@ -1,7 +1,3 @@ -# Tagging - Keep Runs Organized - -Learn how to use tags to organize and categorize your pipeline runs. - ## What you'll learn - How to add simple tags to pipelines @@ -27,4 +23,5 @@ def tagged_pipeline(): ## Try it yourself -Run this pipeline multiple times and watch how the exclusive tag automatically moves to the latest run! \ No newline at end of file +Run this pipeline multiple times and watch how the exclusive tag automatically +moves to the latest run! diff --git a/pipelines/visualizations/visualizations.md b/pipelines/visualizations/visualizations.md index 8de6779..b84e93f 100644 --- a/pipelines/visualizations/visualizations.md +++ b/pipelines/visualizations/visualizations.md @@ -1,7 +1,3 @@ -# Visualizations - Custom Charts - -Learn how to create automatic and custom visualizations that appear in the ZenML dashboard. - ## What you'll learn - How ZenML automatically visualizes common data types @@ -32,4 +28,5 @@ def scatter(df: pd.DataFrame) -> Annotated[HTMLString, "scatter_plot"]: ## Try it yourself -Run this pipeline and check the dashboard to see both the automatic DataFrame visualization and the custom scatter plot! \ No newline at end of file +Run this pipeline and check the dashboard to see both the automatic DataFrame +visualization and the custom scatter plot! diff --git a/pipelines/welcome/welcome.md b/pipelines/welcome/welcome.md index ad5e630..f1b9e4c 100644 --- a/pipelines/welcome/welcome.md +++ b/pipelines/welcome/welcome.md @@ -1,7 +1,7 @@
-# Welcome to ZenML Interactive Tutorial! +# Welcome to the ZenML Interactive Tutorial! This hands-on tutorial will teach you **ZenML fundamentals** through 10 progressive lessons. Each lesson introduces exactly **one new concept** with copy-paste code examples. From 522354a9848aced5ef2ec4f2836323541e0d4acb Mon Sep 17 00:00:00 2001 From: Alex Strick van Linschoten Date: Thu, 12 Jun 2025 15:05:19 +0000 Subject: [PATCH 05/16] Improve caching pipeline logging clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Enhanced logging in cache_pipeline.py to clearly show which run uses cache - Added ASCII separators to visually distinguish between Run 1 and Run 2 - Simplified step logging to focus on the key concept - Added explanatory note highlighting that cached steps are skipped entirely - Updated utils.py separator width for consistency These changes make it much clearer to students when caching is happening and how it affects pipeline execution. šŸ¤– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- pipelines/caching/cache_pipeline.py | 20 +++++++++++++------- utils.py | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pipelines/caching/cache_pipeline.py b/pipelines/caching/cache_pipeline.py index 106786d..19277ec 100644 --- a/pipelines/caching/cache_pipeline.py +++ b/pipelines/caching/cache_pipeline.py @@ -11,9 +11,8 @@ @step(enable_cache=True) def slow_step() -> Annotated[int, "answer"]: - logger.info("Starting slow computation (3 seconds)...") + logger.info("šŸ”„ Actually computing result... (sleeping 3 seconds)") time.sleep(3) - logger.info("Computation completed!") return 42 @@ -23,10 +22,17 @@ def cache_pipeline(): if __name__ == "__main__": - logger.info("First run - will take ~3 seconds") - cache_pipeline() # first run ~3 s - - logger.info("Second run - should be instant (cache hit)") - cache_pipeline() # second run instant (cache hit) + logger.info("\n" + "="*60) + logger.info(">>> RUN 1: First execution (no cache available)") + logger.info("="*60) + cache_pipeline() + + logger.info("\n" + "="*60) + logger.info(">>> RUN 2: Second execution (cache should be used)") + logger.info("="*60) + cache_pipeline() + + logger.info("\nšŸ’” Notice: The step's log message only appears in Run 1!") + logger.info(" In Run 2, the step was skipped entirely due to caching.") log_dashboard_urls("cache_pipeline") diff --git a/utils.py b/utils.py index c457ee6..2569f6c 100644 --- a/utils.py +++ b/utils.py @@ -19,9 +19,9 @@ def log_dashboard_urls(pipeline_name: str): ) dashboard_url = f"{base_url}/runs/{run.id}" - logger.info("\n" + "=" * 50) + logger.info("\n" + "=" * 60) logger.info("āœ… Pipeline execution complete!") logger.info(f"🌐 View pipeline in dashboard: {base_url}/pipelines/{pipeline_name}") logger.info(f"🌐 View this run: {dashboard_url}") logger.info(f"🌐 View all artifacts: {base_url}/artifacts") - logger.info("=" * 50) + logger.info("=" * 60) From 21e9ead3fc1165df2b088caf89e8a44fd6def862 Mon Sep 17 00:00:00 2001 From: Alex Strick van Linschoten Date: Fri, 13 Jun 2025 08:09:47 +0000 Subject: [PATCH 06/16] Add image showing dashboard visualization --- .../visualizations/visualizations-dashboard.png | Bin 0 -> 88332 bytes pipelines/visualizations/visualizations.md | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 pipelines/visualizations/visualizations-dashboard.png diff --git a/pipelines/visualizations/visualizations-dashboard.png b/pipelines/visualizations/visualizations-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..c67235a4ee821304eb7c0c7b68e9f345db131e8d GIT binary patch literal 88332 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 Annotated[HTMLString, "scatter_plot"]: - **HTMLString type** lets you embed rich content in the dashboard - **Dashboard integration** makes results easily shareable +![Two visualizations generated by this pipeline](./pipelines/visualizations/visualizations-dashboard.png) + ## Try it yourself Run this pipeline and check the dashboard to see both the automatic DataFrame From 084f3fe53ec24b113e434850908acd6f72d7bba3 Mon Sep 17 00:00:00 2001 From: Alex Strick van Linschoten Date: Fri, 13 Jun 2025 09:08:13 +0000 Subject: [PATCH 07/16] Add split button design for dashboard access after pipeline completion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace single "Completed" button with split design showing both completion status and dashboard link - Add "Open Dashboard" button that appears next to green "Completed" button after pipeline runs - Capture actual dashboard URL from Python output to link directly to specific run - Style dashboard button with secondary VSCode theme for visual hierarchy - Make completed button non-interactive while keeping visual feedback This improves discoverability of the ZenML dashboard, especially for tutorials that produce interesting artifacts like visualizations. šŸ¤– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- assets/main.css | 96 +++++++++++++++++++++++++++++++++++++ assets/main.js | 19 +++++--- src/tutorialOrchestrator.ts | 45 ++++++++++------- src/utils/codeRunner.ts | 32 +++++++++++-- 4 files changed, 164 insertions(+), 28 deletions(-) diff --git a/assets/main.css b/assets/main.css index 25e05c5..24ff189 100644 --- a/assets/main.css +++ b/assets/main.css @@ -448,6 +448,13 @@ footer .run-pipeline-button.running { footer .run-pipeline-button.completed { background: var(--zenml-green); color: white; + cursor: default; +} + +footer .run-pipeline-button.completed:hover { + background: var(--zenml-green); + transform: none; + box-shadow: none; } footer .run-pipeline-button.failed { @@ -455,6 +462,95 @@ footer .run-pipeline-button.failed { color: white; } +/* Dashboard button styling */ +.dashboard-button { + background: var(--zenml-purple); + border: none; + color: #ffffff; + padding: 10px 20px; + border-radius: 6px; + font-size: 14px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 8px; + min-width: 140px; + justify-content: center; + font-family: "Inter", sans-serif; + margin: 0; + height: 40px; + text-decoration: none; + flex-shrink: 0; +} + +.dashboard-button:hover { + background: var(--zenml-purple-dark); + transform: translateY(-1px); + box-shadow: 0 2px 8px rgba(122, 62, 244, 0.3); + color: white; + text-decoration: none; +} + +.dashboard-button:active { + transform: translateY(0); +} + +.dashboard-button:visited { + color: white; +} + +.dashboard-button .codicon { + font-size: 16px; +} + +/* Pipeline button group */ +.pipeline-button-group { + display: flex; + gap: 8px; + align-items: center; +} + +/* Dashboard button styling - smaller variant */ +.dashboard-button-small { + background: var(--vscode-button-secondaryBackground); + border: 1px solid var(--vscode-sideBar-border); + color: var(--vscode-button-secondaryForeground); + padding: 8px 16px; + border-radius: 6px; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + display: flex; + align-items: center; + gap: 6px; + justify-content: center; + font-family: "Inter", sans-serif; + margin: 0; + height: 36px; + text-decoration: none; + flex-shrink: 0; + white-space: nowrap; +} + +.dashboard-button-small:hover { + background: var(--vscode-button-secondaryHoverBackground); + transform: translateY(-1px); + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); + color: var(--vscode-button-secondaryForeground); + text-decoration: none; +} + +.dashboard-button-small:active { + transform: translateY(0); +} + +.dashboard-button-small .codicon { + font-size: 14px; +} + #progress { height: 4px; background-color: var(--vscode-progressBar-background); diff --git a/assets/main.js b/assets/main.js index f609a1f..71eedd8 100644 --- a/assets/main.js +++ b/assets/main.js @@ -476,7 +476,8 @@ } else if (status === "completed" || status === "cached") { runButton.innerHTML = `āœ“ ${buttonTexts[status]}`; //@ts-ignore - runButton.disabled = false; + runButton.disabled = true; + runButton.style.cursor = "default"; } else if (status === "failed") { runButton.innerHTML = ` ${buttonTexts[status]}`; //@ts-ignore @@ -493,14 +494,18 @@ } function showDashboardUrl(url) { - const dashboardLink = document.getElementById("dashboard-link"); - const dashboardUrl = document.getElementById("dashboard-url"); + const dashboardButton = document.getElementById("dashboard-button"); - if (dashboardLink && dashboardUrl) { + if (dashboardButton) { //@ts-ignore - dashboardUrl.href = url; - dashboardUrl.textContent = "View Pipeline in Dashboard"; - dashboardLink.style.display = "flex"; + dashboardButton.href = url; + dashboardButton.style.display = "flex"; + + // Add click handler to open in external browser + dashboardButton.onclick = function(e) { + e.preventDefault(); + vscode.postMessage({ type: "openDashboard", url: url }); + }; } } diff --git a/src/tutorialOrchestrator.ts b/src/tutorialOrchestrator.ts index 94a5ec1..23d7169 100644 --- a/src/tutorialOrchestrator.ts +++ b/src/tutorialOrchestrator.ts @@ -27,8 +27,15 @@ export default class TutorialOrchestrator { private _getDashboardUrl(runId?: string): string { const baseUrl = vscode.workspace .getConfiguration("zenml") - .get("dashboardUrl", "http://localhost:8080"); - return runId ? `${baseUrl}/workspaces/default/runs/${runId}` : baseUrl; + .get("dashboardUrl", "https://cloud.zenml.io"); + // If we have a run ID, show specific run, otherwise show pipelines page + if (runId) { + return `${baseUrl}/workspaces/default/runs/${runId}`; + } else { + // Get the current pipeline name from the tutorial section + const pipelineName = this._tutorial.currentSection.code()?.split('/').pop()?.replace('.py', '') || 'pipelines'; + return `${baseUrl}/workspaces/default/pipelines`; + } } constructor(context: vscode.ExtensionContext, tutorial: Tutorial) { @@ -142,7 +149,7 @@ export default class TutorialOrchestrator { codeRunner( this.terminal, this._codePanel.document.uri, - () => { + (dashboardUrl?: string) => { vscode.window.showInformationMessage("Code Ran Successfully! šŸŽ‰"); if (callback) { callback(); @@ -196,7 +203,7 @@ export default class TutorialOrchestrator { codeRunner( this.terminal, this._codePanel.document.uri, - (runId?: string) => { + (dashboardUrl?: string) => { // Pipeline completed successfully this._pipelineRunning = false; this._completedTutorials.add(this._tutorial.currentSection.index); @@ -204,19 +211,17 @@ export default class TutorialOrchestrator { type: "pipelineStatusUpdate", status: "completed", }); - this._sendWebviewMessage({ type: "pipelineCompleted", runId: runId }); + this._sendWebviewMessage({ type: "pipelineCompleted" }); // Save progress this._saveProgress(); - // Show dashboard URL - if (runId) { - const dashboardUrl = this._getDashboardUrl(runId); - this._sendWebviewMessage({ - type: "showDashboardUrl", - url: dashboardUrl, - }); - } + // Show dashboard URL - use the captured URL or fallback to generic + const finalDashboardUrl = dashboardUrl || this._getDashboardUrl(); + this._sendWebviewMessage({ + type: "showDashboardUrl", + url: finalDashboardUrl, + }); }, () => { // Pipeline failed @@ -779,10 +784,16 @@ export default class TutorialOrchestrator { Prev - +
+ + +