
    )`i.                        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 d dlm	Z	 ddl
mZ ddlmZ  G d d	          Z G d
 d          Zdededz  fdZdedz  fdZdedz  fdZ ej                    Z ee          adS )    N)RLock)Optional   )logger   )SageMakerConfigc                   b    e Zd ZdZ	 ddededee         fdZdefdZddefd	Z	d
 Z
defdZdS )SessionzRepresents a single stateful session with file-based storage.

    Each session has a unique directory where it stores key-value data
    as JSON files. Sessions have an expiration timestamp and are automatically
    cleaned up when expired.
    N
session_idsession_rootexpiration_tsc                     || _         t          j                            ||          | _        || _        | j        |                     d          | _        dS dS )a*  Initialize a session instance.

        Args:
            session_id: Unique identifier for this session (typically UUID)
            session_root: Root directory where session directories are stored
            expiration_ts: Unix timestamp when session expires, or None to load from disk
        N.expiration_ts)r   ospathjoin
files_pathr   get)selfr   r   r   s       /home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/model_hosting_container_standards/sagemaker/sessions/manager.py__init__zSession.__init__   sV     %',,|Z@@*%!%*:!;!;D &%    keyc                     t          |                     |          d          5 }t          j        ||           ddd           dS # 1 swxY w Y   dS )a  Store a JSON-serializable value in the session.

        Args:
            key: The key to store the value under
            value: Must be JSON-serializable (str, int, float, bool, list, dict, None)

        Raises:
            TypeError: If value is not JSON-serializable
        wN)open_pathjsondump)r   r   valuefs       r   putzSession.put*   s     $**S//3'' 	 1IeQ	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 s   AAAc                     |                      |          }t          j                            |          s|S t	          |d          5 }t          j        |          cddd           S # 1 swxY w Y   dS )zRetrieve a value from the session.

        Args:
            key: The key to retrieve
            d: Default value if key doesn't exist

        Returns:
            The stored value or default if key not found
        rN)r   r   r   isfiler   r   load)r   r   dr   r!   s        r   r   zSession.get7   s     zz#w~~d## 	H$__ 	 9Q<<	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	  	 s   A((A,/A,c                     t           j                            | j                  st	          d| j                   t          j        d| j                    t          j	        | j                   dS )zDelete the session and all its stored data from disk.

        Returns:
            bool: True if deletion successful

        Raises:
            ValueError: If session directory doesn't exist
        z"session directory does not exist: zclosing session: T)
r   r   existsr   
ValueErrorr   r   infoshutilrmtree)r   s    r   removezSession.removeH   sh     w~~do.. 	US$/SSTTT999:::do&&&tr   c                    d|v rt          d| d          t          j                            |          rt          d| d          |                    dd          }t          j                            | j        |          }t          j                            |          }|                    t          j                            | j                  t          j	        z             st          d| d          |S )a-  Generate a safe file path within the session directory.

        Args:
            key: The key name for the session data file

        Returns:
            Absolute path to the file within the session directory

        Raises:
            ValueError: If key contains path traversal attempts
        z..z&Invalid key: '..' not allowed in key ''z)Invalid key: absolute paths not allowed '/-z&Invalid key: path traversal detected ')
r*   r   r   isabsreplacer   r   abspath
startswithsep)r   r   sanitized_key	file_pathresolved_paths        r   r   zSession._pathW   s     3;;LcLLLMMM7== 	QOOOOPPP C--GLL-@@	 	22''(H(H26(QRR 	NLcLLLMMMr   )N)__name__
__module____qualname____doc__strr   floatr   r"   r   r.   r    r   r   r
   r
      s          TX< <<-0<AI%< < < <" s           s        "        r   r
   c                   R    e Zd ZdZdefdZdefdZdede	e         fdZ
d Zd	 Zd
S )SessionManagera2  Manages the lifecycle of stateful sessions with automatic expiration and cleanup.

    SessionManager maintains a registry of active sessions, each stored in its own
    directory on disk. It handles session creation, retrieval, expiration checking,
    and cleanup. Thread-safe for concurrent access.
    
propertiesc                    t          |                    dt          d                              | _        |                    d          }|t          j                            t          j                    d          }t          j        	                    d          o+t	          j
        dt          j        t          j        z            }|rdn|}t          j        d|rd	nd
 d|            || _        i | _        t#                      | _        	 t	          j        | j        d           t	          j
        | j        t          j        t          j        z            st)          d| j                   t          j        d| j                    t	          j        | j                  D ]}t-          || j                  | j        |<    dS # t(          t.          f$ r}t          j        d| j         d| d           t          j                            t          j                    d          | _        t	          j        | j        d           t          j        d| j                    Y d}~dS d}~ww xY w)aQ  Initialize the SessionManager with configuration properties.

        Args:
            properties: Configuration dict with optional keys:
                - sessions_expiration: Session lifetime in seconds (default: 1200)
                - sessions_path: Root directory for session storage (default: /dev/shm/sagemaker_sessions)
        sessions_expirationi  sessions_pathNsagemaker_sessionsz/dev/shmz/dev/shm/sagemaker_sessionsz$Sessions path not configured, using zshared memoryztemp directoryz: T)exist_okzCannot write to z Session storage initialized at: z!Failed to initialize sessions at z . Falling back to temp directoryz)Session storage initialized at fallback: )intr   r?   
expirationr   r   r   tempfile
gettempdirr)   accessR_OKW_OKr   r+   rG   sessionsr   _lockmakedirsPermissionErrorlistdirr
   OSErrorwarning)r   rD   rG   temp_sessions_pathshm_accessibler   es          r   r   zSessionManager.__init__}   s    jnn-BCLLQQRR #77 !##%%';" "  W^^J77 BIBGbg-= =N 2@W--EW  K B.7n^n  B  Br  B  B   +,.WW
	K*T::::9T/271BCC O%&M9K&M&MNNNKO4;MOOPPP j);<< T T
,3J@R,S,Sj))T T) 	 	 	NmD4Fmm!mmm   "$#%%';" "D K*T::::KPD<NPP        	s   B8G	 	I2BI--I2returnc                    | j         5  |                                  t          t          j                              }t          j                    | j        z   }t          || j        |          }|| j	        |<   t          j        |j                   |                    d|           |cddd           S # 1 swxY w Y   dS )a>  Create a new session with a unique ID and expiration timestamp.

        Also triggers cleanup of any expired sessions before creating the new one.

        Returns:
            Session: The newly created session instance with UUID and expiration

        Thread-safe: Uses internal lock for concurrent access
        r   N)rR   _clean_expired_sessionr?   uuiduuid4timerK   r
   rG   rQ   r   rS   r   r"   )r   r   r   sessions       r   create_sessionzSessionManager.create_session   s     Z 	 	''))) TZ\\**J IKK$/9M j$*<mLLG(/DM*% K*+++KK(-888!	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   B B55B9<B9r   c                 ~   | j         5  |dk    s|s	 ddd           dS || j        vrt          d|           | j        |         }|j        Vt	          j                    |j        k    r:t          j        d|            |                     |           	 ddd           dS |cddd           S # 1 swxY w Y   dS )a  Retrieve a session by ID, checking for expiration.

        Args:
            session_id: The unique session identifier

        Returns:
            Session instance if found and not expired, None if session doesn't exist
            or has expired, or if session_id is "NEW_SESSION" or empty

        Raises:
            ValueError: If session_id is not found in registry

        Thread-safe: Uses internal lock for concurrent access
        NEW_SESSIONNsession not found: zSession expired: )rR   rQ   r*   r   r`   r   r+   close_sessionr   r   ra   s      r   get_sessionzSessionManager.get_session   sY    Z 	 	]****	 	 	 	 	 	 	 	 .. !Cz!C!CDDDmJ/G %1IKK'"777<
<<==="":...	 	 	 	 	 	 	 	" #	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   
B2A8B2$B22B69B6c                     | j         5  |st          d|           || j        vrt          d|           | j        |         }|                                 | j        |= ddd           dS # 1 swxY w Y   dS )a&  Close and remove a session, deleting all its data.

        Args:
            session_id: The unique session identifier to close

        Raises:
            ValueError: If session_id is empty/None or not found in registry

        Thread-safe: Uses internal lock for concurrent access
        zinvalid session_id: re   N)rR   r*   rQ   r.   rg   s      r   rf   zSessionManager.close_session   s     Z 
	* 
	* F !D
!D!DEEE.. !Cz!C!CDDDmJ/GNNj)
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	* 
	*s   AA..A25A2c                    | j         5  t          | j                                                  D ]=\  }}|j        t          j                    |j        k    r|                     |           >	 ddd           dS # 1 swxY w Y   dS )a  Internal method to remove all expired sessions.

        Iterates through all sessions and closes any that have expired.
        Called automatically during session creation to prevent stale session buildup.

        Thread-safe: Uses internal lock for concurrent access
        N)rR   listrQ   itemsr   r`   rf   rg   s      r   r]   z%SessionManager._clean_expired_session  s     Z 	3 	3'+DM,?,?,A,A'B'B 3 3#
G(0DIKK'BW4W4W&&z2223	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3 	3s   A%A;;A?A?N)r;   r<   r=   r>   dictr   r
   rb   r?   r   rh   rf   r]   rA   r   r   rC   rC   u   s         74 7 7 7 7r    8 c  hw.?        D* * *.3 3 3 3 3r   rC   configr[   c                 j    | j         r+t          | j                  | j        d}t	          |          S dS )zInitialize a SessionManager if stateful sessions are enabled.

    Args:
        config: SagemakerConfig instance with session settings

    Returns:
        SessionManager instance if enabled, None otherwise
    )rF   rG   N)enable_stateful_sessionsr?   rF   rG   rC   )rn   config_dicts     r   _init_session_managerrr     sF     & + $'v'A#B#B#1
 
 k***4r   c                      t           S )zGet the global session manager instance.

    Returns:
        The global SessionManager instance, or None if not initialized
    )session_managerrA   r   r   get_session_managerru   ,  s
     r   c                  T    t          j                    } t          |           at          S )a  Initialize the global session manager from environment variables.

    This can be called to reinitialize the session manager after environment
    variables have been set.

    Returns:
        The initialized SessionManager instance, or None if disabled
    )r   from_envrr   rt   )rn   s    r   init_session_manager_from_envrx   5  s%     %''F+F33Or   )r   r   r,   rL   r`   r^   	threadingr   typingr   logging_configr   rn   r   r
   rC   rr   ru   rx   rw   _configrt   rA   r   r   <module>r}      st    				                 $ $ $ $ $ $ $ $ $ $ $ $a a a a a a a aHa3 a3 a3 a3 a3 a3 a3 a3H/ nt6K    &^d2    ~'<      #/
"
$
$''00r   