1515from rich .table import Table
1616from rich .text import Text
1717
18- from fastapi_fastkit import console
1918from fastapi_fastkit .core .settings import settings
2019from fastapi_fastkit .utils .logging import debug_log , get_logger
2120
2524REGEX = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b"
2625
2726
27+ def get_optimal_console_size () -> tuple [int , int ]:
28+ """
29+ Get optimal console size based on terminal dimensions.
30+
31+ Returns:
32+ tuple: (width, height) - optimal console dimensions
33+ """
34+ try :
35+ # Get terminal size
36+ terminal_size = os .get_terminal_size ()
37+ width = terminal_size .columns
38+ height = terminal_size .lines
39+
40+ # Set minimum and maximum constraints
41+ min_width = 80
42+ max_width = 120
43+ min_height = 24
44+
45+ # Calculate optimal width (80% of terminal width, but within constraints)
46+ optimal_width = max (min_width , min (max_width , int (width * 0.8 )))
47+ # Calculate optimal height (leave some space for prompt and buffer)
48+ optimal_height = max (min_height , height - 5 )
49+
50+ return optimal_width , optimal_height
51+ except (OSError , ValueError ):
52+ # Fallback to default size if terminal size detection fails
53+ return 80 , 24
54+
55+
56+ def create_adaptive_console () -> Console :
57+ """
58+ Create a console instance with adaptive sizing based on terminal dimensions.
59+
60+ Returns:
61+ Console: Rich console instance with optimal sizing
62+ """
63+ if "PYTEST_CURRENT_TEST" in os .environ :
64+ return Console (no_color = True )
65+
66+ width , height = get_optimal_console_size ()
67+ return Console (width = width , height = height )
68+
69+
70+ # Initialize console with adaptive sizing
71+ console = create_adaptive_console ()
72+
73+
74+ def _get_adaptive_panel_width (message : str ) -> int :
75+ """
76+ Calculate optimal panel width based on message length and terminal size.
77+
78+ :param message: Message content
79+ :return: Optimal panel width
80+ """
81+ optimal_width , _ = get_optimal_console_size ()
82+ # Use message length + padding, but constrain to reasonable bounds
83+ min_width = min (len (message ) + 10 , optimal_width - 4 )
84+ return max (40 , min_width ) # Minimum 40 chars, leave margin for borders
85+
86+
2887def print_error (
2988 message : str ,
3089 title : str = "Error" ,
@@ -42,7 +101,9 @@ def print_error(
42101 error_text = Text ()
43102 error_text .append ("❌ " , style = "bold red" )
44103 error_text .append (message )
45- console .print (Panel (error_text , border_style = "red" , title = title ))
104+
105+ panel_width = _get_adaptive_panel_width (message )
106+ console .print (Panel (error_text , border_style = "red" , title = title , width = panel_width ))
46107
47108 # Log error for debugging purposes (internal logging)
48109 debug_log (f"Error: { message } " , "error" )
@@ -81,7 +142,11 @@ def print_success(
81142 success_text = Text ()
82143 success_text .append ("✨ " , style = "bold yellow" )
83144 success_text .append (message , style = "bold green" )
84- console .print (Panel (success_text , border_style = "green" , title = title ))
145+
146+ panel_width = _get_adaptive_panel_width (message )
147+ console .print (
148+ Panel (success_text , border_style = "green" , title = title , width = panel_width )
149+ )
85150
86151
87152def print_warning (
@@ -97,7 +162,11 @@ def print_warning(
97162 warning_text = Text ()
98163 warning_text .append ("⚠️ " , style = "bold yellow" )
99164 warning_text .append (message )
100- console .print (Panel (warning_text , border_style = "yellow" , title = title ))
165+
166+ panel_width = _get_adaptive_panel_width (message )
167+ console .print (
168+ Panel (warning_text , border_style = "yellow" , title = title , width = panel_width )
169+ )
101170
102171
103172def print_info (message : str , title : str = "Info" , console : Console = console ) -> None :
@@ -111,7 +180,9 @@ def print_info(message: str, title: str = "Info", console: Console = console) ->
111180 info_text = Text ()
112181 info_text .append ("ℹ " , style = "bold blue" )
113182 info_text .append (message )
114- console .print (Panel (info_text , border_style = "blue" , title = title ))
183+
184+ panel_width = _get_adaptive_panel_width (message )
185+ console .print (Panel (info_text , border_style = "blue" , title = title , width = panel_width ))
115186
116187
117188def create_info_table (
@@ -121,21 +192,61 @@ def create_info_table(
121192 console : Console = console ,
122193) -> Table :
123194 """
124- Create a table for displaying information.
195+ Create a table for displaying information that never truncates text .
125196
126197 :param title: Title for the table
127198 :param data: Dictionary of data to populate the table
128199 :param show_header: Whether to show table headers
129200 :param console: Rich console instance
130201 :return: Configured Rich Table instance
131202 """
132- table = Table (title = title , show_header = show_header , title_style = "bold magenta" )
133- table .add_column ("Field" , style = "cyan" )
134- table .add_column ("Value" , style = "green" )
203+ # Calculate exact content lengths if data exists
204+ if data :
205+ max_field_length = max (len (str (key )) for key in data .keys ())
206+ max_value_length = max (len (str (value )) for value in data .values ())
207+
208+ # Set column widths to exactly match the longest content
209+ # Add small padding to ensure content fits comfortably
210+ field_width = max_field_length + 2
211+ value_width = max_value_length + 2
212+ else :
213+ # Default widths for empty tables
214+ field_width = 15
215+ value_width = 30
216+
217+ # Create table that prioritizes full text display over terminal fitting
218+ table = Table (
219+ title = title ,
220+ show_header = show_header ,
221+ title_style = "bold magenta" ,
222+ expand = False , # Never expand to terminal width
223+ width = None , # Let table size itself based on content
224+ pad_edge = False , # Reduce padding to save space
225+ )
226+
227+ # Add columns with settings that prevent any truncation
228+ table .add_column (
229+ "Field" ,
230+ style = "cyan" ,
231+ no_wrap = False , # Allow wrapping instead of truncating
232+ width = field_width , # Exact width for content
233+ min_width = field_width , # Minimum width to prevent shrinking
234+ max_width = None , # No maximum width limit
235+ overflow = "fold" , # Fold text instead of truncating
236+ )
237+ table .add_column (
238+ "Value" ,
239+ style = "green" ,
240+ no_wrap = False , # Allow wrapping instead of truncating
241+ width = value_width , # Exact width for content
242+ min_width = value_width , # Minimum width to prevent shrinking
243+ max_width = None , # No maximum width limit
244+ overflow = "fold" , # Fold text instead of truncating
245+ )
135246
136247 if data :
137248 for key , value in data .items ():
138- table .add_row (key , value )
249+ table .add_row (str ( key ), str ( value ) )
139250
140251 return table
141252
0 commit comments