
    tjm                       U d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddl
mZ ddlmZ ddlmZ  ej4                  e      Zed   Zed   Zed   Zda de!d<   ddZ" G d d      Z#y)    )annotationsN)Literal   )utils)
Controller)
HttpHeader)
CoreServer)State)VirtualNodeManager)share)ArgumentParser)
Translator)vue2vue3)aiohttpgenerictornadojupyter)maindesktoptask	coroutiner   
ClientTypeDEFAULT_CLIENT_TYPEc                    | a y N)r   )values    >/DATA/.local/lib/python3.12/site-packages/trame_server/core.pyset_default_client_typer      s        c                  &   e Zd ZdZ	 	 	 	 d$	 d%dZd&d'dZd Zed        Zd Z	d&d(dZ
ed	        Zed
        Zed        Zed)d       Zed'd       Zed        Zed        Zed*d       Zej&                  d+d       Zed        Zed,d       Zed,d       Zed-d       Zed.d       Zed/d       Zed        Zed        Zd Zd Zd Zed        Zd Z d Z!	 	 	 	 	 	 	 	 	 	 d0	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d1d Z"d%d!Z#ed2d"       Z$ed#        Z%y)3Servera]  
    Server implementation for trame.
    This is the core object that manage client/server communication but also
    holds a state and controller instance.
    With trame a server instance should be retrieved by using **trame.app.get_server()**

    Known options:
      - log_network: False (path to log file)
      - ws_max_msg_size: 10000000 (bytes)
      - ws_heart_beat: 30
      - desktop_debug: False

    :param name: A name identifier for a given server
    :type name: str, optional (default: trame)

    :param **options: Gather any keyword arguments into options
    :type options: Dict
    Nc                   || _         |r|n	t               | _        t        |d|      | _        t        |d|      | _        t        |dd       | _        t        |dt                     | _        d | _	        d| _
        d| _        d | _        d | _        i | _        t               | _        g | _        d | _        d | _        g | _        dt*        j,                  v xs t/        t1        j2                  dd             | _        |/| j
                  j7                  dt0        j8                  j7                  d	d
            | j
                  d<   | j
                  j7                  dt0        j8                  j7                  dd            | j
                  d<   | j
                  j7                  dt0        j8                  j7                  dd            | j
                  d<   | j
                  j7                  dt0        j8                  j7                  dd
            | j
                  d<   dt0        j8                  d<   |t;        | j<                  | j>                  | j4                        | _         dD ]  }g | j@                  d| <    dg| j@                  _!        d| j@                  _"        d | j@                  _#        d| j@                  _$        n<t;        | j<                  |j@                  | j>                  | j4                        | _         |'tK        | j<                  | j4                        | _&        n1tK        | j<                  |jL                  | j4                        | _&        |'t;        | j<                  | j4                        | _'        n1t;        | j<                  |jN                  | j4                        | _'        t        |dtQ        | |            | _)        y )N_name_options_client_type_http_headerr   --hot-reloadTRAME_HOT_RELOADlog_networkTRAME_LOG_NETWORKFws_max_msg_sizeTRAME_WS_MAX_MSG_SIZEi ws_heart_beatTRAME_WS_HEART_BEAT   desktop_debugTRAME_DESKTOP_DEBUG WSLINK_READY_MSG)	commit_fn
hot_reload)scriptsmodule_scriptsstylesvue_use	mousetraptrame__trame__busyr   Trame)internalr5   r6   )r6   )r?   r6   _ui)*_parent_serverr   _translatorr   r$   r%   r&   r   r'   _server_running_stage_running_port_running_future_wwwserveset_loaded_modules_loaded_module_dicts_cli_parser_root_protocol_protocols_to_configuresysargvboolosgetenvr6   getenvironr
   
translator_push_state_statetrame__client_onlyr=   trame__favicontrame__titler   _controller_contextr   r@   )selfnamevn_constructorrV   parent_serveroptionskeys          r   __init__zServer.__init__6   s    ,)3:='48
mZA!-F!-N #	
"u$&!"')$ )CHH4 
II($/9
  +/==+<+<rzz~~.A5I,DMM-( 04}}/@/@!2::>>2I8#T0DMM+, .2]]->->0Er!J.DMM/* .2]]->->0Eu!M.DMM/* .0BJJ)*  4+;+;DK W/1gcUO, W.;_DKK*&'DKK#)-DKK&'.DKK$&--**??	DK  )$//dooVD)&22?? D  !$//dooNDM!&//??DM /A$/WXr    c                <    |r|nt        |      }t        ||       S )N)prefix)rV   ra   )r   r"   )r^   rV   rf   s      r   create_child_serverzServer.create_child_server   s    #-Z:V3L
4@@r    c                T    | j                   r| j                   j                  |       y y r   )protocolpush_state_change)r^   states     r   rW   zServer._push_state   s     ==MM++E2 r    c                    | j                   S )zIReturn http header helper so they can be applied before the server start.)r'   r^   s    r   http_headerszServer.http_headers   s        r    c                   | j                   | k7  r | j                   j                  |fi |S |}t        |t              r+|| j                  v ry| j                  j                  |       n6|| j                  v ry| j                  j                  |       |j                  }d|v r |d   | fi | dD ]$  }||v s| j                  d| xx   ||   z  cc<   & d|v r| j                  j                  |d          d|v r| j                  j                  |d          d|v r
|d   | _        t        j                  | j                         y)	an  
        Expend server using a module definition which can be used to serve custom
        client code or assets, load/initialize resources (js, css, vue),
        register custom protocols and even execute custom code.

        Any previously seem module will be automatically skipped.

        The attributes that are getting processed in a module are the following:
          - setup(server, **kwargs): Function called first
          - scripts = []           : List all JavaScript URL that should be loaded
          - module_scripts = []    : List all JavaScript URL as type=module to load
          - styles  = []           : List all CSS URL that should be loaded
          - vue_use = ['libName', ('libName2', { **options })]: List Vue plugin to load
          - state = {}             : Set of variable to add to state
          - serve = { data: '/path/on/fs' }: Set of endpoints to serve static content
          - www = '/path/on/fs'    : Path served as main web content

        :param module: A module to enable or a dict()
        :param kwargs: Any optional parameters needed for your module setup() function.
        Fsetup)r7   r8   r9   r:   r<   rk   rH   wwwT)root_serverenable_module
isinstancedictrK   appendrJ   add__dict__rk   updaterH   rG   r   reduce_vue_use)r^   modulekwargsdefinitionsrc   s        r   rs   zServer.enable_module   sO   * t#14##11&CFCC k4(d777%%,,[9D000  $$[1%..Kk! K 00ECk!

WSE?+{3/??+ F k!JJk'23k!JJk'23K#E*DI 	TZZ(r    c                r    | j                   r+| j                   j                  d||t        |      dg       yy)a  
        Python call method on JS element.

        :param ref: ref name of the widget element
        :type ref: str

        :param method: name of the method that should be called
        :type method: str

        :param *args: set of parameters needed for the function
        method)typerefr   argsN)ri   push_actionslist)r^   r   r   r   s       r   js_callzServer.js_call   s>     ==MM&& !)""( $T
		 r    c                .    | j                   j                  S )a;  
        Use as decorator `@server.change(key1, key2, ...)` so the decorated function
        will be called like so `_fn(**state)` when any of the listed key name
        is getting modified from either client or server.

        :param *_args: A list of variable name to monitor
        :type *_args: str
        )rX   changerm   s    r   r   zServer.change   s     {{!!!r    c                .    | j                   j                  S )z
        Use as decorator `@server.trigger(name)` so the decorated function
        will be able to be called from the client by doing `click="trigger(name)"`.

        :param name: A name to use for that trigger
        :type name: str
        )r\   triggerrm   s    r   r   zServer.trigger  s     '''r    c                .    | j                   j                  S )z
        Given a function this method will register a trigger and returned its name.
        If manually registered, the given name at the time will be returned.

        :return: The trigger name for that function
        :rtype: str
        )r\   trigger_namerm   s    r   r   zServer.trigger_name  s     ,,,r    c                    | j                   S )zName of server)r$   rm   s    r   r_   zServer.name,  s     zzr    c                J    | j                   r| j                   j                  S | S )zRoot server to start)rA   rr   rm   s    r   rr   zServer.root_server1  s$     &&222r    c                    | j                   S )zTranslator of the server)rB   rm   s    r   rV   zServer.translator8  s     r    c                    | j                   S )z-Server options provided at instantiation time)r%   rm   s    r   rb   zServer.options=  s     }}r    c                >    | j                   t        S | j                   S )z9Specify the client type. Either 'vue2' or 'vue3' for now.)r&   r   rm   s    r   client_typezServer.client_typeB  s"     $&&   r    c                    | j                   || _         | j                  |k7  rd| j                    d| d}t        |      y)z;Should only be called once before any widget initializationNz"Trying to switch client_type from z to z&.The client_type can only be set once.)r&   r   	TypeError)r^   r   msgs      r   r   zServer.client_typeI  s[     $ %Du$4T5F5F4GtE7 S8 8  C.  %r    c                   | j                   | k7  r| j                   j                  S | j                  r| j                  S t        dd      | _        | j                  j	                  ddd       | j                  j	                  dd	d       | j                  j	                  d
dd       | j                  j	                  dddd       | j                  j	                  dd       | j                  j	                  ddd       | j                  j	                  dd       | j                  j	                  dddd       t        j                  | j                         | j                  S )zargparse parserzKitware trameF)descriptionallow_abbrevz--serverz,Prevent your browser from opening at startup
store_true)helpactionz--bannerzPrint trame bannerz--appzUse OS built-in browserz	--no-httpzDo not serve anything over httpno_http)r   destr   z--authKeyFilezPath to a File that contains the Authentication key for clients
                    to connect to the WebSocket.
                    This takes precedence over '-a, --authKey' from wslink.)r   r(   zAutomatically reload state/controller callback functions for every
                    function call. This allows live editing of the functions. Functions
                    located in the site-packages directories are skipped.z--trame-argsa#  If specified, trame will ignore all other arguments, and only the contents
                    of the `--trame-args` will be used. For example:
                    `--trame-args="-p 8081 --server"`. Alternatively, the environment variable
                    `TRAME_ARGS` may be set instead.z--follow-symlinksstatic_follow_symlinksa  flag for allowing to follow symlinks that lead outside
                    the static root directory, by default it's not allowed
                    and HTTP/404 will be returned on access.
                    Enabling follow_symlinks can be a security risk,
                    and may lead to a directory transversal attack.
                    You do NOT need this option to follow symlinks which point
                    to somewhere else within the static directory, this option
                    is only used to break out of the security sandbox.
                    Enabling this option is highly discouraged, and only
                    expected to be used for edge cases in a local development
                    setting where remote users do not have access to the server.)r   r   r   )rr   clirL   r   add_argumentr	   add_argumentsrm   s    r   r   z
Server.cliV  s    t###'''###)'
 	%%? 	& 	

 	%%% 	& 	

 	%%* 	& 	

 	%%2	 	& 	
 	%%O 	& 	
 	%%M   	& 	
 	%%8 	& 	
 	%%)
T   	& 	
" 	  !1!12r    c                    | j                   S )z[
        :return: The server shared state
        :rtype: trame_server.state.State
        )rX   rm   s    r   rk   zServer.state  s     {{r    c                    | j                   S )z
        The server-only context (not shared with the client).

        :return: The server context state
        :rtype: trame_server.state.State
        )r]   rm   s    r   contextzServer.context  s     }}r    c                    | j                   S )zc
        :return: The server controller
        :rtype: trame_server.controller.Controller
        )r\   rm   s    r   
controllerzServer.controller  s     r    c                    | j                   S )zl
        :return: The server VirtualNode manager
        :rtype: trame_server.ui.VirtualNodeManager
        )r@   rm   s    r   uiz	Server.ui  s     xxr    c                j    | j                   | k7  r| j                   j                  S | j                  dkD  S )z;Return True if the server is currently starting or running.r   )rr   runningrD   rm   s    r   r   zServer.running  s5     t###+++""Q&&r    c                p    t        j                  | j                  j                  j	                               S )zReturn a future to await if you want to ensure that any pending network call
        have been issued before locking the server)asyncioensure_futurer   network_monitor
completionrm   s    r   network_completionzServer.network_completion  s(     $$T\\%A%A%L%L%NOOr    c                    | j                   | k7  r| j                   j                  S | j                  't        j                         j                         | _        | j                  S )z:Return a future that will resolve once the server is ready)rr   readyrF   r   get_running_loopcreate_futurerm   s    r   r   zServer.ready  sV     t###)))'#*#;#;#=#K#K#MD ###r    c                H    | j                   | j                  j                  dS )zReturn the current server state)r_   rk   )r$   rk   initialrm   s    r   get_server_statezServer.get_server_state  s"     JJZZ''
 	
r    c                @    | j                   }|r |j                  |  y y r   )ri   clear_state_client_cache)r^   state_namesri   s      r   r   zServer.clear_state_client_cache  s#    ==-H--{; r    c                    | j                   | k7  r| j                   j                  |       y| j                  j                  |       y)a9  
        Register function that will be called with a wslink.ServerProtocol
        when the server start and is ready for registering new wslink.Protocol.

        :param configure_protocol_fn: A function to be called later with a
                                      wslink.ServerProtocol as argument.
        N)rr   add_protocol_to_configurerN   rv   )r^   configure_protocol_fns     r   r   z Server.add_protocol_to_configure  s?     t#667LM$$++,ABr    c                d    | j                   | k7  r| j                   j                  S | j                  S )zReturn the server root protocol)rr   ri   rM   rm   s    r   ri   zServer.protocol  s0     t###,,,"""r    c                    | j                   r/| j                   j                  |      }|r|\  }} ||g|i |S yd}t        |      )aQ  
        Call a registered protocol method

        :param method: Method registration name
        :type method: str
        :param *args: Set of args to use for that method call
        :param **kwargs: Set of keyword arguments to use for that method call
        :return: transparently return what the called function returns
        NzProtocol does not exist yet)ri   getRPCMethod
ValueError)r^   r   r   r|   pairobjfuncerrors           r   protocol_callzServer.protocol_call  sS     ====--f5D 	TC1$1&11-r    c           	          | j                   dg|D cg c]  }| j                  j                  |       c}  yc c}w )z
        Should only be needed when client corrupted its data and need the server need to send it again.

        :param *args: Set of key names to be send again to the client.
        ztrame.force.pushN)r   rB   translate_key)r^   	key_namesks      r   force_state_pushzServer.force_state_push  sB     		
MV!WY$"2"2"@"@"CY!W	
!Ws   "<
c                p	     j                    k7  r'  j                   j                  d|||||||	|
d	 y j                  ry j                  ddlm}  j                  |        j                  j                           j                  j                  j                         r j                  j                          t        j                           j                  j                         d   }| t         j"                  j%                  dd      }|||_        !t         j"                  j%                  dd       |j(                  d	k(  r)|
 t         j"                  j%                  d
d	      }
|
|_        |	|	|_        |||_        |j.                  s j                  |_        |rd|_        |j2                  r+ddlm}  j                  j8                  j;                  |       |j<                  rd}|dk(  r=ddlm  d|_        d\  }} j                  j8                  j;                   fd       tC        |dd      }|s6|r4|dk7  r/ddl"m#  j                  j8                  j;                   fd       |sBr@|dk7  r;|jH                  s/ddl%m&  j                  j8                  j;                   fd       tO         jP                        r~g } jP                  D ]W  } jP                  |   }tS        |tT        tV        f      r|jY                  | d|d           B|jY                  | d|        Y dj[                  |      |_.        |j^                  rd|_        d|_.        | _0        t        jb                  |       d _        t        jd                  |fi i |||d}|dk(  rd _         j                  jf                  j                         rti        jj                         }  j                  jf                  di  jl                  jo                         D ]c  }tq        jr                  |      r|ju                  |       *tw        |      s6 |       }tq        jr                  |      sS|ju                  |       e |S ty        |d      rd  fd}|j{                  |       |S )!a  
        Start the server by listening to the provided port or using the
        `--port, -p` command line argument.
        If the server is already starting or started, any further call will be skipped.

        When the exec_mode="main" or "desktop", the method will be blocking.
        If exec_mode="task", the method will return a scheduled task.
        If exec_mode="coroutine", the method will return a coroutine which
        will need to be scheduled by the user.

        :param port: A port number to listen to. When 0 is provided
                     the system will use a random open port.
        :param thread: If the server run in a thread which means
                       we should disable interuption listeners
        :param open_browser: Should we open the system browser with app url.
                             Using the `--server` command line argument is
                             similar to setting it to False.
        :param show_connection_info: Should we print connection URL at startup?
        :param disable_logging: Ask wslink to disable logging
        :param backend: aiohttp by default but could be generic or tornado.
                        This can also be set with the environment variable ``TRAME_BACKEND``.
                        Defaults to ``'aiohttp'``.
        :param exec_mode: main/desktop/task/coroutine
                          specify how the start function should work
        :param timeout: How much second should we wait before automatically
                        stopping the server when no client is connected.
                        Setting it to 0 will disable such auto-shutdown.
        :param host: The hostname used to bind the server. This can also be
                     set with the environment variable ``TRAME_DEFAULT_HOST``.
                     Defaults to ``'localhost'``.
        :param **kwargs: Keyword arguments for capturing optional parameters
                         for wslink server and/or desktop browser
        )	portthreadopen_browsershow_connection_infodisable_loggingbackend	exec_modetimeouthostNr   )r{   TRAME_BACKENDr   TRAME_SERVERF	localhostTRAME_DEFAULT_HOSTTr   )print_bannerr   )start_browser)r   FFc                      fi S r    )_r|   r^   r   s    r   <lambda>zServer.start.<locals>.<lambda>  s    M$9&9r    reverse_urlr   )print_informationsc                            S r   r   )r   r   r^   s    r   r   zServer.start.<locals>.<lambda>  s    <Nt<Tr    )r   c                            S r   r   )r   r   r^   s    r   r   zServer.start.<locals>.<lambda>  s
    L<Nr    =|r3   )disableLoggingr   r   r   add_done_callbackc                Z   	 | j                          d_        j                  j                  j	                         r5 j                  j                  di j
                  j                          y y # t        j                  $ r Y y t        $ r t        j                  d|        Y y w xY w)Nr   zException raised by task = %rr   )resultrD   r   on_server_exitedexistsrk   to_dictr   CancelledError	Exceptionlogging	exception)r   r^   s    r   on_donezServer.start.<locals>.on_done  s    MKKM*+D'77>>@888P4::;M;M;OP A--   M%%&EtLMs   A/A4 4B*	B*)B*r   )r   zasyncio.TaskreturnNone)>rr   startrD   rG   trame_clientr{   rs   r'   applyr   on_server_startr   r	   bind_serverr   parse_known_argsrR   rU   rT   r   r   r   r   contentnosignalhandlersbannerutils.bannerr   on_server_readyrw   apputils.desktopr   getattrutils.serverr   serverutils.browserr   lenrH   rt   r   tuplerv   joinfsEndpointsr   _server_options	configureserver_startr   r   get_event_looprk   r   inspectisawaitablerun_until_completecallablehasattrr   )r^   r   r   r   r   r   r   follow_symlinksr   r   r   r|   r{   rb   r   r   	endpointsrc   r   r   loop	exit_taskr   r   r   r   s   `  `       `            @@r   r   zServer.start*  s*   ^ t#"D"" )%9 /#   99+v& 	! ??**113OO++D1t$((++-a0?jjnn_i@G&-<G*!zz~~neDDL<<;&|zz~~&:KHGL%GOGL"iiGO'+G$>>2OO++//=;;!I	!4GL<P9I+\OO++//9
 g}d;3	V8K8OO++//0TU V#NN3OO++//0NOtzz?Izz

3edE]3$$uAeAhZ%89$$uAeW%56 " #&((9"5G ?? GO"$G&W%&&
"1"&	
 "#D//668--/!A!A!A "jj((*"I **95//	:!),!*"..v6 33F;"0  T./	M ""7+r    c                   K   | j                   | k7  r*| j                   j                          d{    d| _        y| j                  r)| j                  j                          d{    d| _        d| _        y7 I7 w)z!Coroutine for stopping the serverNr   )rr   stoprD   rC   rF   rm   s    r   r  zServer.stop  sp     t#""'')))     ,,##%%%#'D 	 *%s!   -A=A95A=%A;&A=;A=c                d    | j                   | k7  r| j                   j                  S | j                  S )z,Once started, you can retrieve the port used)rr   r   rE   rm   s    r   r   zServer.port  s0     t###(((!!!r    c                    | j                   S )z6Once started, you can retrieve the server options used)r  rm   s    r   server_optionszServer.server_options  s     ###r    )trameNNN)r   r   )NN)r   r"   )r   
str | Noner   r  )r   str)r   r   r   r   r   r   )r   r
   )r   r   )r   r   )r   rQ   )
NFNTFNNr   NN)r   
int | Noner   rQ   r   bool | Noner   rQ   r   rQ   r   zBackendType | Noner  r  r   ExecModeTyper   r  r   r  )r   int)&__name__
__module____qualname____doc__rd   rg   rW   propertyrn   rs   r   r   r   r   r_   rr   rV   rb   r   setterr   rk   r   r   r   r   r   r   r   r   r   ri   r   r   r   r  r   r  r   r    r   r"   r"   "   s   * YY 
YYvA3 ! !8|8 	" 	" ( ( - -           ! ! 
! 
! J  J X           ' ' P P
 $ $
<C # # (
   $(%) %&*'+"("II I "	I
 #I I $I %I  I I IV  " " $ $r    r"   r  )$
__future__r   r   r  r   rR   rO   typingr   r3   r   r   r   httpr   ri   r	   rk   r
   r   r   r   utils.argument_parserr   utils.namespacer   	getLoggerr"  loggerr   BackendTyper   r   __annotations__r   r"   r   r    r   <module>r1     s    "    	 
   "     "  1 '			8	$^$
@A=>"( Z ( 
g$ g$r    