1+ """
2+ Console and Rich utility functions for MCP tutorial labs.
3+ This module provides consistent console output formatting across all MCP lab exercises.
4+ """
5+
6+ from rich .console import Console
7+ from rich .panel import Panel
8+ from rich .prompt import Prompt
9+ from rich .markdown import Markdown
10+ from rich .progress import Progress , SpinnerColumn , TextColumn
11+ from rich .syntax import Syntax
12+ from rich .table import Table
13+ from rich .text import Text
14+ import time
15+ import asyncio
16+
17+ # Initialize the global console
18+ console = Console ()
19+
20+ def display_header (title : str , subtitle : str = None ):
21+ """Display a formatted header for lab exercises."""
22+ console .print ()
23+ console .print (Panel (
24+ f"[bold blue]{ title } [/]" + (f"\n [yellow]{ subtitle } [/]" if subtitle else "" ),
25+ title = "🔧 MCP Tutorial" ,
26+ title_align = "left" ,
27+ border_style = "blue" ,
28+ padding = (1 , 2 )
29+ ))
30+ console .print ()
31+
32+ def display_info_panel (content : str , title : str = "ℹ️ Information" , style : str = "cyan" ):
33+ """Display information in a styled panel."""
34+ console .print (Panel (
35+ Markdown (content ),
36+ title = title ,
37+ title_align = "left" ,
38+ border_style = style ,
39+ padding = (1 , 2 ),
40+ expand = False
41+ ))
42+ console .print ()
43+
44+ def display_success_panel (content : str , title : str = "✅ Success" ):
45+ """Display success message in a green panel."""
46+ console .print (Panel (
47+ Markdown (content ),
48+ title = title ,
49+ title_align = "left" ,
50+ border_style = "green" ,
51+ padding = (1 , 2 ),
52+ expand = False
53+ ))
54+ console .print ()
55+
56+ def display_error_panel (content : str , title : str = "❌ Error" ):
57+ """Display error message in a red panel."""
58+ console .print (Panel (
59+ Markdown (content ),
60+ title = title ,
61+ title_align = "left" ,
62+ border_style = "red" ,
63+ padding = (1 , 2 ),
64+ expand = False
65+ ))
66+ console .print ()
67+
68+ def display_code_panel (code : str , language : str = "python" , title : str = "📝 Code Example" ):
69+ """Display code in a syntax-highlighted panel."""
70+ import textwrap
71+
72+ # Clean up the code formatting
73+ code = textwrap .dedent (code ).strip ()
74+
75+ # Display title separately
76+ console .print (f"[bold yellow]{ title } [/]" )
77+ console .print ("─" * 50 )
78+
79+ # Display syntax without panel
80+ syntax = Syntax (
81+ code ,
82+ language ,
83+ theme = "monokai" ,
84+ line_numbers = False ,
85+ word_wrap = True
86+ )
87+
88+ console .print (syntax )
89+ console .print ("─" * 50 )
90+ console .print ()
91+
92+ def display_step (step_number : int , title : str , description : str = None ):
93+ """Display a numbered step in the tutorial."""
94+ step_text = f"[bold blue]Step { step_number } :[/] [bold]{ title } [/]"
95+ if description :
96+ step_text += f"\n { description } "
97+
98+ console .print (Panel (
99+ step_text ,
100+ title = f"📋 Step { step_number } " ,
101+ title_align = "left" ,
102+ border_style = "magenta" ,
103+ padding = (1 , 2 ),
104+ expand = False
105+ ))
106+ console .print ()
107+
108+ def prompt_user (message : str , default : str = None ) -> str :
109+ """Get user input with rich formatting."""
110+ return Prompt .ask (f"[bold green]{ message } [/]" , default = default )
111+
112+ def prompt_continue (message : str = "Press Enter to continue..." ):
113+ """Pause execution and wait for user to continue."""
114+ Prompt .ask (f"[dim]{ message } [/]" , default = "" )
115+
116+ def show_progress (description : str , duration : float = 2.0 ):
117+ """Show a progress spinner for the given duration."""
118+ with Progress (
119+ SpinnerColumn (),
120+ TextColumn ("[progress.description]{task.description}" ),
121+ transient = True ,
122+ ) as progress :
123+ task = progress .add_task (description , total = None )
124+ time .sleep (duration )
125+
126+ def create_table (title : str , headers : list , rows : list ) -> Table :
127+ """Create a rich table with the given headers and rows."""
128+ table = Table (title = title , show_header = True , header_style = "bold magenta" )
129+
130+ for header in headers :
131+ table .add_column (header , style = "cyan" )
132+
133+ for row in rows :
134+ table .add_row (* row )
135+
136+ return table
137+
138+ def display_table (title : str , headers : list , rows : list ):
139+ """Display a table with rich formatting."""
140+ table = create_table (title , headers , rows )
141+ console .print (table )
142+ console .print ()
143+
144+ def display_json_data (data : dict , title : str = "📊 JSON Data" ):
145+ """Display JSON data in a formatted panel."""
146+ import json
147+ json_str = json .dumps (data , indent = 2 )
148+ syntax = Syntax (json_str , "json" , theme = "monokai" , line_numbers = True )
149+ console .print (Panel (
150+ syntax ,
151+ title = title ,
152+ title_align = "left" ,
153+ border_style = "cyan" ,
154+ padding = (1 , 2 ),
155+ expand = False
156+ ))
157+ console .print ()
158+
159+ def section_separator ():
160+ """Print a visual separator between sections."""
161+ console .print ("\n " + "─" * 80 + "\n " )
162+
163+ def lab_complete ():
164+ """Display lab completion message."""
165+ console .print (Panel (
166+ "[bold green]🎉 Lab Complete![/]\n \n You have successfully completed this lab exercise." ,
167+ title = "✅ Congratulations" ,
168+ title_align = "center" ,
169+ border_style = "green" ,
170+ padding = (1 , 2 )
171+ ))
172+
173+ async def async_show_progress (description : str , duration : float = 2.0 ):
174+ """Async version of show_progress."""
175+ with Progress (
176+ SpinnerColumn (),
177+ TextColumn ("[progress.description]{task.description}" ),
178+ transient = True ,
179+ ) as progress :
180+ task = progress .add_task (description , total = None )
181+ await asyncio .sleep (duration )
0 commit comments