
    Zǻi8|                        d Z ddlmZ ddlmZmZ ddlZddlmZ	 ddl
mZmZmZmZmZmZmZ ddlmZmZmZmZmZ ddlmZmZmZmZmZ dd	lmZ dd
l m!Z! ddZ"ddZ# G d d      Z$y)zEMain SandboxClient class for interacting with the sandbox server API.    )annotations)AnyOptionalN)utils)ResourceCreationErrorResourceInUseErrorResourceNameConflictErrorResourceNotFoundErrorResourceTimeoutErrorSandboxAPIErrorValidationError)handle_client_http_errorhandle_pool_errorhandle_sandbox_creation_errorhandle_volume_creation_errorparse_error_response)PoolResourceStatusSandboxTemplateVolumeVolumeMountSpec)Sandbox)RetryTransportc                 X    t        j                  dd      } | j                  d       dS )zGet the default sandbox API endpoint from environment.

    Derives the endpoint from LANGSMITH_ENDPOINT (or LANGCHAIN_ENDPOINT).
    ENDPOINTzhttps://api.smith.langchain.com)default/z/v2/sandboxes)ls_utilsget_env_varrstrip)bases    W/opt/lhia/marcimex/agent/venv/lib/python3.12/site-packages/langsmith/sandbox/_client.py_get_default_api_endpointr#   %   s.    
 
4UVDkk#}--    c                 ,    t        j                  d      S )z)Get the default API key from environment.API_KEY)r   r    r$   r"   _get_default_api_keyr(   .   s    	**r$   c                     e Zd ZdZddddd	 	 	 	 	 	 	 d0dZd1dZd1dZd2d	Z	 	 	 	 	 	 	 	 d3d
Zdd	 	 	 	 	 	 	 d4dZ	d5dZ
d6dZd7dZddd	 	 	 	 	 	 	 d8dZddddd	 	 	 	 	 	 	 	 	 	 	 	 	 d9dZd:dZd;dZd<dZd7dZdd	 	 	 	 	 	 	 	 	 d=dZd>dZd?dZddd	 	 	 	 	 	 	 d@d Zd7d!Zddd"	 	 	 	 	 	 	 dAd#Zddd$d%	 	 	 	 	 	 	 	 	 dBd&ZdCd'ZdDd(ZdEd)Zd7d*ZdFd+Zd,d-d.	 	 	 	 	 	 	 dGd/Zy)HSandboxClienta  Client for interacting with the Sandbox Server API.

    This client provides a simple interface for managing sandboxes and templates.

    Example:
        # Uses LANGSMITH_ENDPOINT and LANGSMITH_API_KEY from environment
        client = SandboxClient()

        # Or with explicit configuration
        client = SandboxClient(
            api_endpoint="https://api.smith.langchain.com/v2/sandboxes",
            api_key="your-api-key",
        )

        # Create a sandbox and run commands
        with client.sandbox(template_name="python-sandbox") as sandbox:
            result = sandbox.run("python --version")
            print(result.stdout)
    Ng      $@   )api_endpointtimeoutapi_keymax_retriesc                   |xs
 t               j                  d      | _        |xs
 t               }|| _        i }|r||d<   t        |      }t        j                  |||      | _        y)ap  Initialize the SandboxClient.

        Args:
            api_endpoint: Full URL of the sandbox API endpoint. If not provided,
                          derived from LANGSMITH_ENDPOINT environment variable.
            timeout: Default HTTP timeout in seconds.
            api_key: API key for authentication. If not provided, uses
                     LANGSMITH_API_KEY environment variable.
            max_retries: Maximum number of retries for transient errors (502, 503,
                         504), rate limits (429), and connection failures. Set to 0
                         to disable retries. Default: 3.
        r   z	X-Api-Key)r/   )	transportr-   headersN)	r#   r    	_base_urlr(   _api_keyr   httpxClient_http)selfr,   r-   r.   r/   resolved_api_keyr2   r1   s           r"   __init__zSandboxClient.__init__H   sf    ( 'E*C*EMMcR"<&:&<("$#3GK "{;	\\IwPWX
r$   c                8    | j                   j                          y)zClose the HTTP client.N)r7   closer8   s    r"   r<   zSandboxClient.closee   s    

r$   c                    	 | j                   j                  s| j                   j                          yy# t        $ r Y yw xY w)z,Close the HTTP client on garbage collection.N)r7   	is_closedr<   	Exceptionr=   s    r"   __del__zSandboxClient.__del__i   s;    	::''

  " ( 		s   04 	A A c                    | S )zEnter context manager.r'   r=   s    r"   	__enter__zSandboxClient.__enter__q   s    r$   c                $    | j                          y)zExit context manager.N)r<   )r8   exc_typeexc_valexc_tbs       r"   __exit__zSandboxClient.__exit__u   s     	

r$   <   )r-   c               &   | j                    d}||d|d}	 | j                  j                  |||dz         }|j                          t	        j
                  |j                               S # t        j                  $ r}t        |        d}~ww xY w)a6  Create a new persistent volume.

        Creates a persistent storage volume that can be referenced in templates.

        Args:
            name: Volume name.
            size: Storage size (e.g., "1Gi", "10Gi").
            timeout: Timeout in seconds when waiting for ready (min: 5, max: 300).

        Returns:
            Created Volume.

        Raises:
            VolumeProvisioningError: If volume provisioning fails.
            ResourceTimeoutError: If volume doesn't become ready within timeout.
            SandboxClientError: For other errors.
        /volumesT)namesizewait_for_readyr-      jsonr-   N)
r3   r7   postraise_for_statusr   	from_dictrQ   r5   HTTPStatusErrorr   )r8   rL   rM   r-   urlpayloadresponsees           r"   create_volumezSandboxClient.create_volume   s    0  ) "	
	zzs'B,OH%%'##HMMO44$$ 	(+	s   AA, ,B?BBc                f   | j                    d| }	 | j                  j                  |      }|j                          t	        j
                  |j                               S # t        j                  $ r<}|j                  j                  dk(  rt        d| dd      |t        |        d}~ww xY w)zGet a volume by name.

        Args:
            name: Volume name.

        Returns:
            Volume.

        Raises:
            ResourceNotFoundError: If volume not found.
            SandboxClientError: For other errors.
        	/volumes/  Volume '' not foundvolumeresource_typeN)r3   r7   getrS   r   rT   rQ   r5   rU   rX   status_coder
   r   r8   rL   rV   rX   rY   s        r"   
get_volumezSandboxClient.get_volume   s      	$0
	zz~~c*H%%'##HMMO44$$ 	zz%%,+tfK0 %Q'	   AA! !B047B++B0c                   | j                    d}	 | j                  j                  |      }|j                          |j	                         }|j                  dg       D cg c]  }t        j                  |       c}S c c}w # t        j                  $ r:}|j                  j                  dk(  rt        d| d      |t        |        d}~ww xY w)zIList all volumes.

        Returns:
            List of Volumes.
        rK   volumesr]   API endpoint not found: %. Check that api_endpoint is correct.N)r3   r7   rc   rS   rQ   r   rT   r5   rU   rX   rd   r   r   )r8   rV   rX   datavrY   s         r"   list_volumeszSandboxClient.list_volumes   s      )	zz~~c*H%%'==?D15)R1HIAF$$Q'III$$ 	zz%%,%.se 4: ;  %Q'	*   AB  A?<B ?B C5CCc                   | j                    d| }	 | j                  j                  |      }|j                          y	# t        j
                  $ ru}|j                  j                  dk(  rt        d| dd      ||j                  j                  dk(  rt        |      }t        |d   d      |t        |       Y d	}~y	d	}~ww xY w)
a  Delete a volume.

        Args:
            name: Volume name.

        Raises:
            ResourceNotFoundError: If volume not found.
            ResourceInUseError: If volume is referenced by templates.
            SandboxClientError: For other errors.
        r\   r]   r^   r_   r`   ra     messageNr3   r7   deleterS   r5   rU   rX   rd   r
   r   r   r   r8   rL   rV   rX   rY   rl   s         r"   delete_volumezSandboxClient.delete_volume   s      	$0	(zz((-H%%'$$ 	(zz%%,+tfK0 zz%%,+A.(iQWXX$Q''	(   +? CA+CC)new_namerM   c                  | j                    d| }i }|||d<   |||d<   |s| j                  |      S 	 | j                  j                  ||      }|j	                          t        j                  |j                               S # t        j                  $ r}|j                  j                  dk(  rt        d| dd	
      ||j                  j                  dk(  rt        |      }t        |d   d      ||j                  j                  dk(  rt        |      }t        |d   d	
      |t!        |        d}~ww xY w)a  Update a volume's name and/or size.

        You can update the display name, size, or both in a single request.
        Only storage size increases are allowed (storage backend limitation).

        Args:
            name: Current volume name.
            new_name: New display name (optional).
            size: New storage size (must be >= current size). Optional.

        Returns:
            Updated Volume.

        Raises:
            ResourceNotFoundError: If volume not found.
            VolumeResizeError: If storage decrease attempted.
            ResourceNameConflictError: If new_name is already in use.
            SandboxQuotaExceededError: If storage quota would be exceeded.
            SandboxClientError: For other errors.
        r\   NrL   rM   rQ   r]   r^   r_   r`   ra   i  rr   VolumeResize)
error_typerq   )r3   rf   r7   patchrS   r   rT   rQ   r5   rU   rX   rd   r
   r   r   r	   r   )	r8   rL   rx   rM   rV   rW   rX   rY   rl   s	            r"   update_volumezSandboxClient.update_volume   sI   6  	$0"$&GFO"GFO??4((	zz'''':H%%'##HMMO44$$ 	zz%%,+tfK0 zz%%,+A.%d9o.QWXXzz%%,+A./O8 %Q'	s   AB D?B!D::D?500m512Mi)cpumemorystoragevolume_mountsc                  | j                    d}||||dd}|r||d   d<   |r*|D 	cg c]  }	|	j                  |	j                  d c}	|d<   	 | j                  j	                  ||      }
|
j                          t        j                  |
j                               S c c}	w # t        j                  $ r}t        |        d	}~ww xY w)
a  Create a new SandboxTemplate.

        Only the container image, resource limits, and volume mounts can be
        configured. All other container details are handled by the server.

        Args:
            name: Template name.
            image: Container image (e.g., "python:3.12-slim").
            cpu: CPU limit (e.g., "500m", "1", "2"). Default: "500m".
            memory: Memory limit (e.g., "256Mi", "1Gi"). Default: "512Mi".
            storage: Ephemeral storage limit (e.g., "1Gi"). Optional.
            volume_mounts: List of volumes to mount in the sandbox. Optional.

        Returns:
            Created SandboxTemplate.

        Raises:
            SandboxClientError: If creation fails.
        
/templates)r   r   )rL   image	resourcesr   r   )volume_name
mount_pathr   rz   N)r3   r   r   r7   rR   rS   r   rT   rQ   r5   rU   r   )r8   rL   r   r   r   r   r   rV   rW   vmrX   rY   s               r"   create_templatezSandboxClient.create_template4  s    :  
+  #
 .5GK + (( !#bmmL(GO$
	zzs9H%%'",,X]]_==( $$ 	$Q'	s    B AB% %C	8CC	c                f   | j                    d| }	 | j                  j                  |      }|j                          t	        j
                  |j                               S # t        j                  $ r<}|j                  j                  dk(  rt        d| dd      |t        |        d}~ww xY w)a  Get a SandboxTemplate by name.

        Args:
            name: Template name.

        Returns:
            SandboxTemplate.

        Raises:
            ResourceNotFoundError: If template not found.
            SandboxClientError: For other errors.
        /templates/r]   
Template 'r_   templatera   N)r3   r7   rc   rS   r   rT   rQ   r5   rU   rX   rd   r
   r   re   s        r"   get_templatezSandboxClient.get_templatek  s      D62
	zz~~c*H%%'",,X]]_==$$ 	zz%%,+ k2* %Q'	rg   c                   | j                    d}	 | j                  j                  |      }|j                          |j	                         }|j                  dg       D cg c]  }t        j                  |       c}S c c}w # t        j                  $ r:}|j                  j                  dk(  rt        d| d      |t        |        d}~ww xY w)z[List all SandboxTemplates.

        Returns:
            List of SandboxTemplates.
        r   	templatesr]   rj   rk   N)r3   r7   rc   rS   rQ   r   rT   r5   rU   rX   rd   r   r   )r8   rV   rX   rl   trY   s         r"   list_templateszSandboxClient.list_templates  s      
+	zz~~c*H%%'==?D:>((;PR:STQO--a0TTT$$ 	zz%%,%.se 4: ;  %Q'	ro   c                  | j                    d| }d|i}	 | j                  j                  ||      }|j                          t	        j
                  |j                               S # t        j                  $ rq}|j                  j                  dk(  rt        d| dd      ||j                  j                  d	k(  rt        |      }t        |d
   d      |t        |        d}~ww xY w)a  Update a template's display name.

        Args:
            name: Current template name.
            new_name: New display name.

        Returns:
            Updated SandboxTemplate.

        Raises:
            ResourceNotFoundError: If template not found.
            ResourceNameConflictError: If new_name is already in use.
            SandboxClientError: For other errors.
        r   rL   rz   r]   r   r_   r   ra   rq   rr   N)r3   r7   r}   rS   r   rT   rQ   r5   rU   rX   rd   r
   r   r	   r   )r8   rL   rx   rV   rW   rX   rY   rl   s           r"   update_templatezSandboxClient.update_template  s      D628$	zz'''':H%%'",,X]]_==$$ 	zz%%,+ k2* zz%%,+A./O: %Q'	s   AA' 'C+:A,C&&C+c                   | j                    d| }	 | j                  j                  |      }|j                          y	# t        j
                  $ ru}|j                  j                  dk(  rt        d| dd      ||j                  j                  dk(  rt        |      }t        |d   d      |t        |       Y d	}~y	d	}~ww xY w)
a   Delete a SandboxTemplate.

        Args:
            name: Template name.

        Raises:
            ResourceNotFoundError: If template not found.
            ResourceInUseError: If template is referenced by sandboxes or pools.
            SandboxClientError: For other errors.
        r   r]   r   r_   r   ra   rq   rr   Nrs   ru   s         r"   delete_templatezSandboxClient.delete_template  s      D62	(zz((-H%%'$$ 
	(zz%%,+ k2* zz%%,+A.(O: %Q''
	(rw   rO   c               ,   | j                    d}|||d|d}	 |dz   }| j                  j                  |||      }|j                          t	        j
                  |j                               S # t        j                  $ r}	t        |	        d}	~	ww xY w)a  Create a new Sandbox Pool.

        Pools pre-provision sandboxes from a template for faster startup.

        Args:
            name: Pool name (lowercase letters, numbers, hyphens; max 63 chars).
            template_name: Name of the SandboxTemplate to use (no volume mounts).
            replicas: Number of sandboxes to pre-provision (1-100).
            timeout: Timeout in seconds when waiting for ready (10-600).

        Returns:
            Created Pool.

        Raises:
            ResourceNotFoundError: If template not found.
            ValidationError: If template has volumes attached.
            ResourceAlreadyExistsError: If pool with this name already exists.
            ResourceTimeoutError: If pool doesn't reach ready state within timeout.
            SandboxQuotaExceededError: If organization quota is exceeded.
            SandboxClientError: For other errors.
        /poolsT)rL   template_namereplicasrN   r-   rO   rP   N)
r3   r7   rR   rS   r   rT   rQ   r5   rU   r   )
r8   rL   r   r   r-   rV   rW   http_timeoutrX   rY   s
             r"   create_poolzSandboxClient.create_pool  s    :  ' * "#
	"R<Lzzs,OH%%'>>(--/22$$ 	a 	s   AA/ /BBBc                f   | j                    d| }	 | j                  j                  |      }|j                          t	        j
                  |j                               S # t        j                  $ r<}|j                  j                  dk(  rt        d| dd      |t        |        d}~ww xY w)zGet a Pool by name.

        Args:
            name: Pool name.

        Returns:
            Pool.

        Raises:
            ResourceNotFoundError: If pool not found.
            SandboxClientError: For other errors.
        /pools/r]   Pool 'r_   poolra   N)r3   r7   rc   rS   r   rT   rQ   r5   rU   rX   rd   r
   r   re   s        r"   get_poolzSandboxClient.get_pool  s      v.
	zz~~c*H%%'>>(--/22$$ 	zz%%,+TF+.f %Q'	rg   c                   | j                    d}	 | j                  j                  |      }|j                          |j	                         }|j                  dg       D cg c]  }t        j                  |       c}S c c}w # t        j                  $ r:}|j                  j                  dk(  rt        d| d      |t        |        d}~ww xY w)zEList all Pools.

        Returns:
            List of Pools.
        r   poolsr]   rj   rk   N)r3   r7   rc   rS   rQ   r   rT   r5   rU   rX   rd   r   r   )r8   rV   rX   rl   prY   s         r"   
list_poolszSandboxClient.list_pools*  s      '	zz~~c*H%%'==?D/3xx/DE!DNN1%EEE$$ 	zz%%,%.se 4: ;  %Q'	ro   )rx   r   c                  | j                    d| }i }|||d<   |||d<   |s| j                  |      S 	 | j                  j                  ||      }|j	                          t        j                  |j                               S # t        j                  $ rq}|j                  j                  dk(  rt        d| dd	
      ||j                  j                  dk(  rt        |      }t        |d   d	
      |t        |        d}~ww xY w)a  Update a Pool's name and/or replica count.

        You can update the display name, replica count, or both.
        The template reference cannot be changed after creation.

        Args:
            name: Current pool name.
            new_name: New display name (optional).
            replicas: New number of replicas (0-100). Set to 0 to pause.

        Returns:
            Updated Pool.

        Raises:
            ResourceNotFoundError: If pool not found.
            ValidationError: If template was deleted.
            ResourceNameConflictError: If new_name is already in use.
            SandboxQuotaExceededError: If quota exceeded when scaling up.
            SandboxClientError: For other errors.
        r   NrL   r   rz   r]   r   r_   r   ra   rq   rr   )r3   r   r7   r}   rS   r   rT   rQ   r5   rU   rX   rd   r
   r   r	   r   )	r8   rL   rx   r   rV   rW   rX   rY   rl   s	            r"   update_poolzSandboxClient.update_pool@  s   6  v."$&GFO"*GJ==&&	zz'''':H%%'>>(--/22$$ 	zz%%,+TF+.f zz%%,+A./O6 a 	s   AB D
A,DD
c                *   | j                    d| }	 | j                  j                  |      }|j                          y# t        j
                  $ r@}|j                  j                  dk(  rt        d| dd      |t        |       Y d}~yd}~ww xY w)zDelete a Pool.

        This will terminate all sandboxes in the pool.

        Args:
            name: Pool name.

        Raises:
            ResourceNotFoundError: If pool not found.
            SandboxClientError: For other errors.
        r   r]   r   r_   r   ra   N
r3   r7   rt   rS   r5   rU   rX   rd   r
   r   re   s        r"   delete_poolzSandboxClient.delete_poolx  s      v.	(zz((-H%%'$$ 	(zz%%,+TF+.f %Q''	(   +? B6BB)rL   r-   c               <    | j                  |||      }d|_        |S )a  Create a sandbox and return a Sandbox instance.

        This is the primary method for creating sandboxes. Use it as a
        context manager for automatic cleanup:

            with client.sandbox(template_name="my-template") as sandbox:
                result = sandbox.run("echo hello")

        The sandbox is automatically deleted when exiting the context manager.
        For sandboxes with manual lifecycle management, use create_sandbox().

        Args:
            template_name: Name of the SandboxTemplate to use.
            name: Optional sandbox name (auto-generated if not provided).
            timeout: Timeout in seconds when waiting for ready.

        Returns:
            Sandbox instance.

        Raises:
            ResourceTimeoutError: If timeout waiting for sandbox to be ready.
            ResourceCreationError: If sandbox creation fails.
            SandboxClientError: For other errors.
        )r   rL   r-   T)create_sandbox_auto_delete)r8   r   rL   r-   sbs        r"   sandboxzSandboxClient.sandbox  s0    >   ' ! 

 	r$   T)rL   r-   rN   c               P   | j                    d}||d}|r||d<   |r||d<   |r|dz   nd}	 | j                  j                  |||      }|j                          t	        j
                  |j                         | d      S # t        j                  $ r}	t        |	        d	}	~	ww xY w)
a3  Create a new Sandbox.

        The sandbox is NOT automatically deleted. Use delete_sandbox() for cleanup,
        or use sandbox() for automatic cleanup with a context manager.

        Args:
            template_name: Name of the SandboxTemplate to use.
            name: Optional sandbox name (auto-generated if not provided).
            timeout: Timeout in seconds when waiting for ready (only used when
                wait_for_ready=True).
            wait_for_ready: If True (default), block until sandbox is ready.
                If False, return immediately with status "provisioning". Use
                get_sandbox_status() or wait_for_sandbox() to poll for readiness.

        Returns:
            Created Sandbox. When wait_for_ready=False, the sandbox will have
            status="provisioning" and cannot be used for operations until ready.

        Raises:
            ResourceTimeoutError: If timeout waiting for sandbox to be ready.
            ResourceCreationError: If sandbox creation fails.
            SandboxClientError: For other errors.
        /boxes)r   rN   r-   rL   rO   rP   Fclientauto_deleteN)
r3   r7   rR   rS   r   rT   rQ   r5   rU   r   )
r8   r   rL   r-   rN   rV   rW   r   rX   rY   s
             r"   r   zSandboxClient.create_sandbox  s    >  ' +,#
 !(GI"GFO)7"R	zzs,OH%%'$$X]]_TuUU$$ 	)!,	s   AB B%B  B%c                l   | j                    d| }	 | j                  j                  |      }|j                          t	        j
                  |j                         | d      S # t        j                  $ r<}|j                  j                  dk(  rt        d| dd      |t        |        d	}~ww xY w)
aF  Get a Sandbox by name.

        The sandbox is NOT automatically deleted. Use delete_sandbox() for cleanup.

        Args:
            name: Sandbox name.

        Returns:
            Sandbox.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            SandboxClientError: For other errors.
        /boxes/Fr   r]   	Sandbox 'r_   r   ra   N)r3   r7   rc   rS   r   rT   rQ   r5   rU   rX   rd   r
   r   re   s        r"   get_sandboxzSandboxClient.get_sandbox  s      v.
	zz~~c*H%%'$$X]]_TuUU$$ 	zz%%,+v[1 %Q'	s   AA$ $B377B..B3c                   | j                    d}	 | j                  j                  |      }|j                          |j	                         }|j                  dg       D cg c]  }t        j                  || d       c}S c c}w # t        j                  $ r:}|j                  j                  dk(  rt        d| d      |t        |        d}~ww xY w)	zMList all Sandboxes.

        Returns:
            List of Sandboxes.
        r   	sandboxesFr   r]   rj   rk   N)r3   r7   rc   rS   rQ   r   rT   r5   rU   rX   rd   r   r   )r8   rV   rX   rl   crY   s         r"   list_sandboxeszSandboxClient.list_sandboxes  s      '	zz~~c*H%%'==?D +r2 !!!DeD   $$ 	zz%%,%.se 4: ;  %Q'	s*   AB  B?B B C5CCc                  | j                    d| }d|i}	 | j                  j                  ||      }|j                          t	        j
                  |j                         | d      S # t        j                  $ rg}|j                  j                  dk(  rt        d| dd	
      ||j                  j                  dk(  rt        d| dd	
      |t        |        d}~ww xY w)ay  Update a sandbox's display name.

        Args:
            name: Current sandbox name.
            new_name: New display name.

        Returns:
            Updated Sandbox.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            ResourceNameConflictError: If new_name is already in use.
            SandboxClientError: For other errors.
        r   rL   rz   Fr   r]   r   r_   r   ra   rq   zSandbox name 'z' already in useN)r3   r7   r}   rS   r   rT   rQ   r5   rU   rX   rd   r
   r	   r   )r8   rL   rx   rV   rW   rX   rY   s          r"   update_sandboxzSandboxClient.update_sandbox%  s      v.8$	zz'''':H%%'$$X]]_TuUU$$ 	zz%%,+v[1 zz%%,/$XJ.>?"+  %Q'	s   AA* *C$=A"CC$c                *   | j                    d| }	 | j                  j                  |      }|j                          y# t        j
                  $ r@}|j                  j                  dk(  rt        d| dd      |t        |       Y d}~yd}~ww xY w)zDelete a Sandbox.

        Args:
            name: Sandbox name.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            SandboxClientError: For other errors.
        r   r]   r   r_   r   ra   Nr   re   s        r"   delete_sandboxzSandboxClient.delete_sandboxH  s      v.	(zz((-H%%'$$ 	(zz%%,+v[1 %Q''	(r   c                h   | j                    d| d}	 | j                  j                  |      }|j                          t	        j
                  |j                               S # t        j                  $ r<}|j                  j                  dk(  rt        d| dd      |t        |        d}~ww xY w)	a  Get the provisioning status of a sandbox.

        This is a lightweight endpoint designed for high-frequency polling
        during sandbox provisioning. It returns only the status fields
        without full sandbox data.

        Args:
            name: Sandbox name.

        Returns:
            ResourceStatus with status and status_message.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            SandboxClientError: For other errors.
        r   z/statusr]   r   r_   r   ra   N)r3   r7   rc   rS   r   rT   rQ   r5   rU   rX   rd   r
   r   re   s        r"   get_sandbox_statusz SandboxClient.get_sandbox_status^  s    "  vW5
	zz~~c*H%%'!++HMMO<<$$ 	zz%%,+v[1 %Q'	s   AA" "B157B,,B1x   g      ?)r-   poll_intervalc                  ddl }|j                         |z   }	 | j                  |      }|j                  dk(  r| j	                  |      S |j                  dk(  rt        |j                  xs dd      ||j                         z
  }|dk  rt        d| d	| d
d|j                        |j                  t        ||             )a  Poll until a sandbox reaches "ready" or "failed" status.

        Uses the lightweight status endpoint for polling, then fetches the
        full sandbox data once ready.

        Args:
            name: Sandbox name.
            timeout: Maximum time to wait in seconds.
            poll_interval: Time between status checks in seconds.

        Returns:
            Sandbox in "ready" status.

        Raises:
            ResourceCreationError: If sandbox status becomes "failed".
            ResourceTimeoutError: If timeout expires while still "provisioning".
            ResourceNotFoundError: If sandbox not found.
            SandboxClientError: For other errors.
        r   NreadyfailedzSandbox provisioning failedr   ra   r   z' not ready after s)rb   last_status)
time	monotonicr   statusr   r   status_messager   sleepmin)r8   rL   r-   r   r   deadliner   	remainings           r"   wait_for_sandboxzSandboxClient.wait_for_sandbox}  s    4 	>>#g-,,T2F}}'''--}}(+))J-J"+  !4>>#33IA~*v%7yB"+ & 
 JJs=)45! r$   )r,   Optional[str]r-   floatr.   r   r/   int)returnNone)r   r*   )rE   zOptional[type]rF   zOptional[BaseException]rG   zOptional[Any]r   r   )rL   strrM   r   r-   r   r   r   )rL   r   r   r   )r   zlist[Volume])rL   r   r   r   )rL   r   rx   r   rM   r   r   r   )rL   r   r   r   r   r   r   r   r   r   r   zOptional[list[VolumeMountSpec]]r   r   )rL   r   r   r   )r   zlist[SandboxTemplate])rL   r   rx   r   r   r   )
rL   r   r   r   r   r   r-   r   r   r   )rL   r   r   r   )r   z
list[Pool])rL   r   rx   r   r   zOptional[int]r   r   )r   r   rL   r   r-   r   r   r   )
r   r   rL   r   r-   r   rN   boolr   r   )rL   r   r   r   )r   zlist[Sandbox])rL   r   rx   r   r   r   )rL   r   r   r   )rL   r   r-   r   r   r   r   r   ) __name__
__module____qualname____doc__r:   r<   rA   rC   rH   rZ   rf   rn   rv   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r'   r$   r"   r*   r*   3   s   . '+!%Y $Y 	Y
 Y Y:  ) 	
 
$ '' '
 ' 
'R6,(< #'"88  	8
 8 
8F !%9=55 5
 5 5 5 75 
5n6,!F(L .. . 	. . 
.`64 #'"&66  	6
  6 
6p(@ #%% 	%
 % 
%V ##22 	2
 2 2 
2h:2!F(,F "-6-6 	-6
 -6 
-6r$   r*   )r   r   )r   r   )%r   
__future__r   typingr   r   r5   	langsmithr   r   langsmith.sandbox._exceptionsr   r   r	   r
   r   r   r   langsmith.sandbox._helpersr   r   r   r   r   langsmith.sandbox._modelsr   r   r   r   r   langsmith.sandbox._sandboxr   langsmith.sandbox._transportr   r#   r(   r*   r'   r$   r"   <module>r      sU    K "    '     / 7.+
w6 w6r$   