
    XhN                     B   d Z ddlZddlZddlZddlmZmZmZmZm	Z	  ede
      Z ede
      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 ddlm Z   G d de!      Z"e G d d             Z# G d d      Z$ G d de      Z%y# e$ r	 ddlmZ Y iw xY w)zA base class session manager.    N)AnyNewTypeOptionalUnioncast
KernelName	ModelName)dbapi2)	dataclassfields)ensure_async)web)Instance
TraitErrorUnicodevalidate)LoggingConfigurable)InstanceFromClassesc                       e Zd ZdZy)KernelSessionRecordConflictzgException class to use when two KernelSessionRecords cannot
    merge because of conflicting data.
    N)__name__
__module____qualname____doc__     c/var/www/html/myenv/lib/python3.12/site-packages/jupyter_server/services/sessions/sessionmanager.pyr   r      s    r   r   c                   R    e Zd ZU dZdZee   ed<   dZee   ed<   de	de
fdZd	dZy)
KernelSessionRecordzA record object for tracking a Jupyter Server Kernel Session.

    Two records that share a session_id must also share a kernel_id, while
    kernels can have multiple session (and thereby) session_ids
    associated with them.
    N
session_id	kernel_idotherreturnc                    t        |t              r| j                  xr | j                  |j                  k(  }t        | j                  |j                  k(  | j                  du xs |j                  du g      }t        ||g      ryt        | j                  | j                  |j                  k(  | j                  |j                  k7  g      rd}t        |      y)z Whether a record equals another.NTzA single session_id can only have one kernel_id associated with. These two KernelSessionRecords share the same session_id but have different kernel_ids. This should not be possible and is likely an issue with the session records.F)
isinstancer   r!   allr    anyr   )selfr"   
condition1
condition2msgs        r   __eq__zKernelSessionRecord.__eq__/   s    e01MDNNeoo,MJOOu'7'77NNd*Eeoo.EJ J
+, OOOOu'7'77NNeoo5  2#66r   c           	         t        |t              sd}t        |      |j                  r2| j                  r&|j                  | j                  k7  rd}t	        |      t        |       D ][  }t        ||j                        st        ||j                        s1t        | |j                  t        ||j                               ] y)zCUpdates in-place a kernel from other (only accepts positive updatesz3'other' must be an instance of KernelSessionRecord.zJCould not update the record from 'other' because the two records conflict.N)
r%   r   	TypeErrorr!   r   r   hasattrnamegetattrsetattr)r(   r"   r+   fields       r   updatezKernelSessionRecord.updateO   s    %!45GCC. ??t~~%//T^^2S^C-c22D\ 	FEuejj)geUZZ.Hejj'%*DE	Fr   )r"   r   r#   N)r   r   r   r   r    r   str__annotations__r!   objectboolr,   r4   r   r   r   r   r   #   s?     !%J$#Ix}#F t @Fr   r   c                       e Zd ZU dZee   ed<   defdZd Zde	ee
f   defdZd	 Zde	ee
f   defd
ZdeddfdZdeddfdZy)KernelSessionRecordLista.  An object for storing and managing a list of KernelSessionRecords.

    When adding a record to the list, the KernelSessionRecordList
    first checks if the record already exists in the list. If it does,
    the record will be updated with the new information; otherwise,
    it will be appended.
    _recordsrecordsc                 B    g | _         |D ]  }| j                  |        yzInitialize a record list.N)r;   r4   )r(   r<   records      r   __init__z KernelSessionRecordList.__init__i   s$     	 FKK	 r   c                 ,    t        | j                        S )z+The string representation of a record list.)r5   r;   r(   s    r   __str__zKernelSessionRecordList.__str__o       4==!!r   r?   r#   c                     t        |t              r|| j                  v ryt        |t              r-| j                  D ]  }||j                  |j
                  fv s y y)z.Search for records by kernel_id and session_idTF)r%   r   r;   r5   r    r!   )r(   r?   rs      r   __contains__z$KernelSessionRecordList.__contains__s   sU    f12v7Nfc"]]  allAKK88  r   c                 ,    t        | j                        S )zThe length of the record list.)lenr;   rB   s    r   __len__zKernelSessionRecordList.__len__~   rD   r   c                     t        |t              r0| j                  D ]   }||j                  |j                  fv s|c S  n*t        |t
              r| j                  D ]  }||k(  s	|c S  | d}t        |      )zsReturn a full KernelSessionRecord from a session_id, kernel_id, or
        incomplete KernelSessionRecord.
        z& not found in KernelSessionRecordList.)r%   r5   r;   r!   r    r   
ValueError)r(   r?   rF   r+   s       r   getzKernelSessionRecordList.get   s     fc"]] akk1<<88H  34]] "Q;!M" >?or   Nc                     	 | j                   j                  |      }| j                   |   j                  |       y# t        $ r | j                   j	                  |       Y yw xY w)z9Update a record in-place or append it if not in the list.N)r;   indexr4   rL   append)r(   r?   idxs      r   r4   zKernelSessionRecordList.update   sS    	)--%%f-CMM#%%f- 	)MM  (	)s   9< $A#"A#c                 X    || j                   v r| j                   j                  |       yy)zYRemove a record if its found in the list. If it's not found,
        do nothing.
        N)r;   remove)r(   r?   s     r   rS   zKernelSessionRecordList.remove   s'     T]]"MM  ( #r   )r   r   r   r   listr   r6   r@   rC   r   r5   r8   rG   rJ   rM   r4   rS   r   r   r   r:   r:   ^   s     &'' !4  "	5)<c)A#B 	t 	"% 3S 89 >Q )0 )T ))0 )T )r   r:   c                       e Zd ZdZ edd      j                  d      Z ed      d        Z e	d	      Z
 ed
dg      Z fdZdZdZh dZed        Zed        Zd Zd Zd ZdefdZ	 	 	 	 	 d&dee   dee   dee   dee   dee   deeef   fdZ	 d'dee   dee   deeef   fdZdedee   dee   dee   dee   defdZ d(dZ!d  Z"d! Z#dede$fd"Z%d)d#Z&d$ Z'd% Z( xZ)S )*SessionManagerzA session manager.:memory:zThe filesystem path to SQLite Database file (e.g. /path/to/session_database.db). By default, the session database is stored in-memory (i.e. `:memory:` setting from sqlite3) and does not persist when the current Jupyter Server shuts down.)default_valuehelpT)configdatabase_filepathc                 L   |d   }|dk(  r|S t        j                  |      }|j                         rf|j                         rd}t	        |      t        |d      5 }|j                  d      }ddd       j                  d      s|dk7  rd	}t	        |      |S # 1 sw Y   .xY w)
zValidate a database file path.valuerW   zL`database_filepath` expected a file path, but the given path is a directory.rbd   Ns   SQLite format 3r   z.The given file is not an SQLite database file.)pathlibPathexistsis_dirr   openread
startswith)r(   proposalr]   pathr+   fheaders          r   _validate_database_filepathz*SessionManager._validate_database_filepath   s     !JL||E";;={{}d o%eT" %a% $$%78Vs]F o%% %s   BB#zBjupyter_server.services.kernels.kernelmanager.MappingKernelManagerz8jupyter_server.services.contents.manager.ContentsManagerz2notebook.services.contents.manager.ContentsManagerc                 B    t        |   |i | t               | _        yr>   )superr@   r:   _pending_sessions)r(   argskwargs	__class__s      r   r@   zSessionManager.__init__   s     $)&)!8!:r   N>   r0   rh   typer!   r    c                     | j                   :| j                  j                         | _         | j                   j                  d       | j                   S )z5Start a cursor and create a database called 'session'z\CREATE TABLE IF NOT EXISTS session
                (session_id, path, name, type, kernel_id))_cursor
connectioncursorexecuterB   s    r   rv   zSessionManager.cursor   sE     <<??113DLLL  = ||r   c                     | j                   Et        j                  | j                  d      | _         t        j                  | j                   _        | j                   S )zStart a database connectionN)isolation_level)_connectionsqlite3connectr[   Rowrow_factoryrB   s    r   ru   zSessionManager.connection   sH     #&t/E/EW[\D+2;;D(r   c                 `    | j                   "| j                   j                          d| _         yy)zClose the sqlite connectionN)rt   closerB   s    r   r   zSessionManager.close   s(    <<#LL DL $r   c                 $    | j                          y)z+Close connection once SessionManager closesN)r   rB   s    r   __del__zSessionManager.__del__   s    

r   c                    K   d}| j                   j                  d|f       | j                   j                         }|| j                  |d       d{   }|d}|S 7 
w)z2Check to see if the session of a given name existsFz"SELECT * FROM session WHERE path=?NT)tolerate_culled)rv   rw   fetchonerow_to_model)r(   rh   rb   rowmodels        r   session_existszSessionManager.session_exists   si     @4'Jkk""$? ++C+FFE  Gs   AA!AA!r#   c                 <    t        t        j                               S )zCreate a uuid for a new session)r5   uuiduuid4rB   s    r   new_session_idzSessionManager.new_session_id  s    4::<  r   rh   r0   rr   kernel_namer!   c                   K   | j                         }t        |      }| j                  j                  |       ||| j                  v rn| j                  |||||       d{   }||_        | j                  j                  |       | j                  |||||       d{   }| j                  j                  |       t        t        t        t        f   |      S 7 |7 >w)zCreates a session and returns its model

        Parameters
        ----------
        name: ModelName(str)
            Usually the model name, like the filename associated with current
            kernel.
        r    N)rh   r0   rr   r!   )r   r   rn   r4   kernel_managerstart_kernel_for_sessionr!   save_sessionrS   r   dictr5   r   )	r(   rh   r0   rr   r   r!   r    r?   results	            r   create_sessionzSessionManager.create_session  s       ((*
$
;%%f- Y$2E2E%E";;D$k I %%%f-((T49 ) 
 
 	%%f-DcNF++

s$   A!C$#C $?C$#C"$=C$"C$c                     |;| j                   j                  |      }t        j                  j	                  ||      }t        |t              sJ i t        j                  d|iS )a[  Return the environment variables that need to be set in the kernel

        Parameters
        ----------
        path : str
            the url path for the given session.
        name: ModelName(str), optional
            Here the name is likely to be the name of the associated file
            with the current kernel at startup time.
        JPY_SESSION_NAME)r   cwd_for_pathosrh   joinr%   r5   environ)r(   rh   r0   cwds       r   get_kernel_envzSessionManager.get_kernel_env(  s[     %%2248C77<<T*D$$$$7"**70$77r   r    c                    K   t        | j                  j                  |             d{   }| j                  ||      }| j                  j                  |||       d{   }t        t        |      S 7 L7 w)aQ  Start a new kernel for a given session.

        Parameters
        ----------
        session_id : str
            uuid for the session; this method must be given a session_id
        path : str
            the path for the given session - seem to be a session id sometime.
        name : str
            Usually the model name, like the filename associated with current
            kernel.
        type : str
            the type of the session
        kernel_name : str
            the name of the kernel specification to use.  The default kernel name will be used if not provided.
        )rh   N)rh   r   env)r   contents_managerget_kernel_pathr   r   start_kernelr   r5   )	r(   r    rh   r0   rr   r   kernel_path
kernel_envr!   s	            r   r   z'SessionManager.start_kernel_for_session;  s     2 ))>)>)N)NTX)N)YZZ((t4
--::# ; 
 
	
 C## [
s!   )A<A87A<#A:$A<:A<c                    K   | j                   j                  d|||||f       | j                  |       d{   }|S 7 w)a  Saves the items for the session with the given session_id

        Given a session_id (and any other of the arguments), this method
        creates a row in the sqlite session database that holds the information
        for a session.

        Parameters
        ----------
        session_id : str
            uuid for the session; this method must be given a session_id
        path : str
            the path for the given session
        name : str
            the name of the session
        type : str
            the type of the session
        kernel_id : str
            a uuid for the kernel associated with this session

        Returns
        -------
        model : dict
            a dictionary of the session model
        z&INSERT INTO session VALUES (?,?,?,?,?)r   N)rv   rw   get_session)r(   r    rh   r0   rr   r!   r   s          r   r   zSessionManager.save_session^  sM     2 	4tT95	
 '':'>> ?s   7AA Ac                   K   |sd}t        |      g }|D ]4  }|| j                  vrd| }t        |      |j                  d|z         6 ddj                  |      z  }| j                  j                  |t        |j                                      	 | j                  j                         }|Xg }|j                         D ]  \  }}	|j                  | d|	        t        j                  dd	d
j                  |      z        	 | j                  |       d{   }
|
S # t        $ r d}Y w xY w7 # t        $ r(}t        j                  dd	t        |      z        |d}~ww xY ww)a:  Returns the model for a particular session.

        Takes a keyword argument and searches for the value in the session
        database, then returns the rest of the session's info.

        Parameters
        ----------
        **kwargs : dict
            must be given one of the keywords and values from the session database
            (i.e. session_id, path, name, type, kernel_id)

        Returns
        -------
        model : dict
            returns a dictionary that includes all the information from the
            session described by the kwarg.
        zmust specify a column to queryzNo such column: %s=?zSELECT * FROM session WHERE %sz AND N=i  zSession not found: %s, )r.   _columnsrP   r   rv   rw   rT   valuesr   KeyErroritemsr   	HTTPErrorr   r5   )r(   rp   r+   
conditionscolumnqueryr   qkeyr]   r   es               r   r   zSessionManager.get_session~  ss    $ 2CC. 
 	/FT]]*(1n$fvo.		/ 1GLL4LME4#89	++&&(C
 ;A$lln -
UC5%+,- --%<		!%MNN	N++C00E   	C	 1 	N--%<s1v%EFAM	Nsa   BE,D% /AE,
D8 D6D8 #E,%D30E,2D33E,6D8 8	E)#E$$E))E,c                 R  K   | j                  |       d{    |syg }|D ]2  }|| j                  vrt        d|z        |j                  d|z         4 ddj	                  |      z  }| j
                  j                  |g t        |j                               |       t        | j                  d      ri| j
                  j                  d|g       | j
                  j                         \  }}}| j                  j                  || j                  ||      	       yy7 w)
a  Updates the values in the session database.

        Changes the values of the session with the given session_id
        with the values from the keyword arguments.

        Parameters
        ----------
        session_id : str
            a uuid that identifies a session in the sqlite3 database
        **kwargs : str
            the key must correspond to a column title in session database,
            and the value replaces the current value in the session
            with session_id.
        r   NzNo such column: %rr   z(UPDATE session SET %s WHERE session_id=?r   
update_envz<SELECT path, name, kernel_id FROM session WHERE session_id=?)r!   r   )r   r   r.   rP   r   rv   rw   rT   r   r/   r   r   r   r   )	r(   r    rp   setsr   r   rh   r0   r!   s	            r   update_sessionzSessionManager.update_session  s     *555 	)FT]]* 4v =>>KK(	) ;diioNE#GT&--/%:#GJ#GH4&&5KKNQ[P\ %)KK$8$8$:!D$	**YDDWDWX\^bDc*d 6 	6s   D'D$DD'c                 &   K   || j                   vS w)zQChecks if the kernel is still considered alive and returns true if its not found.)r   )r(   r!   s     r   kernel_culledzSessionManager.kernel_culled  s      3 333s   c                   K   t        | j                  |d                d{   }|re| j                  j                  d|d   f       dj	                  |d   |d         }|r| j
                  j                  | d       yt        |      t        | j                  j                  |d                d{   }|d   |d   |d	   |d
   |d}|d
   dk(  r|d   |d	   d|d<   |S 7 7 2w)z@Takes sqlite database session row and turns it into a dictionaryr!   N&DELETE FROM session WHERE session_id=?r    zKernel '{kernel_id}' appears to have been culled or died unexpectedly, invalidating session '{session_id}'. The session has been removed.)r!   r    z  Continuing...rh   r0   rr   )idrh   r0   rr   kernelnotebook)rh   r0   )
r   r   rv   rw   formatlogwarningr   r   kernel_model)r(   r   r   r   r+   r   r   s          r   r   zSessionManager.row_to_model  s    $01C1CCDT1U$VV KK H3|K\J^_UU[U[!+.3|;L V\ V    C5!893-)$*=*=*J*J3{K[*\]]l#KKK"
 v;*$),Vc&k JE*A W* ^s"   !C.C*BC.9C,:1C.,C.c                    K   | j                   j                  d      }g }|j                         D ]-  }	 | j                  |       d{   }|j	                  |       / |S 7 # t
        $ r Y ?w xY ww)z_Returns a list of dictionaries containing all the information from
        the session databasezSELECT * FROM sessionN)rv   rw   fetchallr   rP   r   )r(   cr   r   r   s        r   list_sessionszSessionManager.list_sessions  sz      KK 78 ::< 	C"//44e$	 	 5 s:   1A3A$A"	A$A3"A$$	A0-A3/A00A3c                 j  K   t        |      }| j                  j                  |       | j                  |       d{   }t	        | j
                  j                  |d   d                d{    | j                  j                  d|f       | j                  j                  |       y7 o7 ?w)z=Deletes the row in the session database with given session_idr   Nr   r   r   )
r   rn   r4   r   r   r   shutdown_kernelrv   rw   rS   )r(   r    r?   sessions       r   delete_sessionzSessionManager.delete_session  s     $
;%%f-((J(??4..>>wx?PQU?VWXXXDzmT%%f- @Xs"   =B3B/ 1B31B12>B31B3)NNNNN)N)NNNN)F)*r   r   r   r   r   tagr[   r   rk   r   r   r   r   r@   rt   rz   r   propertyrv   ru   r   r   r   r5   r   r   r	   r   r   r   r   r   r   r   r   r   r8   r   r   r   r   __classcell__)rq   s   @r   rV   rV      s    O 
cc  !" #( bcN*F@	
; GKBH       ! ! #$(",0#',sm, y!, sm	,
 j), C=, 
c3h,D @D8SM8)1))<8	c3h8&!$!$ sm!$ y!	!$
 sm!$ j)!$ 
!$F@1f"eH4S 4T 4"H.r   rV   )&r   r   r`   r   typingr   r   r   r   r   r5   r   r	   r{   ImportError	pysqlite2r
   dataclassesr   r   jupyter_core.utilsr   tornador   	traitletsr   r   r   r   traitlets.config.configurabler   jupyter_server.traittypesr   	Exceptionr   r   r:   rV   r   r   r   <module>r      s    # 
   6 6\3'
K%	,
 * +  = = = 9)  7F 7F 7Ft@) @)Fr.( r.e  ,+,s   B BB