
    Mh#                       d Z 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Zddl	Z	ddl
Z
ddlZddlmZmZmZ ddlmZ ddlmZ ddlmZmZmZ ddlm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%Z%ddl%m&Z& ddl'm(Z( ddl)m*Z* ddl+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z: erBddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD ddl.mEZE ddlFmGZG ddlHmIZI ddlJmKZK ddlLmMZM dd lNmOZO daPd! ZQdGd$ZR G d% d&e jS                  ZT G d' d(eT          ZU G d) d*eU          ZV G d+ d,eU          ZW G d- d.eUe jX                  ZYdHd1ZZe j[        Z[ G d2 d3eUe jX                  Z\ G d4 d5eV          Z] G d6 d7e jS                  Z^ G d8 d9eU          Z_ G d: d;eU          Z` G d< d=e jS                  Za G d> d?eU          Zb G d@ dAe jX                  ZcdBZddCe^fdDe]fdEecfdFebfgZedS )Iz-Base Tornado handlers for the Jupyter server.    )annotationsN)	Awaitable	CoroutineSequence)	responses)Logger)TYPE_CHECKINGAnycast)urlparse)TemplateNotFound)	is_hidden)web)app_log)Application)CallContext)get_sys_info)utcnow)allow_unauthenticated
authorized)User)combine_translations)csp_report_uri)ensure_asyncfilefind
url_escapeurl_is_absoluteurl_path_joinurldecode_unix_socket_path)KernelSpecManager)EventLogger)TerminalManager)Future)
AuthorizerIdentityProvider)	ServerApp)ConfigManager)ContentsManager)AsyncMappingKernelManager)SessionManagerc                 ^    t            t          j        t                                a t           S )zGet sys info as json.)_sys_info_cachejsondumpsr        \/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/jupyter_server/base/handlers.pyjson_sys_infor3   C   s#     *\^^44r1   returnr   c                     t          j                    r+t          t          t          j                    j                  S t          S )zGet the application log.)r   initializedr   r   instancelogr   r0   r1   r2   r8   r8   K   s4       FK0226777r1   c                  ,   e Zd ZdZedd            Zedd            ZddZedd            Zd d!dZ	ddZ
ddZd"dZed"d            Zed"d            Zed#d            Zed$d            Zed"d            Zed%d            Zed&d            Zd
S )'AuthenticatedHandlerz,A RequestHandler with an authenticated user.r4   strc                ^    t          t          | j                            dd                    S )Nbase_url/r   r;   settingsgetselfs    r2   r=   zAuthenticatedHandler.base_urlV   s$    C**:s;;<<<r1   c                   d| j                             di           v r&t          t          | j         d         d                   S d                    dd| j                             dt          | j        t                              z   g          S )zThe default Content-Security-Policy header

        Can be overridden by defining Content-Security-Policy in settings['headers']
        Content-Security-Policyheaders; zframe-ancestors 'self'zreport-uri r   )r@   rA   r   r;   joinr   r=   r   rB   s    r2   content_security_policyz,AuthenticatedHandler.content_security_policyZ   s     %(9(9)R(H(HHHT]956OPQQQyy(-##$4mDMSa6b6bccd
 
 	
r1   Nonec                J   i }d|d<   |                     | j                            di                      | j        |d<   |                                D ]N\  }}	 |                     ||           # t          $ r%}| j                            d|           Y d}~Gd}~ww xY wdS )zSet the default headers.nosniffzX-Content-Type-OptionsrF   rE   z!Could not set default headers: %sN)	updater@   rA   rI   items
set_header	Exceptionr8   	exception)rC   rF   header_namevaluees        r2   set_default_headersz(AuthenticatedHandler.set_default_headersm   s    ,5()t}((B77888-1-I)* #*--// 		 		KU3333    ""7       			 		s   A11
B ;BB c                n    t          j        dt          d           | j                            |           S )NqJupyterHandler.login_handler is deprecated in 2.0,
            use JupyterHandler.identity_provider.
               
stacklevel)warningswarnDeprecationWarningidentity_providerget_cookie_namerB   s    r2   cookie_namez AuthenticatedHandler.cookie_name   sA     	
 	
 	
 	
 %55d;;;r1   r>   Nnamepathdomain
str | Nonec                z    t          j        dt          d           | j                            | |||           dS )zForce a cookie clear.rW   rX   rY   )rb   rc   N)r[   r\   r]   r^   _force_clear_cookie)rC   ra   rb   rc   s       r2   force_clear_cookiez'AuthenticatedHandler.force_clear_cookie   sQ     	
 	
 	
 	
 	224DQW2XXXXXr1   c                r    t          j        dt          d           | j                            |            dS )zClear a login cookie.rW   rX   rY   N)r[   r\   r]   r^   clear_login_cookierB   s    r2   ri   z'AuthenticatedHandler.clear_login_cookie   sG     	
 	
 	
 	
 	11$77777r1   c                    | j         j        }d| d}t          | d          r6t          j        |t
          d           t          t          | j                  S t          |          )zGet the current user.z	Calling `z{.get_current_user()` directly is deprecated in jupyter-server 2.0. Use `self.current_user` instead (works in all versions)._jupyter_current_userrX   rY   )
	__class____name__hasattrr[   r\   r]   r   r;   rk   RuntimeError)rC   clsnamemsgs      r2   get_current_userz%AuthenticatedHandler.get_current_user   s    .)H H H H 	 4011 	9M"   
 T78883r1   boolc                \    | j         j        dk    rdS | j                            |            S )zAsk my login_handler if I should skip the origin_check

        For example: in the default LoginHandler, if a request is token-authenticated,
        origin checking should be skipped.
        OPTIONST)requestmethodr^   should_check_originrB   s    r2   skip_check_originz&AuthenticatedHandler.skip_check_origin   s3     <)++4)==dCCCCr1   c                6    | j                             |           S )z'Have I been authenticated with a token?)r^   is_token_authenticatedrB   s    r2   token_authenticatedz(AuthenticatedHandler.token_authenticated   s     %<<TBBBr1   c                :    | j         }t          |o|dk              S )zIs a user currently logged in?	anonymous)current_userrs   )rC   users     r2   	logged_inzAuthenticatedHandler.logged_in   s$      D0T[0111r1   r
   c                R    t          j        dt          d           | j        j        S )z6Return the login handler for this application, if any.rW   rX   rY   )r[   r\   r]   r^   login_handler_classrB   s    r2   login_handlerz"AuthenticatedHandler.login_handler   s8     	 	
 	
 	
 	
 %99r1   c                    | j         j        S )z4Return the login token for this application, if any.)r^   tokenrB   s    r2   r   zAuthenticatedHandler.token   s     %++r1   c                @    t          t          | j        j                  S )zMay a user proceed to log in?

        This returns True if login capability is available, irrespective of
        whether the user is already logged in or not.

        )r   rs   r^   login_availablerB   s    r2   r   z$AuthenticatedHandler.login_available   s     D$0@AAAr1   r$   c                   d| j         vrOt          j        dd           ddlm}  || j                             dd           | j                  | j         d<   t          d	| j                             d                    S )
N
authorizera  The Tornado web application does not have an 'authorizer' defined in its settings. In future releases of jupyter_server, this will be a required key for all subclasses of `JupyterHandler`. For an example, see the jupyter_server source code for how to add an authorizer to the tornado settings: https://github.com/jupyter-server/jupyter_server/blob/653740cbad7ce0c8a8752ce83e4d3c2c754b13cb/jupyter_server/serverapp.py#L234-L256rX   rY   r   )AllowAllAuthorizerconfig)r   r^   r$   )r@   r[   r\   jupyter_server.authr   rA   r^   r   )rC   r   s     r2   r   zAuthenticatedHandler.authorizer   s    t},,M 
 
 
 
 ?>>>>>*<*<}((488"&"8+ + +DM,'
 L$-"3"3L"A"ABBBr1   r&   c                    d| j         vrIt          j        dd           ddlm}  || j                             dd                     | j         d<   t          d	| j         d                   S )
Nr^   a  The Tornado web application does not have an 'identity_provider' defined in its settings. In future releases of jupyter_server, this will be a required key for all subclasses of `JupyterHandler`. For an example, see the jupyter_server source code for how to add an identity provider to the tornado settings: https://github.com/jupyter-server/jupyter_server/blob/v2.0.0/jupyter_server/serverapp.py#L242rX   rY   r   r%   r   )r   r&   )r@   r[   r\   r   r&   rA   r   )rC   r&   s     r2   r^   z&AuthenticatedHandler.identity_provider   s    dm33M3 	 	 	 	 =<<<<< 2B1A}((4882 2 2DM-. &6I(JKKKr1   r4   r;   r4   rJ   )r>   N)ra   r;   rb   r;   rc   rd   r4   rJ   r4   rs   )r4   r
   r4   rd   )r4   r$   )r4   r&   )rm   
__module____qualname____doc__propertyr=   rI   rU   r`   rg   ri   rr   ry   r|   r   r   r   r   r   r^   r0   r1   r2   r:   r:   S   s       66= = = X= 
 
 
 X
$   ( < < < X<	Y 	Y 	Y 	Y 	Y	8 	8 	8 	8       $	D 	D 	D 	D C C C XC 2 2 2 X2
 	: 	: 	: X	: , , , X, B B B XB C C C XC, L L L XL L Lr1   r:   c                      e Zd ZdZed>d            Zed?d            Zed@d            ZedAd
            ZedBd            Z	edBd            Z
edBd            ZedBd            ZedBd            ZedBd            ZedCd            ZedDd            ZedEd            ZedFd            ZedGd            ZedHd            ZedId            ZedBd             ZedJd"            ZedKd$            ZdL fd&ZdLd'ZdMd)ZdJd*ZdNdOd-ZdKd.ZdL fd/ZdKd0Z d1d2dP fd4Z!d5 Z"d6 Z#ed@d7            Z$d>d8Z%dQd=Z& xZ'S )RJupyterHandlerzwJupyter-specific extensions to authenticated handling

    Mostly property shortcuts to Jupyter-specific settings.
    r4   dict[str, Any] | Nonec                T    t          d| j                            dd                     S )Nr   r   r   r@   rA   rB   s    r2   r   zJupyterHandler.config  s%    +T]->->x-N-NOOOr1   r   c                    t                      S )z@use the Jupyter log by default, falling back on tornado's logger)r8   rB   s    r2   r8   zJupyterHandler.log  s     uur1   dict[str, Any]c                T    t          d| j                            di                     S )z2User-supplied values to supply to jinja templates.r   jinja_template_varsr   rB   s    r2   r   z"JupyterHandler.jinja_template_vars!  s(     $dm&7&78Mr&R&RSSSr1   ServerApp | Nonec                8    t          d| j        d                   S )Nr   	serverappr   r@   rB   s    r2   r   zJupyterHandler.serverapp&  s    &k(BCCCr1   r;   c                ^    t          t          | j                            dd                    S )z8The version hash to use for cache hints for static filesversion_hash r?   rB   s    r2   r   zJupyterHandler.version_hash.  &     C**>2>>???r1   c                    t          t          | j                            dd                    }|rt	          |          r|S t          | j        |          S )Nmathjax_urlr   )r   r;   r@   rA   r   r   r=   )rC   urls     r2   r   zJupyterHandler.mathjax_url3  sQ    3))-<<== 	oc** 	JT]C000r1   c                ^    t          t          | j                            dd                    S )Nmathjax_configzTeX-AMS-MML_HTMLorMML-full,Safer?   rB   s    r2   r   zJupyterHandler.mathjax_config:  s&    C**+;=^__```r1   c                ^    t          t          | j                            dd                    S )Ndefault_urlr   r?   rB   s    r2   r   zJupyterHandler.default_url>  s$    C**="==>>>r1   c                ^    t          t          | j                            dd                    S )Nwebsocket_urlr   r?   rB   s    r2   ws_urlzJupyterHandler.ws_urlB  s$    C**?B??@@@r1   c                    | j                             d| j                            dd                     t	          t
          | j                            dd                    S )NzUsing contents: %scontents_js_sourcezservices/contents)r8   debugr@   rA   r   r;   rB   s    r2   r   z!JupyterHandler.contents_js_sourceF  sZ     M24GHH	
 	
 	
 C**+?ATUUVVVr1   r*   c                8    t          d| j        d                   S )Nr*   kernel_managerr   rB   s    r2   r   zJupyterHandler.kernel_managerR  s    /?O1PQQQr1   r)   c                8    t          d| j        d                   S )Nr)   contents_managerr   rB   s    r2   r   zJupyterHandler.contents_managerV      %t}5G'HIIIr1   r+   c                8    t          d| j        d                   S )Nr+   session_managerr   rB   s    r2   r   zJupyterHandler.session_managerZ  s    $dm4E&FGGGr1   r"   c                8    t          d| j        d                   S )Nr"   terminal_managerr   rB   s    r2   r   zJupyterHandler.terminal_manager^  r   r1   r    c                8    t          d| j        d                   S )Nr    kernel_spec_managerr   rB   s    r2   r   z"JupyterHandler.kernel_spec_managerb  s    '7L)MNNNr1   r(   c                8    t          d| j        d                   S )Nr(   config_managerr   rB   s    r2   r   zJupyterHandler.config_managerf  s    OT]3C%DEEEr1   r!   c                8    t          d| j        d                   S )Nr!   event_loggerr   rB   s    r2   r   zJupyterHandler.event_loggerj  s    M4=#@AAAr1   c                ^    t          t          | j                            dd                    S )z"Normal Access-Control-Allow-Originallow_originr   r?   rB   s    r2   r   zJupyterHandler.allow_originr  r   r1   rd   c                T    t          d| j                            dd                    S )z*Regular expression version of allow_originrd   allow_origin_patNr   rB   s    r2   r   zJupyterHandler.allow_origin_patw  s'     L$-"3"34F"M"MNNNr1   rs   c                ^    t          t          | j                            dd                    S )z/Whether to set Access-Control-Allow-Credentialsallow_credentialsF)r   rs   r@   rA   rB   s    r2   r   z JupyterHandler.allow_credentials|  s'     D$-++,?GGHHHr1   rJ   c                H    t                                                       dS )zAdd CORS headers, if definedN)superrU   rC   rl   s    r2   rU   z"JupyterHandler.set_default_headers  s    ##%%%%%r1   c                   | j         r|                     d| j                    n| j        rG|                                 }|r0t	          j        | j        |          r|                     d|           nX| j        rQd| j                            di           vr4|                     d| j	        j
                            dd                     | j        r|                     dd           dS dS )zAdd CORS headers, if defined

        Now that current_user is async (jupyter-server 2.0),
        must be called at the end of prepare(), instead of in set_default_headers.
        Access-Control-Allow-OriginrF   Originr   z Access-Control-Allow-CredentialstrueN)r   rO   r   
get_originrematchr|   r@   rA   rv   rF   r   rC   origins     r2   set_cors_headerszJupyterHandler.set_cors_headers  s     	cOO94;LMMMM" 		c__&&F G"(4#8&AA G =vFFF% 	c*Gt}O`O`rP
 P
 +
 +

 OO94<;O;S;ST\^`;a;abbb! 	HOO>GGGGG	H 	Hr1   filenamec                V    t          |          }|                     dd|            dS )zpSet Content-Disposition: attachment header

        As a method to ensure handling of filename encoding
        zContent-Dispositionzattachment; filename*=utf-8''N)r   rO   )rC   r   escaped_filenames      r2   set_attachment_headerz$JupyterHandler.set_attachment_header  sA    
 &h//!>,<>>	
 	
 	
 	
 	
r1   c                    d| j         j        v r | j         j                            d          }n | j         j                            dd           }|S )Nr   zSec-Websocket-Origin)rv   rF   rA   r   s     r2   r   zJupyterHandler.get_origin  sN    
 t|+++\)--h77FF\)--.DdKKFr1   r   origin_to_satisfy_tornadoc                $   | j         dk    s|                                 rdS | j        j                            d          }| j        j                            d          }||dS |                                }t          |          j        }||k    rdS | j         rt          | j         |k              }n1| j	        r(t          t          j        | j	        |                    }nd}|s'| j                            d| j        j        ||           |S )zCheck Origin for cross-site API requests, including websockets

        Copied from WebSocket with changes:

        - allow unspecified host/origin (e.g. scripts)
        - allow token-authenticated requests
        *THostr   NFz?Blocking Cross Origin API request for %s.  Origin: %s, Host: %s)r   ry   rv   rF   rA   lowerr   netlocrs   r   r   r   r8   warningrb   )rC   r   hostr   origin_hostallows         r2   check_originzJupyterHandler.check_origin  s%    ##t'='='?'?#4|#''//%))(33 >T\4v&&- $4  	*f455EE" 	$"7@@AAEE E 	HQ!	   r1   c                t   | j         dk    s|                                 rdS | j        j                            d          }| j        j                            d          }|s| j                            d           dS |s| j                            d           dS t          |          }|j        }||k    rdS |j	         d|j         }| j         r| j         |k    }n1| j
        r(t          t          j        | j
        |                    }nd}|s'| j                            d	| j        j        ||           |S )
a[  Check Referer for cross-site requests.
        Disables requests to certain endpoints with
        external or missing Referer.
        If set, allow_origin settings are applied to the Referer
        to whitelist specific cross-origin sites.
        Used on GET for api endpoints and /files/
        to block cross-site inclusion (XSSI).
        r   Tr   RefererzBlocking request with no hostFz Blocking request with no refererz://z<Blocking Cross Origin request for %s.  Referer: %s, Host: %s)r   ry   rv   rF   rA   r8   r   r   r   schemer   rs   r   r   rb   )rC   r   refererreferer_urlreferer_hostr   r   s          r2   check_refererzJupyterHandler.check_referer  sd    ##t'='='?'?#4|#''//,&**955 	H<===5 	H?@@@5w''")44  &??;+=?? 	%/EE" 	$"7@@AAEE E 	HN!	   r1   c                   t          | d          sdS | j        s| j                            dd          rdS 	 t	                                                      S # t          j        $ ro}| j        j	        dv rU| 
                                s@| j        j                            d          }|rd| d}nd	}t          j        d
|          |n Y d}~dS d}~ww xY w)z2Bypass xsrf cookie checks when token-authenticatedrk   Ndisable_check_xsrfF>   GETHEADr   z#Blocking Cross Origin request from .z$Blocking request from unknown origin  )rn   r|   r@   rA   r   check_xsrf_cookier   	HTTPErrorrv   rw   r   rF   )rC   rT   r   rq   rl   s       r2   r   z JupyterHandler.check_xsrf_cookie  s   t455 	4# 	t}'8'89Mu'U'U 	 4	77,,...} 	 	 	|"o55))++ 9"l266yAAG ENGNNND-S11q89 9 9 9 9 9 9	s   A C(A$CCc                   | j                             dd          rdS t          j        d| j        j                  }|J |                    d          }|                    d          r|                    d          r
|dd	         }t          |          }|                    d
          r"t          j                            |          rd}nK	 t          j        |          }|j        }n.# t           $ r! || j                             ddg          v }Y nw xY w|s&| j                            d|| j        j                   |S )zCheck the host header if remote access disallowed.

        Returns True if the request should continue, False otherwise.
        allow_remote_accessFTz^(.*?)(:\d+)?$N   []r>   local_hostnames	localhostzBlocking request with non-local 'Host' %s (%s). If the server should be accessible at that name, set ServerApp.allow_remote_access to disable the check.)r@   rA   r   r   rv   r   group
startswithendswithr   osrb   exists	ipaddress
ip_addressis_loopback
ValueErrorr8   r   )rC   r   r   
check_hostr   addrs         r2   r  zJupyterHandler.check_host(  sr   
 =2E:: 	4 *DL,=>>   {{1~~ ??3 	DMM#$6$6 	":D 055
  %% 		)"'..*D*D 		)EE) +D11
 (	  T T T 1 12Ck] S SST  		HN !   s   C- -(DDT)_redirect_to_loginAwaitable[None] | Nonec                 K   t          j        t           j        |            |                                 s"dx| _        | _        t          j        d          ddlm	} t          j        | j                  }|J d}t          | j                  |u rN|j        t          k    r>t!          j        dt$          d           t'          |                                           }n9| j                            |           }t+          |t,                    r| d{V }|}|x| _        | _        |                                  | j        j        dvr|                                  | j                            d	d
          s| j        j        st          d          t;          | | j        j                                                  }t;          |dd
          sg|r  t          j        fd          |           S | j        }|<| j         !                    d| j"        j         d           t          j        d          tG                      $                                S )zPrepare a response.Nr   r   r%   znOverriding JupyterHandler.get_current_user is deprecated in jupyter-server 2.0. Use an IdentityProvider class.r   rY   >   r   r   ru   allow_unauthenticated_accessF__allow_unauthenticatedc                D    t                                                      S N)r   prepare)_rl   s    r2   <lambda>z(JupyterHandler.prepare.<locals>.<lambda>  s    uww7H7H r1   zCouldn't authenticate z connection)%r   setJUPYTER_HANDLERr  r   rk   r   r   r   r&   inspect	getmodulerr   typer^   rm   r[   r\   r]   r   get_user
isinstancer   r   rv   rw   r   r@   rA   getattrr   authenticatedr8   r   rl   r   r  )rC   r	  r&   mod_objr   _userrw   rl   s          r2   r  zJupyterHandler.prepareR  sn      	3T:::   	%=AAD :-$$$888888#D$9::""" &''+;;;@PT\@\@\ M2"	    --//00DD*33D99E%++ $#D
 :>=D6<&@@@""$$$}  !?GG 	1<& %nn$T4<#6#<#<#>#>??F6#<eDD 1% 1 J3,-H-H-H-HII$OOO  ,D|((YT^5LYYY   "mC000ww   r1   c                B    | j         d                             |          S )z1Return the jinja template object for a given name
jinja2_env)r@   get_template)rC   ra   s     r2   r   zJupyterHandler.get_template  s    }\*77===r1   c                z    |                     | j                   |                     |          } |j        di |S )zRender a template by name.r0   )rM   template_namespacer   render)rC   ra   nstemplates       r2   render_templatezJupyterHandler.render_template  sB    
		$)***$$T**x$$$$$r1   c                   t          di d| j        d| j        d| j        d| j        dt          | j        dd          d| j        j        d| j        j        d	t          | j
                  d
| j        dt                      d| j        d| j        d| j        d| j
        d| j                            d          dt%          j        t)          | j        j                            dd                              | j        S )Nr=   r   r   r   allow_password_changeFauth_enabledr   token_available
static_urlsys_infor   r   xsrf_form_htmlr   
xsrf_tokenutf8nbjs_translationszAccept-Languager   r0   )dictr=   r   r   r   r  r^   r)  r   rs   r   r+  r3   r   r   r-  r.  decoder.   r/   r   rv   rF   rA   r   rB   s    r2   r"  z!JupyterHandler.template_namespace  sm    
 
 
]]
((
 ;;
 nn	

 #*$*@BY[`"a"a"a
 /<<
 !2BB
 !,,,
 
 #___
  $66
 **
  ..
 **
 --f555
  #j$T\%9%=%=>OQS%T%TUU   &'
 
 	
r1   c                   | j         j        sdS | j         j                                                            d          }	 t	          j        |          }n_# t          $ rR}| j                            d|           | j        	                    dd           t          j        dd          |d}~ww xY wt          d	|          S )
z,Return the body of the request as JSON data.Nzutf-8zBad JSON: %rzCouldn't parse JSONTexc_infoi  zInvalid JSON in body of requestr   )rv   bodystripr2  r.   loadsrP   r8   r   errorr   r   r   )rC   r6  modelrT   s       r2   get_json_bodyzJupyterHandler.get_json_body  s    |  	4| &&((//88	OJt$$EE 	O 	O 	OHNN>4000HNN04N@@@-%FGGQN	O $e,,,s   A 
B2 AB--B2status_codeintkwargsr
   c                   |                     d          }d}t          j         |d          }|r?|d         }	 |j        |j        z  }n# t          $ r Y nw xY wt          |dd          }|r|}nd}||||d}|                     dd	           	  | j        d
|z  fi |}	n# t          $ r  | j        di |}	Y nw xY w| 	                    |	           dS )zrender custom error pagesr5  r   Unknown HTTP Errorr   reasonz	(unknown))r<  status_messagemessagerQ   Content-Typez	text/htmlz%s.html
error.htmlN)rE  )
rA   r   log_messageargsrP   r  rO   r&  r   write)
rC   r<  r>  r5  rC  rB  rQ   rA  r$  htmls
             r2   write_errorzJupyterHandler.write_error  s>   ::j))"{4HII 	$ I#/).@    Y"55F (!'#I ',"	
 
 	444	<'4'	K(?FF2FFDD 	< 	< 	<'4';;;;DDD	< 	

4s#   A 
AAB   B:9B:)r4   r   r4   r   )r4   r   )r4   r   r   )r4   r*   )r4   r)   )r4   r+   )r4   r"   )r4   r    )r4   r(   )r4   r!   r   r   r   )r   r;   r4   rJ   r   )r   r;   r4   rs   )r4   r
  r<  r=  r>  r
   r4   rJ   )(rm   r   r   r   r   r   r8   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rU   r   r   r   r   r   r   r  r  r   r&  r"  r;  rJ  __classcell__rl   s   @r2   r   r     sA        
 P P P XP    X T T T XT D D D XD @ @ @ X@ 1 1 1 X1 a a a Xa ? ? ? X? A A A XA W W W XW R R R XR J J J XJ H H H XH J J J XJ O O O XO F F F XF B B B XB @ @ @ X@ O O O XO I I I XI& & & & & &H H H H,	
 	
 	
 	
	 	 	 	- - - - -^, , , ,\     0( ( ( (T 37 <! <! <! <! <! <! <! <!D> > >% % % 
 
 
 X
.- - - -$ $ $ $ $ $ $ $r1   r   c                       e Zd ZdZd fdZdd	Zd fdZed fd            ZdZ	ddZ
d fdZedd            Z xZS )
APIHandlerzBase class for API handlersr4   rJ   c                   K   t                                                       d{V  |                                 st          j        d          dS )zPrepare an API response.N  )r   r  r   r   r   r   s    r2   r  zAPIHandler.prepare  s[      ggoo  "" 	%-$$$	% 	%r1   r<  r=  r>  r
   c                   |                      dd           t          j        |d          }d|i}|                    d          }|rC|d         }t          |t                    r|j        p||d<   |j        |d<   nd|d<   d	|d<   d
|d<   | j                            d|d         d           | 	                    t          j        |                     d	S )z+APIHandler errors are JSON, not human pagesrD  application/jsonr@  rC  r5  r   rA  zUnhandled errorNr   	tracebackzwrote error: %rTr4  )rO   r   rA   r  r   rF  rA  r8   r   finishr.   r/   )rC   r<  r>  rC  replyr5  rT   s          r2   rJ  zAPIHandler.write_error  s    (:;;;--ABBw!
 ::j)) 
	(A!Y'' (#$=#;Gi "#(h#4i "&h &(k"*E),<tLLLDJu%%&&&&&r1   r;   c                z    | j         st          j        d          t                                                      S )zGet the login url.r   )r   r   r   r   get_login_urlr   s    r2   rZ  zAPIHandler.get_login_url
  s6    
   	%-$$$ww$$&&&r1   c                X    d                     t                      j        dg          }|S )NrG   zdefault-src 'none')rH   r   rI   )rC   csprl   s     r2   rI   z"APIHandler.content_security_policy  s/    ii/$
 
 
r1   Tc                    | j         r?t          | dd          r0|                     dd          t                      | j        d<   dS dS dS dS )z$Update last_activity of API requestsrk   Nno_track_activityapi_last_activity)_track_activityr  get_argumentr   r@   rB   s    r2   update_api_activityzAPIHandler.update_api_activity   sq      	:5t<<	: !!"5t<<D17DM-...	: 	: 	: 	: EDr1   rG  Future[Any]c                    |                                   |                    dd          }|                     d|            t                      j        |i |S )zFinish an API response.set_content_typerU  rD  )rb  poprO   r   rW  )rC   rG  r>  re  rl   s       r2   rW  zAPIHandler.finish*  s[      """!::&8:LMM(8999uww~t.v...r1   c                `   d| j                             di           v r(|                     d| j         d         d                    n|                     dd           |                     dd           | j        j                            dd                              d          }|rt          d	 |D                       rj| j        re| j        s$| j	        sd
| j                             di           v r<|                     d
| j        j                            dd                     dS dS dS dS dS )zGet the options.zAccess-Control-Allow-HeadersrF   z0accept, content-type, authorization, x-xsrftokenzAccess-Control-Allow-Methodsz&GET, PUT, POST, PATCH, DELETE, OPTIONSzAccess-Control-Request-Headersr   ,c              3  j   K   | ].}|                                                                 d k    V  /dS )authorizationN)r7  r   ).0hs     r2   	<genexpr>z%APIHandler.options.<locals>.<genexpr>L  s9      TTQAGGIIOO%%8TTTTTTr1   r   r   N)
r@   rA   rO   rv   rF   splitanyr   r   r   )rC   rG  r>  requested_headerss       r2   optionszAPIHandler.options2  s    *T]->->y"-M-MMMOO.i()GH   
 OO.B   	68`aaa !L0445UWYZZ``
 
 	cTTBSTTTTT	c $	c !	c (	c 1DM4E4EiQS4T4TTT OO94<;O;S;ST\^`;a;abbbbb	c 	c 	c 	c 	c 	c UTr1   r   rM  r   )rG  r
   r>  r
   r4   rc  )rG  r
   r>  r
   r4   rJ   )rm   r   r   r   r  rJ  rZ  r   rI   r`  rb  rW  r   rq  rN  rO  s   @r2   rQ  rQ    s       %%% % % % % %' ' ' ',' ' ' ' ' '      X O: : : :/ / / / / / %c %c %c %c %c %c %c %cr1   rQ  c                  $     e Zd ZdZd fdZ xZS )Template404zRender our 404 templater4   rJ   c                |   K   t                                                       d{V  t          j        d          )zPrepare a 404 response.NrS  )r   r  r   r   r   s    r2   r  zTemplate404.prepare^  s=      ggoomC   r1   r   )rm   r   r   r   r  rN  rO  s   @r2   rs  rs  [  sC        !!! ! ! ! ! ! ! ! ! !r1   rs  c                       e Zd ZdZdZed fd            Zej        e	d fd                        Z
ej        e	dd                        Zd fdZd fdZddZd fdZ xZS )AuthenticatedFileHandlerz5static files should only be accessible when logged incontentsr4   r;   c                0    t                      j        dz   S )Nz; sandbox allow-scripts)r   rI   r   s    r2   rI   z0AuthenticatedFileHandler.content_security_policyi  s     ww.1JJJr1   rb   Awaitable[None]c                n    |                                   t                                          |          S )z!Get the head response for a path.)r   r   headrC   rb   rl   s     r2   r{  zAuthenticatedFileHandler.heado  s-     	   ww||D!!!r1   r>  r
   c                :   |                                   t          j                            |          d         dk    s|                     dd          r1|                    dd          d         }|                     |           t          j        j	        | |fi |S )zGet a file by path.r   .ipynbdownloadNr>   r   )
r   r  rb   splitextra  rsplitr   r   StaticFileHandlerrA   )rC   rb   r>  ra   s       r2   rA   zAuthenticatedFileHandler.getv  s     	   7D!!!$00D4E4EjRV4W4W0;;sA&&r*D&&t,,,$(t>>v>>>r1   c                <   | j         J | j                             d          }d|v r|                    dd          \  }}n|}|                    d          rdS t	          j        |          d         }|dk    rdS t                                                      S )	zGet the content type.Nr>   r   r~  zapplication/x-ipynb+jsonr   z
text/plainztext/plain; charset=UTF-8)absolute_pathr7  r  r   	mimetypes
guess_typer   get_content_type)rC   rb   r  ra   cur_mimerl   s        r2   r  z)AuthenticatedFileHandler.get_content_type  s    !---!'',,$;;kk#q))GAttD=="" 	2-- +D11!4H<''22ww//111r1   rJ   c                    t                                                       d| j        j        vr|                     dd           dS dS )Set the headers.vCache-Controlno-cacheN)r   set_headersrv   	arguments
add_headerr   s    r2   r  z$AuthenticatedFileHandler.set_headers  sK    dl,,,OOOZ88888 -,r1   rd   c                    dS zCompute the etag.Nr0   rB   s    r2   compute_etagz%AuthenticatedFileHandler.compute_etag      tr1   rootr  c                &   t                                          ||          }t          j                            |          }|J | j        j        s>t          ||          r.| j        	                    d           t          j        d          |S )zValidate and return the absolute path.

        Requires tornado 3.1

        Adding to tornado's own handling, forbids the serving of hidden files.
        Nz_Refusing to serve hidden file, via 404 Error, use flag 'ContentsManager.allow_hidden' to enablerS  )r   validate_absolute_pathr  rb   abspathr   allow_hiddenr   r8   infor   r   )rC   r  r  abs_pathabs_rootrl   s        r2   r  z/AuthenticatedFileHandler.validate_absolute_path  s     7711$FF7??4((###$1 	%i(6S6S 	%HMMq   -$$$r1   r   rb   r;   r4   ry  )rb   r;   r>  r
   r4   ry  r   r   )r  r;   r  r;   r4   r;   )rm   r   r   r   auth_resourcer   rI   r   r  r   r{  rA   r  r  r  r  rN  rO  s   @r2   rv  rv  d  s,       ??MK K K K K XK
 	" " " " " Z "
 		? 	? 	? Z 	?2 2 2 2 2 2"9 9 9 9 9 9            r1   rv  rw   r
   c                ~     t          j        dt          d           t          j                    fd            }|S )a  Decorate methods with this to return GitHub style JSON errors.

    This should be used on any JSON API on any handler method that can raise HTTPErrors.

    This will grab the latest HTTPError exception using sys.exc_info
    and then:

    1. Set the HTTP status code based on the HTTPError
    2. Create and return a JSON body with a message field describing
       the error in a human readable form.
    zJ@json_errors is deprecated in notebook 5.2.0. Subclass APIHandler instead.rX   rY   c                d    t          j        t          j        |           | _         | g|R i |S r  )types
MethodTyperQ  rJ  )rC   rG  r>  rw   s      r2   wrapperzjson_errors.<locals>.wrapper  s;     +J,BDIIvd,T,,,V,,,r1   )r[   r\   r]   	functoolswraps)rw   r  s   ` r2   json_errorsr    s^     MT    _V- - - - - Nr1   c                       e Zd ZU dZi Zded<   ded<   d fdZ	 	 d d!dZd"dZe	d#d$ fd            Z
e	d% fd            Zed&d            Zd' fdZ xZS )(FileFindHandlera=  subclass of StaticFileHandler for serving files from a search path

    The setting "static_immutable_cache" can be set up to serve some static
    file as immutable (e.g. file name containing a hash). The setting is a
    list of base URL, every static file URL starting with one of those will
    be immutable.
    zdict[str, str]_static_pathsz
tuple[str]r  r4   rJ   c                r    t                                                        j                            dg           }t	           fd|D                       r                     dd           dS d j        j        vs t	           fd j        D                       r                     dd           dS dS )	r  static_immutable_cachec              3  V   K   | ]#}j         j                            |          V  $d S r  rv   rb   r   rk  rb   rC   s     r2   rm  z.FileFindHandler.set_headers.<locals>.<genexpr>  s6      NNdt| ++D11NNNNNNr1   r  z#public, max-age=31536000, immutabler  c              3  V   K   | ]#}j         j                            |          V  $d S r  r  r  s     r2   rm  z.FileFindHandler.set_headers.<locals>.<genexpr>  sG       6
 6
37DL((..6
 6
 6
 6
 6
 6
r1   r  N)	r   r  r@   rA   ro  rO   rv   r  no_cache_paths)rC   immutable_pathsrl   s   ` r2   r  zFileFindHandler.set_headers  s    -++,DbII NNNNoNNNNN 	9OOO-RSSSSS ...# 6
 6
 6
 6
;?;N6
 6
 6
 3
 3
. OOOZ88888 /.r1   Nrb   str | list[str]default_filenamerd   r  list[str] | Nonec                    |pg | _         t          |t                    r|g}t          d |D                       | _        || _        dS )z!Initialize the file find handler.c              3     K   | ]M}t           j                            t           j                            |                    t           j        z   V  Nd S r  )r  rb   r  
expandusersep)rk  ps     r2   rm  z-FileFindHandler.initialize.<locals>.<genexpr>  sG      XXa"'//"'*<*<Q*?*?@@26IXXXXXXr1   N)r  r  r;   tupler  r  )rC   rb   r  r  s       r2   
initializezFileFindHandler.initialize  sW     -2dC   	6DXXSWXXXXX	 0r1   c                    dS r  r0   rB   s    r2   r  zFileFindHandler.compute_etag  r  r1   Tr;   include_bodyrs   Coroutine[Any, Any, None]c                H    t                                          ||          S r  r   rA   rC   rb   r  rl   s      r2   rA   zFileFindHandler.get      ww{{4...r1   ry  c                F    t                                          |          S r  r   r{  r|  s     r2   r{  zFileFindHandler.head      ww||D!!!r1   rootsSequence[str]c                   | j         5  || j        v r| j        |         cddd           S 	 t          j                            t          ||                    }n# t          $ r Y ddd           dS w xY w|| j        |<   t                                          d| d|            |cddd           S # 1 swxY w Y   dS )z5locate a file to serve on our static file search pathNr   zPath z served from )	_lockr  r  rb   r  r   OSErrorr8   r   )clsr  rb   r  s       r2   get_absolute_pathz!FileFindHandler.get_absolute_path  sT    Y 	 	s((((.	 	 	 	 	 	 	 	'//(4*?*?@@   	 	 	 	 	 	 	 	
 '.Cd#EEKK<<<7<<===	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s4   B5-AB5
A3$B52A335B55B9<B9r  c                    |st          j        d          | j        D ]&}|t          j        z                       |          r n't                                          ||          S )z:check if the file should be served (raises 404, 403, etc.)rS  )r   r   r  r  r  r   r   r  )rC   r  r  rl   s      r2   r  z&FileFindHandler.validate_absolute_path   so     	%-$$$I 	 	D&22488  ww--dMBBBr1   r   )NN)rb   r  r  rd   r  r  r4   rJ   r   Trb   r;   r  rs   r4   r  r  )r  r  rb   r;   r4   r;   )r  r;   r  r;   r4   rd   )rm   r   r   r   r  __annotations__r  r  r  r   rA   r{  classmethodr  r  rN  rO  s   @r2   r  r    s@          %'M&&&&9 9 9 9 9 9& (,+/	1 1 1 1 1    / / / / / / /
 " " " " " "    [ 	C 	C 	C 	C 	C 	C 	C 	C 	C 	Cr1   r  c                  .    e Zd ZdZdZedd            ZdS )APIVersionHandlerz&An API handler for the server version.Fr4   rJ   c                l    |                      t          j        dt          j        i                     dS )zGet the server version info.versionN)rW  r.   r/   jupyter_server__version__rB   s    r2   rA   zAPIVersionHandler.get1  s.     	DJ	>+EFGGHHHHHr1   Nr   )rm   r   r   r   r`  r   rA   r0   r1   r2   r  r  ,  sD        00OI I I I I Ir1   r  c                  2    e Zd ZdZedd            ZexZZdS )TrailingSlashHandlerzrSimple redirect handler that strips trailing slashes

    This should be the first, highest priority handler.
    r4   rJ   c                    | j         j        J | j         j                            d          ^}}d|                    d          z   }d                    |g|          }|                     |           dS )z!Handle trailing slashes in a get.N?r>   r   )rv   uri	partitionr7  rH   redirect)rC   rb   restnew_uris       r2   rA   zTrailingSlashHandler.get>  sv     |+++l&0055t TZZ__$''4-$-((gr1   Nr   rm   r   r   r   r   rA   postputr0   r1   r2   r  r  8  sE         
     D333r1   r  c                  2    e Zd ZdZedd            ZexZZdS )MainHandlerzSimple handler for base_url.r4   rJ   c                Z    |                      d          }|                     |           dS )zGet the main template.z	main.htmlN)r&  rH  )rC   rI  s     r2   rA   zMainHandler.getO  s/     ##K00

4r1   Nr   r  r0   r1   r2   r  r  L  s?        &&   
 D333r1   r  c                  D    e Zd ZdZedd            Zeddd
            ZdS )FilesRedirectHandlerz<Handler for redirecting relative URLs to the /files/ handlerrC   r
   rb   r;   r4   rJ   c                  K   | j         }t          |                    |                     d{V r$t          | j        dt          |                    }n|}|                    d          }t          |                    |                     d{V sId|v rE| j        	                    d|           |
                    d           d                    |          }t          |                    |                     d{V st          j        d          t          | j        dt          |                    }| j                            d| j        j        |           |                     |           dS )	zgmake redirect logic a reusable static method

        so it can be called from other handlers.
        Ntreer>   )rb   fileszDeprecated files/ URL: %srS  zRedirecting %s to %s)r   r   
dir_existsr   r=   r   rn  file_existsr8   r   removerH   r   r   r   rv   rb   r  )rC   rb   cmr   	orig_pathpartss         r2   redirect_to_filesz&FilesRedirectHandler.redirect_to_files[  sx      "bmmD1122222222 	Jvz$7G7GHHCCIJJsOOE%bnn$n&?&?@@@@@@@@ 'WPUEUEU   !<iHHHW%%%xx%bnn$n&?&?@@@@@@@@ )mC(((w
48H8HIIC-t|/@#FFFcr1   r   c                >   K   |                      | |           d {V S r  )r  )rC   rb   s     r2   rA   zFilesRedirectHandler.getx  s.      ++D$777777777r1   N)rC   r
   rb   r;   r4   rJ   rL  )rb   r;   r4   rJ   )rm   r   r   r   staticmethodr  r   rA   r0   r1   r2   r  r  X  s^        FF   \8 8 8 8 8 8 8 8r1   r  c                  4    e Zd ZdZddd	Zedd
            ZdS )RedirectWithParamsz9Same as web.RedirectHandler, but preserves URL parametersTr   r;   	permanentrs   r4   rJ   c                "    || _         || _        dS )zInitialize a redirect handler.N)_url
_permanent)rC   r   r  s      r2   r  zRedirectWithParams.initialize  s    	#r1   c                    d| j         v rdnd}|                    | j         | j        j        g          }|                     || j                   dS )zGet a redirect.r  &)r  N)r  rH   rv   queryr  r  )rC   r  r   s      r2   rA   zRedirectWithParams.get  sT     DI%%cc3hh	4<#5677cT_55555r1   Nr  )r   r;   r  rs   r4   rJ   r   )rm   r   r   r   r  r   rA   r0   r1   r2   r  r  }  sT        CC$ $ $ $ $
 6 6 6 6 6 6r1   r  c                  *    e Zd ZdZedd            ZdS )PrometheusMetricsHandlerz3
    Return prometheus metrics for this server
    r4   rJ   c                    | j         d         r| j        st          j        d          |                     dt
          j                   |                     t          j        t
          j	                             dS )zGet prometheus metrics.authenticate_prometheusr   rD  N)
r@   r   r   r   rO   prometheus_clientCONTENT_TYPE_LATESTrH  generate_latestREGISTRYrB   s    r2   rA   zPrometheusMetricsHandler.get  sm     =23 	%DN 	%-$$$(9(MNNN

$45F5OPPQQQQQr1   Nr   )rm   r   r   r   r   rA   r0   r1   r2   r  r    sE          R R R R R Rr1   r  c                  R     e Zd ZdZed fd            Zedd fd            Z xZS )PublicStaticFileHandlerzVSame as web.StaticFileHandler, but decorated to acknowledge that auth is not required.rb   r;   r4   ry  c                F    t                                          |          S r  r  r|  s     r2   r{  zPublicStaticFileHandler.head  r  r1   Tr  rs   r  c                H    t                                          ||          S r  r  r  s      r2   rA   zPublicStaticFileHandler.get  r  r1   r  r  r  )rm   r   r   r   r   r{  rA   rN  rO  s   @r2   r  r    s~        ``" " " " " " / / / / / / / / / / /r1   r  z(?P<path>(?:(?:/[^/]+)+|/?))z.*/apiz/(robots\.txt|favicon\.ico)z/metricsrK  )rw   r
   r4   r
   )fr   
__future__r   r  r  r  r.   r  r  r   r  r[   collections.abcr   r   r   http.clientr   loggingr   typingr	   r
   r   urllib.parser   r  jinja2r   jupyter_core.pathsr   tornador   tornado.logr   traitlets.configr   r  r   jupyter_server._sysinfor   jupyter_server._tzr   jupyter_server.auth.decoratorr   r   jupyter_server.auth.identityr   jupyter_server.i18nr    jupyter_server.services.securityr   jupyter_server.utilsr   r   r   r   r   r   jupyter_client.kernelspecr    jupyter_eventsr!   (jupyter_server_terminals.terminalmanagerr"   tornado.concurrentr#   jupyter_server.auth.authorizerr$   r&   jupyter_server.serverappr'   &jupyter_server.services.config.managerr(   (jupyter_server.services.contents.managerr)   -jupyter_server.services.kernels.kernelmanagerr*   /jupyter_server.services.sessions.sessionmanagerr+   r-   r3   r8   RequestHandlerr:   r   rQ  rs  r  rv  r  r   r  r  r  r  r  r  r  r  
path_regexdefault_handlersr0   r1   r2   <module>r*     s   3 3 # " " " " "               				 				   : : : : : : : : : : ! ! ! ! ! !       + + + + + + + + + + ! ! ! ! ! !     # # # # # # ( ( ( ( ( (             ( ( ( ( ( (     & & & & & & 0 0 0 0 0 0 % % % % % % K K K K K K K K - - - - - - 4 4 4 4 4 4 ; ; ; ; ; ;                 O;;;;;;******HHHHHH))))))999999======222222DDDDDDHHHHHHWWWWWWNNNNNN      |L |L |L |L |L3- |L |L |L~V V V V V) V V Vrmc mc mc mc mc mc mc mc`! ! ! ! !. ! ! !J J J J J~s/D J J JZ   > M	VC VC VC VC VCnc&; VC VC VCr	I 	I 	I 	I 	I
 	I 	I 	I    3-   (	 	 	 	 	. 	 	 	"8 "8 "8 "8 "8> "8 "8 "8J6 6 6 6 6+ 6 6 6 R R R R R~ R R R	/ 	/ 	/ 	/ 	/c3 	/ 	/ 	/" -
 !"#%<=*+	   r1   