o
    ;i4C                     @   s  U d Z ddlZddlZddlZddlmZmZ ddlmZ ddlm	Z	 ddl
mZmZmZmZ ddlmZ er=ddlmZ G d	d
 d
eZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZe Zeaeed< dS )a  Output management interface for Modal CLI.

This module defines the interface for output management and provides a no-op
implementation for when output is disabled. The rich-based implementation lives
in rich.py to avoid importing rich when it's not needed.
    N)ABCabstractmethod)	Generator)AbstractContextManager)TYPE_CHECKINGAnyCallableOptional)write_to_fd)api_pb2c                   @   sf   e Zd ZdZedddZedddZededdfd	d
ZedddZ	ede
ddfddZdS )StatusContextzWAbstract base class for status context managers that support manual start/stop control.returnNc                 C      dS )z!Start showing the status spinner.N selfr   r   I/home/ubuntu/.local/lib/python3.10/site-packages/modal/_output/manager.pystart      zStatusContext.startc                 C   r   )z Stop showing the status spinner.Nr   r   r   r   r   stop   r   zStatusContext.stopstatusc                 C   r   )zUpdate the status message.Nr   r   r   r   r   r   update$   r   zStatusContext.updatec                 C      d S Nr   r   r   r   r   	__enter__)      zStatusContext.__enter__argsc                 G   r   r   r   r   r   r   r   r   __exit__,   r   zStatusContext.__exit__r   N)r   r   )__name__
__module____qualname____doc__r   r   r   strr   r   r   r   r   r   r   r   r      s    r   c                   @   sJ   e Zd ZdZededdfddZedd	d
ZededdfddZdS )	StatusRowzHAbstract base class describing a row in the object creation status tree.messager   Nc                 C   r   )z.Update the primary message shown for this row.Nr   r   r'   r   r   r   r'   3   r   zStatusRow.messagewarningapi_pb2.Warningc                 C   r   )z2Append a warning message associated with this row.Nr   r   r)   r   r   r   warn8   r   zStatusRow.warnc                 C   r   )z0Mark the row as finished with the given message.Nr   r(   r   r   r   finish=   r   zStatusRow.finishr)   r*   r   N)	r!   r"   r#   r$   r   r%   r'   r,   r-   r   r   r   r   r&   0   s    r&   c                   @   s>   e Zd ZdZdeddfddZdd	d
ZdeddfddZdS )DisabledStatusRowz-No-op StatusRow used when output is disabled.r'   r   Nc                 C   r   r   r   r(   r   r   r   r'   F   r   zDisabledStatusRow.messager)   r*   c                 C   r   r   r   r+   r   r   r   r,   I   r   zDisabledStatusRow.warnc                 C   r   r   r   r(   r   r   r   r-   L   r   zDisabledStatusRow.finishr.   )r!   r"   r#   r$   r%   r'   r,   r-   r   r   r   r   r/   C   s
    
r/   c                   @   s\   e Zd ZdZe						ddedee dee dee dee	 d	ee	 d
efddZ
dS )TransferProgressContextz;Abstract base class for transfer progress tracking context.NFtask_idadvancenamesizeresetcompleter   c                 C   r   )z:Update progress. Returns task_id when creating a new task.Nr   r   r1   r2   r3   r4   r5   r6   r   r   r   progressS      z TransferProgressContext.progressNNNNFF)r!   r"   r#   r$   r   r   r	   floatr%   boolr8   r   r   r   r   r0   P   s0    r0   c                   @   sX   e Zd ZdZ						ddedee dee dee dee d	ee d
dfddZ	dS )_DisabledTransferProgressz<No-op transfer progress context for when output is disabled.NFr1   r2   r3   r4   r5   r6   r   c                 C   r   r   r   r7   r   r   r   r8   d   s   	z"_DisabledTransferProgress.progressr:   )
r!   r"   r#   r$   r   r	   r;   r%   r<   r8   r   r   r   r   r=   a   s.    r=   c                   @   s  e Zd ZU dZdZeed< dZeed< edhddZ	edid
dZ
eedefddZeedefddZeedefddZeejded fddZedefddZeddd	ddddedededee ded edd	fd!d"Zed#edd	fd$d%Zed&ed'ee d(ed)ed*ed+ dd	fd,d-Zed.edd	fd/d0Z ed1edd2fd3d4Z!ed1ede"d	 fd5d6Z#edjd7d8Z$edkd:ede"d	 fd;d<Z%ed=edd	fd>d?Z&ed@edAee deeegd	f fdBdCZ'edDedEedd	fdFdGZ(edHedIdJdd	fdKdLZ)edMedNedAee dOee dd	f
dPdQZ*edldTdUZ+dldVdWZ,edjdXdYZ-edZede"d[ fd\d]Z.edjd^d_Z/d`edd	fdadbZ0dcedd	fdddeZ1ed1edd	fdfdgZ2d	S )mOutputManagera  Abstract base class defining the interface for output management.

    This class allows for different implementations:
    - RichOutputManager: Full rich-based terminal output with progress spinners, trees, etc.
    - DisabledOutputManager: No-op implementation for when output is disabled.

    Subclasses must implement all abstract methods. Use OutputManager.get() to get
    the current output manager instance.
    F_quiet_mode_show_timestampsr   c                 C   s   t S )aI  Get the current output manager.

        Returns a RichOutputManager when output is enabled, otherwise returns
        a DisabledOutputManager that provides no-op implementations of all methods.

        This allows code to call output methods without checking if output is enabled,
        simplifying the calling code.
        _current_output_manager)clsr   r   r   get      
zOutputManager.getmanagerNc                 C   s   |a dS )zCSet the current output manager. Used internally by enable_output().NrA   )rC   rF   r   r   r   _set   s   zOutputManager._setc                 C   r   )zWhether output is currently being displayed somewhere.

        Returns False if using DisabledOutputManager OR if quiet mode is active.
        This reflects whether print(), status(), etc. will actually produce visible output.
        Nr   r   r   r   r   
is_enabled   s   zOutputManager.is_enabledc                 C   r   )z4Whether the output is connected to a terminal (TTY).Nr   r   r   r   r   is_terminal      zOutputManager.is_terminalc                 C   r   )zWhether to show image logs.Nr   r   r   r   r   _show_image_logs   rJ   zOutputManager._show_image_logsNNNc                 C   r   )z>Context manager that displays a tree of objects being created.Nr   r   r   r   r   display_object_tree   rJ   z!OutputManager.display_object_treec                 C   r   )z,Add a status row to the current object tree.Nr   r   r   r   r   add_status_row   r   zOutputManager.add_status_rowT 
stderr	highlightstylesepend
renderablerR   rS   rT   rU   rV   c                C   r   )a  Print a renderable to the console.

        Args:
            renderable: The content to print.
            stderr: If True, print to stderr instead of stdout.
            highlight: If True, apply syntax highlighting.
            style: Optional Rich style string (e.g., "green", "bold cyan").
            sep: The separator to use between items.
            end: The string to use at the end of the output.
        Nr   r   rW   rR   rS   rT   rU   rV   r   r   r   print   s   zOutputManager.print
error_textc                 C   r   )af  Print an error message to stderr, ignoring quiet/disabled mode.

        This method always prints the error message regardless of quiet mode
        or whether output is disabled. It should be used for critical error
        messages that must always be visible to the user.

        Args:
            error_text: The error message text to display.
        Nr   r   rZ   r   r   r   print_error   r9   zOutputManager.print_errorr)   categoryfilenamelinenobase_showwarning.Nc                 C   r   )a  Display a warning message.

        This method is called by the patched warnings.showwarning for all warnings.

        Args:
            warning: The warning instance.
            category: The warning category (class).
            filename: The source file where the warning originated.
            lineno: The line number where the warning originated.
            base_showwarning: The original warnings.showwarning function to fall back to.
        Nr   r   r)   r]   r^   r_   r`   r   r   r   show_warning   s   zOutputManager.show_warningdatac                 C   r   )z Print JSON data with formatting.Nr   r   rd   r   r   r   
print_json   r   zOutputManager.print_jsonr'   r   c                 C   r   )zContext manager that displays a status spinner with a message.

        Returns a context manager that shows a spinner while active.
        The returned object has start(), stop(), and update() methods for manual control.
        Nr   r(   r   r   r   r         zOutputManager.statusc                 C   r   )zContext manager that shows a live spinner with a message.

        This combines spinner creation and live display into a single interface,
        hiding the implementation details of how spinners are rendered.
        Nr   r(   r   r   r   make_live_spinner   rg   zOutputManager.make_live_spinnerc                 C   r   )zEnable showing image logs.Nr   r   r   r   r   enable_image_logs  r   zOutputManager.enable_image_logsRunning app...status_textc                 C   r   )zContext manager that shows a status spinner.

        Args:
            status_text: The text to display next to the spinner. Defaults to "Running app...".
        Nr   r   rk   r   r   r   show_status_spinner  rg   z!OutputManager.show_status_spinnerapp_page_urlc                 C   r   )z$Update the app page URL for display.Nr   r   rn   r   r   r   update_app_page_url  r   z!OutputManager.update_app_page_urltagtotalc                 C   r   )z.Get a callback for updating function progress.Nr   )r   rq   rr   r   r   r   function_progress_callback  r   z(OutputManager.function_progress_callbackr1   statec                 C   r   )zUpdate the state of a task.Nr   r   r1   rt   r   r   r   update_task_state  r   zOutputManager.update_task_stateimage_idtask_progressapi_pb2.TaskProgressc                 C   r   )z Update snapshot upload progress.Nr   r   rw   rx   r   r   r   update_snapshot_progress   r   z&OutputManager.update_snapshot_progressfunction_id	completeddescriptionc                C   r   )z"Update function queueing progress.Nr   r   r|   r}   rr   r~   r   r   r   update_queueing_progress%  s   z&OutputManager.update_queueing_progresslogapi_pb2.TaskLogsc                    s   dS )a}  Process and display log content.

        Note: In RichOutputManager, log output is always displayed even when quiet mode
        is enabled. This is intentional - quiet mode suppresses progress indicators and
        status messages, but not actual log output from running functions/images.
        In contrast, DisabledOutputManager suppresses all output including logs.
        Nr   r   r   r   r   r   put_log_content,  s   	zOutputManager.put_log_contentc                    s  t j}t|drw|jd}d}zt|dr| }W n ty'   d}Y nw |dur6t||I dH  dS d}d}|t|k ruz||j	
||d 7 }|  W n tyl   |dkr^ |d7 }tdI dH  Y nw |t|k s@dS dS |
|j |  dS )	a#  Write PTY content to stdout for interactive terminal sessions.

        This handles raw PTY output from interactive shells/debuggers, writing
        directly to stdout with proper handling of non-blocking writes.

        Note: This method is implemented in the base class (not abstract) because
        interactive/raw terminal content is always forwarded to stdout regardless
        of whether output is enabled or quiet mode is active. This ensures that
        interactive debugging sessions (e.g., pdb breakpoints) work correctly.
        bufferzutf-8Nfilenor         g?)sysstdouthasattrrd   encoder   	Exceptionr
   lenr   writeflushBlockingIOErrorasynciosleep)r   r   r   rd   fdwritten	n_retriesr   r   r   put_pty_content7  s:   

zOutputManager.put_pty_contentc                 C   r   )zFlush any buffered output.Nr   r   r   r   r   flush_lines`  r   zOutputManager.flush_linestyper0   c                 C   r   )zContext manager for tracking file transfer progress.

        Args:
            type: Either "download" or "upload".

        Returns:
            A context manager that yields a TransferProgressContext with a progress() method.
        Nr   r   r   r   r   r   transfer_progresse  rE   zOutputManager.transfer_progressc                 C   r   )zStop the status spinner if it's running.

        This is used to cleanly stop the spinner before entering PTY mode or
        other situations where the spinner would interfere with output.
        Nr   r   r   r   r   stop_status_spinnerq  rg   z!OutputManager.stop_status_spinnerquietc                 C   
   || _ dS )a  Enable or disable quiet mode.

        When quiet mode is enabled:
        - All print() output is suppressed, including stderr
        - Progress indicators (spinners, progress bars) are suppressed
        - Warnings (via show_warning) are still displayed
        - Log output (via put_log_content) is still displayed
        - Interactive/raw PTY content (via put_pty_content) is still forwarded to stdout
        - Error output (via print_error) is still displayed

        Note: This differs from DisabledOutputManager, which suppresses all output
        including logs. Quiet mode is meant for reducing noise while still showing
        relevant content.
        N)r?   )r   r   r   r   r   set_quiet_modez  s   
zOutputManager.set_quiet_modeshowc                 C   r   )z2Enable or disable timestamp display in log output.N)r@   )r   r   r   r   r   set_timestamps     
zOutputManager.set_timestampsc                 C   r   )z;Print a step completed message with appropriate formatting.Nr   r(   r   r   r   step_completed  r   zOutputManager.step_completed)r   r>   )rF   r>   r   Nr    rj   r   r   r   N)3r!   r"   r#   r$   r?   r<   __annotations__r@   classmethodrD   rG   propertyr   rH   rI   rK   
contextlibcontextmanagerr   rM   r&   rN   r   r	   r%   rY   r\   Warningr   intr   rc   rf   r   r   rh   ri   rm   rp   rs   rv   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r>   p   s   
 	(

)r>   c                   @   sR   e Zd ZdZdddZdddZdeddfd	d
ZdddZde	ddfddZ
dS )_DisabledStatusz9No-op status context manager for when output is disabled.r   Nc                 C   r   r   r   r   r   r   r   r     r   z_DisabledStatus.startc                 C   r   r   r   r   r   r   r   r     r   z_DisabledStatus.stopr   c                 C   r   r   r   r   r   r   r   r     r   z_DisabledStatus.updatec                 C   s   | S r   r   r   r   r   r   r     r   z_DisabledStatus.__enter__r   c                 G   r   r   r   r   r   r   r   r     r   z_DisabledStatus.__exit__r    )r   r   )r!   r"   r#   r$   r   r   r%   r   r   r   r   r   r   r   r   r     s    


r   c                   @   s$  e Zd ZdZedefddZedefddZedefddZe	j
ded	 fd
dZdefddZdddddddedededee dededdfddZdeddfddZded ee d!ed"ed#ed$ ddfd%d&Zd'eddfd(d)Zd*edefd+d,Ze	j
d*eded	 fd-d.ZdWd/d0Ze	j
dXd2eded	 fd3d4Zd5eddfd6d7Zd8ed9ee deeegdf fd:d;Z d<ed=eddfd>d?Z!d@edAdBddfdCdDZ"dEedFed9ee dGee ddf
dHdIZ#dYdLdMZ$dWdNdOZ%e	j
dPedee&ddf fdQdRZ'dWdSdTZ(d*eddfdUdVZ)dS )ZDisabledOutputManagera  No-op implementation of OutputManager for when output is disabled.

    Most methods are no-ops that do nothing, allowing code to call output methods
    without checking if the output manager exists.

    Exceptions:
    - Interactive/raw PTY content (via put_pty_content) is always forwarded to stdout
      to ensure interactive debugging sessions work correctly.
    - Warnings (via show_warning) fall back to Python's default warning display.
    r   c                 C   r   )NFr   r   r   r   r   rH        z DisabledOutputManager.is_enabledc                 C   s
   t j S r   )r   r   isattyr   r   r   r   rI     r   z!DisabledOutputManager.is_terminalc                 C   r   )NTr   r   r   r   r   rK     r   z&DisabledOutputManager._show_image_logsrL   c                 c       d V  d S r   r   r   r   r   r   rM        
z)DisabledOutputManager.display_object_treec                 C      t  S r   )r/   r   r   r   r   rN        z$DisabledOutputManager.add_status_rowFTNrO   rP   rQ   rW   rR   rS   rT   rU   rV   c                C   r   r   r   rX   r   r   r   rY     rE   zDisabledOutputManager.printrZ   c                 C   s   t j|d  d S )NrP   )r   rR   r   r[   r   r   r   r\     s   z!DisabledOutputManager.print_errorr)   r]   r^   r_   r`   ra   c                 C   s   |||||d d d d S )N)fileliner   rb   r   r   r   rc     s   	z"DisabledOutputManager.show_warningrd   c                 C   r   r   r   re   r   r   r   rf     r   z DisabledOutputManager.print_jsonr'   c                 C   r   r   )r   r(   r   r   r   r     r   zDisabledOutputManager.statusc                 c   r   r   r   r(   r   r   r   rh     r   z'DisabledOutputManager.make_live_spinnerc                 C   r   r   r   r   r   r   r   ri     r   z'DisabledOutputManager.enable_image_logsrj   rk   c                 c   r   r   r   rl   r   r   r   rm     r   z)DisabledOutputManager.show_status_spinnerrn   c                 C   r   r   r   ro   r   r   r   rp     r   z)DisabledOutputManager.update_app_page_urlrq   rr   c                 C   s   dt dt dd fdd}|S )Nr}   rr   r   c                 S   r   r   r   )r}   rr   r   r   r   noop  r   z>DisabledOutputManager.function_progress_callback.<locals>.noop)r   )r   rq   rr   r   r   r   r   rs     s   z0DisabledOutputManager.function_progress_callbackr1   rt   c                 C   r   r   r   ru   r   r   r   rv     r   z'DisabledOutputManager.update_task_staterw   rx   ry   c                 C   r   r   r   rz   r   r   r   r{     r   z.DisabledOutputManager.update_snapshot_progressr|   r}   r~   c                C   r   r   r   r   r   r   r   r     r   z.DisabledOutputManager.update_queueing_progressr   r   c                    s   d S r   r   r   r   r   r   r     s   z%DisabledOutputManager.put_log_contentc                 C   r   r   r   r   r   r   r   r   
  r   z!DisabledOutputManager.flush_linesr   c                 c   s    t  V  dS )z(No-op transfer progress context manager.N)r=   r   r   r   r   r     s   z'DisabledOutputManager.transfer_progressc                 C   r   r   r   r   r   r   r   r     r   z)DisabledOutputManager.stop_status_spinnerc                 C   r   r   r   r(   r   r   r   r     r   z$DisabledOutputManager.step_completedr    r   r   )*r!   r"   r#   r$   r   r<   rH   rI   rK   r   r   r   rM   r&   rN   r   r	   r%   rY   r\   r   r   r   r   rc   rf   r   r   rh   ri   rm   rp   rs   rv   r{   r   r   r   r0   r   r   r   r   r   r   r   r     s    	


&



r   rB   )r$   r   r   r   abcr   r   collections.abcr   r   typingr   r   r   r	   modal._utils.shell_utilsr
   modal_protor   r   r&   r/   r0   r=   r>   r   r   _DISABLED_OUTPUT_MANAGERrB   r   r   r   r   r   <module>   s.     'r