
    ^hN                     D   S r SSKrSSKrSSKrSSKJrJrJrJrJ	r	  \" S\
5      r\" S\
5      r SSKrSSKJrJr  SSKJr  SS	KJr  SS
KJrJrJrJr  SSKJr  SSKJ r    " S S\!5      r"\ " S S5      5       r# " S S5      r$ " S S\5      r%g! \ a	    SSKJr   Njf = f)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                       \ rS rSrSrSrg)KernelSessionRecordConflict   z_Exception class to use when two KernelSessionRecords cannot
merge because of conflicting data.
 N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       i/home/james-whalen/.local/lib/python3.13/site-packages/jupyter_server/services/sessions/sessionmanager.pyr   r      s    r   r   c                   ^    \ rS rSr% SrSr\\   \S'   Sr	\\   \S'   S\
S\4S jrSS	 jrS
rg)KernelSessionRecord#   zA 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                    [        U[        5      (       a  U R                  =(       a    U R                  UR                  :H  n[        U R                  UR                  :H  U R                  SL =(       d    UR                  SL /5      n[        X#/5      (       a  g[        U R                  U R                  UR                  :H  U R                  UR                  :g  /5      (       a  Sn[        U5      eg)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__KernelSessionRecord.__eq__/   s    e011MDNNeoo,MJOOu'7'77NNd*Eeoo.EJ J+,, OOOOu'7'77NNeoo5   2#66r   c           	         [        U[        5      (       d  Sn[        U5      eUR                  (       a8  U R                  (       a'  UR                  U R                  :w  a  Sn[	        U5      e[        U 5       Hd  n[        XR                  5      (       d  M  [        XR                  5      (       d  M;  [        XR                  [        XR                  5      5        Mf     g)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    updateKernelSessionRecord.updateO   s    %!455GCC. ??t~~%//T^^2S^C-c22D\Eujj))geZZ.H.Hjj'%*DE "r   r   )r&   r"   r'   N)r   r   r   r   r   r$   r   str__annotations__r%   objectboolr0   r9   r   r   r   r    r"   r"   #   s?     !%J$#Ix}#F t @Fr   r"   c                       \ rS rSr% Sr\\   \S'   S\4S jrS r	S\
\\4   S\4S	 jrS
 rS\
\\4   S\4S jrS\SS4S jrS\SS4S jrSrg)KernelSessionRecordList^   a  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                 F    / U l         U H  nU R                  U5        M     gzInitialize a record list.N)rB   r9   )r,   rC   records      r    __init__ KernelSessionRecordList.__init__i   s    FKK r   c                 ,    [        U R                  5      $ )z+The string representation of a record list.)r;   rB   r,   s    r    __str__KernelSessionRecordList.__str__o       4==!!r   rF   r'   c                     [        U[        5      (       a  XR                  ;   a  g[        U[        5      (       a0  U R                   H   nXR                  UR
                  4;   d  M     g   g)z.Search for records by kernel_id and session_idTF)r)   r"   rB   r;   r$   r%   )r,   rF   rs      r    __contains__$KernelSessionRecordList.__contains__s   sR    f122v7Nfc""]]llAKK88 # r   c                 ,    [        U R                  5      $ )zThe length of the record list.)lenrB   rJ   s    r    __len__KernelSessionRecordList.__len__~   rM   r   c                    [        U[        5      (       a3  U R                   H"  nXR                  UR                  4;   d  M   Us  $    O1[        U[
        5      (       a  U R                   H  nX:X  d  M
  Us  $    U S3n[        U5      e)zcReturn a full KernelSessionRecord from a session_id, kernel_id, or
incomplete KernelSessionRecord.
z& not found in KernelSessionRecordList.)r)   r;   rB   r%   r$   r"   
ValueError)r,   rF   rO   r/   s       r    getKernelSessionRecordList.get   sx     fc""]]kk1<<88H #  344]];!M # >?or   Nc                      U R                   R                  U5      nU R                   U   R                  U5        g! [         a    U R                   R	                  U5         gf = f)z9Update a record in-place or append it if not in the list.N)rB   indexr9   rW   append)r,   rF   idxs      r    r9   KernelSessionRecordList.update   sS    	)--%%f-CMM#%%f- 	)MM  (	)s   9< %A$#A$c                 Z    XR                   ;   a  U R                   R                  U5        gg)zIRemove a record if its found in the list. If it's not found,
do nothing.
N)rB   remove)r,   rF   s     r    r`   KernelSessionRecordList.remove   s%     ]]"MM  ( #r   )rB   )r   r   r   r   r   listr"   r<   rG   rK   r   r;   r>   rP   rT   rX   r9   r`   r   r   r   r    r@   r@   ^   s     &'' !4  "	5)<c)A#B 	t 	"% 3S 89 >Q )0 )T ))0 )T )r   r@   c                     ^  \ rS rSrSr\" SSS9R                  SS9r\" S5      S	 5       r	\
" S
5      r\" SS/5      rU 4S jrSrSr1 Skr\S 5       r\S 5       rS rS rS rS\4S jr     S(S\\   S\\   S\\   S\\   S\\   S\\\4   4S jjr S)S\\   S\\   S\\\4   4S jjr S\S\\   S\\   S\\   S\\   S\4S jr!S*S  jr"S! r#S" r$S\S\%4S# jr&S+S$ jr'S% r(S& r)S'r*U =r+$ ),SessionManager   z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                 z   US   nUS:X  a  U$ [         R                  " U5      nUR                  5       (       aq  UR                  5       (       a  Sn[	        U5      e[        US5       nUR                  S5      nSSS5        WR                  S5      (       d  US:w  a  S	n[	        U5      eU$ ! , (       d  f       N9= f)
zValidate a database file path.valuerf   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,   proposalrl   pathr/   fheaders          r    _validate_database_filepath*SessionManager._validate_database_filepath   s     !JL||E";;=={{}}d o%eT"a # $$%788Vs]F o% #"s   'B,,
B:zBjupyter_server.services.kernels.kernelmanager.MappingKernelManagerz8jupyter_server.services.contents.manager.ContentsManagerz2notebook.services.contents.manager.ContentsManagerc                 D   > [         TU ]  " U0 UD6  [        5       U l        grE   )superrG   r@   _pending_sessions)r,   argskwargs	__class__s      r    rG   SessionManager.__init__   s     $)&)!8!:r   N>   r5   rw   typer%   r$   c                     U R                   c:  U R                  R                  5       U l         U R                   R                  S5        U R                   $ )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executerJ   s    r    r   SessionManager.cursor   sE     <<??113DLLL  = ||r   c                     U R                   cC  [        R                  " U R                  SS9U l         [        R                  U R                   l        U R                   $ )zStart a database connectionN)isolation_level)_connectionsqlite3connectrj   Rowrow_factoryrJ   s    r    r   SessionManager.connection   sH     #&t/E/EW[\D+2;;D(r   c                 b    U R                   b"  U R                   R                  5         SU l         gg)zClose the sqlite connectionN)r   closerJ   s    r    r   SessionManager.close   s(    <<#LL DL $r   c                 $    U R                  5         g)z+Close connection once SessionManager closesN)r   rJ   s    r    __del__SessionManager.__del__   s    

r   c                    #    SnU R                   R                  SU45        U R                   R                  5       nUb  U R                  USS9I Sh  vN nUb  SnU$  N7f)z2Check to see if the session of a given name existsFz"SELECT * FROM session WHERE path=?NT)tolerate_culled)r   r   fetchonerow_to_model)r,   rw   rq   rowmodels        r    session_existsSessionManager.session_exists   sh     @4'Jkk""$? ++C+FFE  Gs   AA AA r'   c                 >    [        [        R                  " 5       5      $ )zCreate a uuid for a new session)r;   uuiduuid4rJ   s    r    new_session_idSessionManager.new_session_id  s    4::<  r   rw   r5   r   kernel_namer%   c                   #    U R                  5       n[        US9nU R                  R                  U5        Ub  XPR                  ;   a  OU R                  XaX#U5      I Sh  vN nXWl        U R                  R                  U5        U R                  XaX#US9I Sh  vN nU R                  R                  U5        [        [        [        [        4   U5      $  Nv N>7f)zCreates a session and returns its model

Parameters
----------
name: ModelName(str)
    Usually the model name, like the filename associated with current
    kernel.
r$   N)rw   r5   r   r%   )r   r"   r~   r9   kernel_managerstart_kernel_for_sessionr%   save_sessionr`   r   dictr;   r   )	r,   rw   r5   r   r   r%   r$   rF   results	            r    create_sessionSessionManager.create_session  s       ((*
$
;%%f- Y2E2E%E";;$k I %%%f-((9 ) 
 
 	%%f-DcNF++

s$   AC C!9CC=CCc                     Ub:  U R                   R                  U5      n[        R                  R	                  X25      n[        U[        5      (       d   e0 [        R                  ESU0E$ )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osrw   joinr)   r;   environ)r,   rw   r5   cwds       r    get_kernel_envSessionManager.get_kernel_env(  s\     %%2248C77<<*D$$$$$7"**70$77r   r$   c                    #    [        U R                  R                  US95      I Sh  vN nU R                  X#5      nU R                  R                  UUUS9I Sh  vN n[        [        U5      $  NH N7f)a  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.
)rw   N)rw   r   env)r   contents_managerget_kernel_pathr   r   start_kernelr   r;   )	r,   r$   rw   r5   r   r   kernel_path
kernel_envr%   s	            r    r   'SessionManager.start_kernel_for_session;  s|     2 ))>)>)N)NTX)N)YZZ((4
--::# ; 
 
	
 C## [
s!   &A5A13A5A3A53A5c                 ~   #    U R                   R                  SXX4U45        U R                  US9I Sh  vN nU$  N7f)aC  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)r   r   get_session)r,   r$   rw   r5   r   r%   r   s          r    r   SessionManager.save_session^  sH     2 	4t95	
 '':'>> ?s   2=;=c                   #    U(       d  Sn[        U5      e/ nU H6  nX@R                  ;  a  SU 3n[        U5      eUR                  SU-  5        M8     SSR                  U5      -  nU R                  R                  U[        UR                  5       5      5         U R                  R                  5       nUc[  / nUR                  5        H  u  pUR                  U SU	< 35        M     [        R                  " SS	S
R                  U5      -  5      e U R                  U5      I Sh  vN n
U
$ ! [         a    Sn Nf = f N! [         a)  n[        R                  " SS	[        U5      -  5      UeSnAff = f7f)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, )r3   _columnsr\   r   r   r   rb   valuesr   KeyErroritemsr   	HTTPErrorr   r;   )r,   r   r/   
conditionscolumnqueryr   qkeyrl   r   es               r    r   SessionManager.get_session~  sd    $ 2CC. 
F]]*(1n$fvo.	  1GLL4LME4#89	++&&(C
 ;A$lln
C5%+, - --%<		!%MNN	N++C00E   	C	 1 	N--%<s1v%EFAM	Nsa   BE;D1 7AE;E *E+E /E;1E =E;?E  E;E 
E8$E33E88E;c                 Z  #    U R                  US9I Sh  vN   U(       d  g/ nU H4  nX@R                  ;  a  [        SU-  5      eUR                  SU-  5        M6     SSR	                  U5      -  nU R
                  R                  U/ [        UR                  5       5      QUP5        [        U R                  S5      (       ac  U R
                  R                  SU/5        U R
                  R                  5       u  pgnU R                  R                  XR                  Xg5      S	9  gg GN7f)
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   r3   r\   r   r   r   rb   r   r4   r   r   r   r   )	r,   r$   r   setsr   r   rw   r5   r%   s	            r    update_sessionSessionManager.update_session  s     *555F]]* 4v =>>KK(  ;diioNE#GT&--/%:#GJ#GH4&&55KKNQ[P\ %)KK$8$8$:!D	**YDWDWX\Dc*d 6 	6s   D+D(DD+c                 &   #    XR                   ;  $ 7f)zQChecks if the kernel is still considered alive and returns true if its not found.)r   )r,   r%   s     r    kernel_culledSessionManager.kernel_culled  s      3 333s   c                   #    [        U R                  US   5      5      I Sh  vN nU(       ag  U R                  R                  SUS   45        SR	                  US   US   S9nU(       a  U R
                  R                  U S35        g[        U5      e[        U R                  R                  US   5      5      I Sh  vN nUS   US   US	   US
   US.nUS
   S:X  a  US   US	   S.US'   U$  N N37f)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...rw   r5   r   )idrw   r5   r   kernelnotebook)rw   r5   )
r   r   r   r   formatlogwarningr   r   kernel_model)r,   r   r   r   r/   r   r   s          r    r   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"   !C6C2BC6 C42C64C6c                    #    U R                   R                  S5      n/ nUR                  5        H.  n U R                  U5      I Sh  vN nUR	                  U5        M0     U$  N! [
         a     MC  f = f7f)zWReturns a list of dictionaries containing all the information from
the session databasezSELECT * FROM sessionN)r   r   fetchallr   r\   r   )r,   cr   r   r   s        r    list_sessionsSessionManager.list_sessions  st      KK 78 ::<C"//44e$   	 5 s:   1A7A&A$	A&A7$A&&
A40A73A44A7c                 ^  #    [        US9nU R                  R                  U5        U R                  US9I Sh  vN n[	        U R
                  R                  US   S   5      5      I Sh  vN   U R                  R                  SU45        U R                  R                  U5        g No N?7f)z=Deletes the row in the session database with given session_idr   Nr   r   r   )
r"   r~   r9   r   r   r   shutdown_kernelr   r   r`   )r,   r$   rF   sessions       r    delete_sessionSessionManager.delete_session  s     $
;%%f-((J(??4..>>wx?PQU?VWXXXDzmT%%f- @Xs!   7B-B)1B-+B+,>B-+B-)r   r   r~   )NNNNN)N)NNNN)F),r   r   r   r   r   r   tagrj   r   rz   r   r   r   r   rG   r   r   r   propertyr   r   r   r   r   r;   r   r   r	   r   r   r   r   r   r   r   r   r   r>   r   r   r   r   r   __classcell__)r   s   @r    rd   rd      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   rd   )&r   r   ro   r   typingr   r   r   r   r   r;   r   r	   r   ImportError	pysqlite2r
   dataclassesr   r   jupyter_core.utilsr   tornador   	traitletsr   r   r   r   traitlets.config.configurabler   jupyter_server.traittypesr   	Exceptionr   r"   r@   rd   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