
    jX                        d Z ddlm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 ddlmZmZmZmZmZ dd	lmZmZmZ dd
lmZ ddlmZ ddZ ddZ!eee"e"f                  Z# G d d          Z$dS )zEMain SandboxClient class for interacting with the sandbox server API.    )annotations)Mapping)AnyOptionalN)utils)ResourceCreationErrorResourceNameConflictErrorResourceNotFoundErrorResourceTimeoutErrorSandboxAPIError)handle_client_http_errorhandle_sandbox_creation_errormerge_headersvalidate_service_paramsvalidate_ttl)ResourceStatus
ServiceURLSnapshot)Sandbox)RetryTransportreturnstrc                 ^    t          j        dd          } |                     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    c/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/langsmith/sandbox/_client.py_get_default_api_endpointr"   "   s5    
 
4UVVVDkk#----    Optional[str]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ddcdZdddZdedZdedZdfdZdgdZ	dhd Z
	 diddd!dddddddd"
djd/Z	 diddd!d0dddddddd1dkd4Zdd5dld6Zdd5dmd8Zddddd9dnd;Zdd5dod<Zdd5dpd>Zd?dd@dqdDZdEdFddGdrdIZdEddJdsdKZdd5dodLZdddddMddNdtdUZdMddJdudWZdd5dvdXZdddddYdwd^Zdd5dxd_Zd`daddGdydbZdS )zSandboxClienta  Client for interacting with the Sandbox Server API.

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

    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 from a snapshot and run commands
        with client.sandbox(snapshot_id="<snapshot-uuid>") as sandbox:
            result = sandbox.run("python --version")
            print(result.stdout)
    Ng      $@   )api_endpointtimeoutapi_keymax_retriesheadersr,   r$   r-   floatr.   r/   intr0   Optional[RequestHeaders]c                  |pt                                          d          | _        |pt                      }|| _        i }|r||d<   |rt          ||          }t          |          }t          j        |||          | _	        dS )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-   r0   N)
r"   r   	_base_urlr(   _api_keyr   r   httpxClient_http)	selfr,   r-   r.   r/   r0   resolved_api_keyclient_headersr5   s	            r!   __init__zSandboxClient.__init__H   s    * 'E*C*E*EMMcRR"<&:&<&<()+ 	;*:N;' 	D*>7CCN"{;;;	\.
 
 



r#   RequestHeadersr   Optional[dict[str, str]]c                >    |dS t          | j        j        |          S )z8Merge default client headers with per-request overrides.N)r   r:   r0   )r;   r0   s     r!   _request_headerszSandboxClient._request_headersj   s!    ?4TZ/999r#   Nonec                8    | j                                          dS )zClose the HTTP client.N)r:   closer;   s    r!   rE   zSandboxClient.closep   s    
r#   c                x    	 | j         j        s| j                                          dS dS # t          $ r Y dS w xY w)z,Close the HTTP client on garbage collection.N)r:   	is_closedrE   	ExceptionrF   s    r!   __del__zSandboxClient.__del__t   sZ    	:' #
  """""# # 	 	 	DD	s   %+ 
99c                    | S )zEnter context manager.r'   rF   s    r!   	__enter__zSandboxClient.__enter__|   s    r#   exc_typeOptional[type]exc_valOptional[BaseException]exc_tbOptional[Any]c                .    |                                   dS )zExit context manager.N)rE   )r;   rM   rO   rQ   s       r!   __exit__zSandboxClient.__exit__   s     	

r#   r   c                    d| j          dS )zReturn a string representation of the instance.

        Returns:
            The string representation of the instance.
        zSandboxClient (API URL: ))r6   rF   s    r!   __repr__zSandboxClient.__repr__   s     <$.;;;;r#      
snapshot_namenamer-   ttl_secondsidle_ttl_secondsvcpus	mem_bytesfs_capacity_bytesproxy_configr0   snapshot_idrZ   r[   r\   Optional[int]r]   r^   r_   r`   ra   Optional[dict[str, Any]]r   c       
        T    |                      |||||||||	|
|          }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(snapshot_id="<uuid>") as sandbox:
                result = sandbox.run("echo hello")

            # Resolve by snapshot name instead of ID:
            with client.sandbox(snapshot_name="my-snap") 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:
            snapshot_id: Snapshot ID to boot from. Mutually exclusive with
                ``snapshot_name``; exactly one must be provided.
            snapshot_name: Snapshot name to boot from. Resolved server-side to a
                snapshot owned by the caller's tenant. Mutually exclusive with
                ``snapshot_id``; exactly one must be provided.
            name: Optional sandbox name (auto-generated if not provided).
            timeout: Timeout in seconds when waiting for ready.
            ttl_seconds: Maximum lifetime in seconds from creation. The sandbox
                will be automatically deleted after this duration. Must be a
                multiple of 60. 0 or None disables this TTL.
            idle_ttl_seconds: Idle timeout in seconds. The sandbox will be
                automatically deleted after this duration of inactivity. Must
                be a multiple of 60. ``0`` explicitly disables the idle
                timeout. When omitted (``None``), the server applies a default
                of ``600`` seconds (10 minutes).
            vcpus: Number of vCPUs.
            mem_bytes: Memory in bytes.
            fs_capacity_bytes: Root filesystem capacity in bytes.
            proxy_config: Per-sandbox proxy configuration forwarded to the
                server as-is. Shape matches the backend `proxy_config` field:
                ``{"rules": [...], "no_proxy": [...], "access_control":
                {"allow_list": [...]}}`` or ``{"access_control":
                {"deny_list": [...]}}``. Use ``access_control.allow_list`` to
                restrict outbound HTTPS to a set of host patterns (exact
                domains, globs like ``*.example.com``, IPs, CIDRs, or
                ``~regex``).

        Returns:
            Sandbox instance.

        Raises:
            ResourceTimeoutError: If timeout waiting for sandbox to be ready.
            ResourceCreationError: If sandbox creation fails.
            SandboxClientError: For other errors.
            ValueError: If TTL values are invalid, or if neither/both of
                ``snapshot_id`` and ``snapshot_name`` are provided.
        rY   T)create_sandbox_auto_delete)r;   rb   rZ   r[   r-   r\   r]   r^   r_   r`   ra   r0   sbs                r!   sandboxzSandboxClient.sandbox   sN    H   '#-/% ! 
 
 	r#   T)rZ   r[   r-   wait_for_readyr\   r]   r^   r_   r`   ra   r0   rj   boolc                  t          |          t          |          k    rt          d          t          |d           t          |d           | j         d}d|i}|r||d<   |r||d<   |r||d<   |r||d	<   |||d<   |||d<   |||d<   |	|	|d<   |
|
|d<   |||d<   |r|dz   nd}	 | j                            ||||                     |                    }|                                 t          j	        |
                                | d          S # t          j        $ r}t          |            d
}~ww xY w)a
  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:
            snapshot_id: Snapshot ID to boot from. Mutually exclusive with
                ``snapshot_name``; exactly one must be provided.
            snapshot_name: Snapshot name to boot from. Resolved server-side to a
                snapshot owned by the caller's tenant. Mutually exclusive with
                ``snapshot_id``; exactly one must be provided.
            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.
            ttl_seconds: Maximum lifetime in seconds from creation. The sandbox
                will be automatically deleted after this duration. Must be a
                multiple of 60. 0 or None disables this TTL.
            idle_ttl_seconds: Idle timeout in seconds. The sandbox will be
                automatically deleted after this duration of inactivity. Must
                be a multiple of 60. ``0`` explicitly disables the idle
                timeout. When omitted (``None``), the server applies a default
                of ``600`` seconds (10 minutes).
            vcpus: Number of vCPUs.
            mem_bytes: Memory in bytes.
            fs_capacity_bytes: Root filesystem capacity in bytes.
            proxy_config: Per-sandbox proxy configuration forwarded to the
                server as-is. Shape matches the backend `proxy_config` field:
                ``{"rules": [...], "no_proxy": [...], "access_control":
                {"allow_list": [...]}}`` or ``{"access_control":
                {"deny_list": [...]}}``. Use ``access_control.allow_list`` to
                restrict outbound HTTPS to a set of host patterns (exact
                domains, globs like ``*.example.com``, IPs, CIDRs, or
                ``~regex``).

        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.
            ValueError: If TTL values are invalid, or if neither/both of
                ``snapshot_id`` and ``snapshot_name`` are provided.
        z7Exactly one of snapshot_id or snapshot_name must be setr\   r]   /boxesrj   rb   rZ   r-   r[   Nr^   r_   r`   ra   rX   )jsonr-   r0   Fclientauto_delete)rk   
ValueErrorr   r6   r:   postrB   raise_for_statusr   	from_dictrn   r8   HTTPStatusErrorr   )r;   rb   rZ   r[   r-   rj   r\   r]   r^   r_   r`   ra   r0   urlpayloadhttp_timeoutresponsees                     r!   rf   zSandboxClient.create_sandbox   s   @ ] 3 333VWWW[-000%'9:::''' n#
  	1%0GM" 	5'4GO$ 	)!(GI 	#"GFO"%0GM"'*:G&'$GG #,GK (+<G'(#&2GN#)7?"R	z$--g66	 '  H %%'''$X]]__TuUUUU$ 	 	 	)!,,,	s   .A-D E +D;;E r0   c                  | j          d| }	 | j                            ||                     |                    }|                                 t          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/r|   Fro     	Sandbox '' not foundri   resource_typeN)r6   r:   getrB   rt   r   ru   rn   r8   rv   rz   status_coder
   r   r;   r[   r0   rw   rz   r{   s         r!   get_sandboxzSandboxClient.get_sandboxX  s     ....
	z~~c43H3H3Q3Q~RRH%%'''$X]]__TuUUUU$ 	 	 	z%,,+1111   %Q'''	s   A+A: :C	6B??Clist[Sandbox]c                    j          d}	  j                            |                     |                    }|                                 |                                } fd|                    dg           D             S # t          j        $ r9}|j        j	        dk    rt          d| d          |t          |            d}~ww xY w)	zMList all Sandboxes.

        Returns:
            List of Sandboxes.
        rm   r|   c                >    g | ]}t          j        |d           S )Fro   )r   ru   ).0cr;   s     r!   
<listcomp>z0SandboxClient.list_sandboxes.<locals>.<listcomp>  s;        !!DeDDD  r#   	sandboxesr   API endpoint not found: %. Check that api_endpoint is correct.Nr6   r:   r   rB   rt   rn   r8   rv   rz   r   r   r   )r;   r0   rw   rz   datar{   s   `     r!   list_sandboxeszSandboxClient.list_sandboxesu  s    '''	z~~c43H3H3Q3Q~RRH%%'''==??D   +r22    $ 	 	 	z%,,%;s ; ; ;   %Q'''	s   A8B C4C		C)new_namer\   r]   r0   r   c               J   t          |d           t          |d           | j         d| }i }|||d<   |||d<   |||d<   	 | j                            |||                     |                    }|                                 t          j        |                                | d          S # t          j
        $ ra}	|	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)a  Update a sandbox's properties.

        Args:
            name: Current sandbox name.
            new_name: New display name.
            ttl_seconds: Maximum lifetime in seconds from creation. Must be a
                multiple of 60. 0 disables this TTL.
            idle_ttl_seconds: Idle timeout in seconds. Must be a multiple of
                60. ``0`` disables this TTL. ``None`` leaves the existing
                value unchanged.

        Returns:
            Updated Sandbox.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            ResourceNameConflictError: If new_name is already in use.
            SandboxClientError: For other errors.
            ValueError: If TTL values are invalid.
        r\   r]   r~   Nr[   rn   r0   Fro   r   r   r   ri   r   i  zSandbox name 'z' already in use)r   r6   r:   patchrB   rt   r   ru   rn   r8   rv   rz   r   r
   r	   r   )
r;   r[   r   r\   r]   r0   rw   rx   rz   r{   s
             r!   update_sandboxzSandboxClient.update_sandbox  s   : 	[-000%'9:::...."$&GFO"%0GM"'*:G&'	z'''4+@+@+I+I (  H %%'''$X]]__TuUUUU$ 	 	 	z%,,+1111   z%,,/?X???"+    %Q'''	s   A,B2 2D"ADD"c               J   | j          d| }	 | j                            ||                     |                    }|                                 dS # t
          j        $ r@}|j        j        dk    rt          d| dd          |t          |           Y d}~dS 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   ri   r   Nr6   r:   deleterB   rt   r8   rv   rz   r   r
   r   r   s         r!   delete_sandboxzSandboxClient.delete_sandbox  s     ....	(z((d6K6KG6T6T(UUH%%'''''$ 	( 	( 	(z%,,+1111   %Q'''''''''	(   AA B""5BB"r   c                  | j          d| d}	 | j                            ||                     |                    }|                                 t          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   ri   r   N)r6   r:   r   rB   rt   r   ru   rn   r8   rv   rz   r   r
   r   r   s         r!   get_sandbox_statusz SandboxClient.get_sandbox_status  s    & 55555
	z~~c43H3H3Q3Q~RRH%%'''!+HMMOO<<<$ 	 	 	z%,,+1111   %Q'''	s   A(A8 8C6B==CiX  expires_in_secondsr0   portr   r   c                   t                      j         d d}d}d fd}	  j                            ||                                         }|                                 t          j        |                                |          S # t          j
        $ r;}	|	j        j        d	k    rt          d
 dd          |	t          |	            d}	~	ww xY w)ai  Get an authenticated URL for a service running inside a sandbox.

        Returns a :class:`ServiceURL` whose properties auto-refresh the
        token transparently before it expires.  The object also provides
        HTTP helper methods (``.get``, ``.post``, etc.) that inject the
        authentication header automatically.

        Args:
            name: Sandbox name.
            port: Port the service is listening on inside the sandbox.
            expires_in_seconds: Token TTL in seconds (1--86400, default 600).
            headers: Optional per-request header overrides.

        Returns:
            ServiceURL with auto-refreshing token and HTTP helpers.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            ValueError: If port or expires_in_seconds is out of range.
            SandboxClientError: For other errors.
        r~   z/service-url)r   r   r   r   c                 6                                    S )Nr   )service)r   r0   r[   r   r;   s   r!   
_refresherz)SandboxClient.service.<locals>._refresher"  s*    <<#5	     r#   r   )r   r   r   r   ri   r   N)r   r   )r   r6   r:   rs   rB   rt   r   ru   rn   r8   rv   rz   r   r
   r   )
r;   r[   r   r   r0   rw   rx   r   rz   r{   s
   `````     r!   r   zSandboxClient.service  sG   : 	 &8999:::::7IJJ	 	 	 	 	 	 	 	 	 		z'4+@+@+I+I '  H %%''''JOOOO$ 	 	 	z%,,+1111   %Q'''	s   A+B C).6C$$C)x   g      ?)r-   poll_intervalr0   r   c                  ddl }|                                |z   }	 |                     ||          }|j        dk    r|                     ||          S |j        dk    rt          |j        pdd	          ||                                z
  }|dk    rt          d
| d| dd|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   NTr|   readyfailedzSandbox provisioning failedri   r   r   ' not ready after sr   last_status)
time	monotonicr   statusr   r   status_messager   sleepmin)	r;   r[   r-   r   r0   r   deadliner   	remainings	            r!   wait_for_sandboxzSandboxClient.wait_for_sandbox8  s   6 	>>##g-	6,,T7,CCF}''''g'>>>}((+)J-J"+    !4>>#3#33IA~~*BBBBBB"+ &   
 JJs=)44555!	6r#   r-   r0   c               z   | j          d| d}	 | j                            |i |                     |                    }|                                 nQ# t
          j        $ r?}|j        j        dk    rt          d| dd          |t          |           Y d	}~nd	}~ww xY w|                     |||
          S )a  Start a stopped sandbox and wait until ready.

        Args:
            name: Sandbox name.
            timeout: Timeout in seconds when waiting for ready.

        Returns:
            Sandbox in "ready" status.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            ResourceCreationError: If sandbox fails during startup.
            ResourceTimeoutError: If sandbox doesn't become ready within timeout.
            SandboxClientError: For other errors.
        r~   z/startr   r   r   r   ri   r   Nr   )r6   r:   rs   rB   rt   r8   rv   rz   r   r
   r   r   )r;   r[   r-   r0   rw   rz   r{   s          r!   start_sandboxzSandboxClient.start_sandboxh  s    , 44444
	(z"d&;&;G&D&D '  H %%''''$ 	( 	( 	(z%,,+1111   %Q''''''''	( $$T7G$LLLs   AA B"#5BB"c               N   | j          d| d}	 | j                            |i |                     |                    }|                                 d	S # t
          j        $ r@}|j        j        dk    rt          d| dd          |t          |           Y d	}~d	S d	}~ww xY w)
zStop a running sandbox (preserves sandbox files for later restart).

        Args:
            name: Sandbox name.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            SandboxClientError: For other errors.
        r~   z/stopr   r   r   r   ri   r   N)r6   r:   rs   rB   rt   r8   rv   rz   r   r
   r   r   s         r!   stop_sandboxzSandboxClient.stop_sandbox  s     33333
	(z"d&;&;G&D&D '  H %%'''''$ 	( 	( 	(z%,,+1111   %Q'''''''''	(s   AA B$$5BB$<   )registry_idregistry_urlregistry_usernameregistry_passwordr-   r0   docker_imager   r   r   r   r   c                  | j          d}
|||d}|||d<   |||d<   |||d<   |||d<   	 | j                            |
||                     |	                    }|                                 t          j        |                                          }n'# t          j	        $ r}t          |            d}~ww xY w|                     |j        ||		          S )
al  Build a snapshot from a Docker image.

        Blocks until the snapshot is ready (polls with 2s interval).

        Args:
            name: Snapshot name.
            docker_image: Docker image to build from (e.g., "python:3.12-slim").
            fs_capacity_bytes: Filesystem capacity in bytes.
            registry_id: Private registry ID (alternative to URL/credentials).
            registry_url: Registry URL for private images.
            registry_username: Registry username.
            registry_password: Registry password.
            timeout: Timeout in seconds when waiting for ready.

        Returns:
            Snapshot in "ready" status.

        Raises:
            ResourceTimeoutError: If snapshot doesn't become ready within timeout.
            ResourceCreationError: If snapshot build fails.
            SandboxClientError: For other errors.
        
/snapshots)r[   r   r`   Nr   r   r   r   r   r   )r6   r:   rs   rB   rt   r   ru   rn   r8   rv   r   wait_for_snapshotid)r;   r[   r   r`   r   r   r   r   r-   r0   rw   rx   rz   snapshotr{   s                  r!   create_snapshotzSandboxClient.create_snapshot  s$   F +++ (!2#
 #

 "%0GM"#&2GN#(+<G'((+<G'(	z'4+@+@+I+I '  H %%''')(--//::HH$ 	 	 	$Q'''	 %%hk7G%TTTs   A*B B=(B88B=sandbox_namec                  | j          d| d}d|i}	 | j                            |||                     |                    }|                                 t          j        |                                          }nM# t          j	        $ r;}	|	j
        j        dk    rt          d| dd	          |	t          |	            d
}	~	ww xY w|                     |j        ||          S )ao  Capture a snapshot from a running sandbox.

        Blocks until the snapshot is ready (polls with 2s interval).

        Args:
            sandbox_name: Name of the sandbox to capture from.
            name: Snapshot name.
            timeout: Timeout in seconds when waiting for ready.

        Returns:
            Snapshot in "ready" status.

        Raises:
            ResourceNotFoundError: If sandbox not found.
            ResourceTimeoutError: If snapshot doesn't become ready within timeout.
            ResourceCreationError: If snapshot capture fails.
            SandboxClientError: For other errors.
        r~   z	/snapshotr[   r   r   r   r   ri   r   Nr   )r6   r:   rs   rB   rt   r   ru   rn   r8   rv   rz   r   r
   r   r   r   )
r;   r   r[   r-   r0   rw   rx   rz   r   r{   s
             r!   capture_snapshotzSandboxClient.capture_snapshot  s   4 ?????#)4.	z'4+@+@+I+I '  H %%''')(--//::HH$ 	 	 	z%,,+9999   %Q'''	 %%hk7G%TTTs   A*A> >C6CCc                  | j          d| }	 | j                            ||                     |                    }|                                 t          j        |                                          S # t          j	        $ r;}|j
        j        dk    rt          d| dd          |t          |            d}~ww xY w)	zGet a snapshot by ID.

        Args:
            snapshot_id: Snapshot UUID.

        Returns:
            Snapshot.

        Raises:
            ResourceNotFoundError: If snapshot not found.
            SandboxClientError: For other errors.
        /snapshots/r|   r   
Snapshot 'r   r   r   N)r6   r:   r   rB   rt   r   ru   rn   r8   rv   rz   r   r
   r   r;   rb   r0   rw   rz   r{   s         r!   get_snapshotzSandboxClient.get_snapshot  s     99K99
	z~~c43H3H3Q3Q~RRH%%'''%hmmoo666$ 	 	 	z%,,+9999   %Q'''	s   A(A7 7C6B<<C)name_containslimitoffsetr0   r   r   r   list[Snapshot]c                  | j          d}i }|||d<   |||d<   |||d<   	 | j                            ||pd|                     |                    }|                                 |                                }d |                    dg           D             S # t          j        $ r9}	|	j        j	        d	k    rt          d
| d          |	t          |	            d}	~	ww xY w)aV  List snapshots.

        The backend always paginates this endpoint. When ``limit`` is omitted
        the server applies a default page size (currently 50), so a single
        call is not guaranteed to return every snapshot. To iterate through
        all results, repeat the call with increasing ``offset`` values (or an
        explicit ``limit``) until fewer than ``limit`` snapshots come back.

        Args:
            name_contains: Optional case-insensitive substring filter applied
                to snapshot names server-side.
            limit: Optional maximum number of snapshots to return for a single
                request. Must be between 1 and 500 (inclusive); the server
                rejects values outside that range. Defaults to 50 server-side
                when omitted.
            offset: Optional number of snapshots to skip before returning
                results. Must be ``>= 0``. Useful for paginating through
                large result sets in combination with ``limit``.

        Returns:
            A single page of Snapshots matching the provided filters.
        r   Nr   r   r   )paramsr0   c                6    g | ]}t          j        |          S r'   )r   ru   )r   r   s     r!   r   z0SandboxClient.list_snapshots.<locals>.<listcomp>d  s#    MMMaH&q))MMMr#   	snapshotsr   r   r   r   )
r;   r   r   r   r0   rw   r   rz   r   r{   s
             r!   list_snapshotszSandboxClient.list_snapshots4  s7   < +++!#$&3F?##F7O%F8	z~~~--g66 &  H
 %%'''==??DMM488K3L3LMMMM$ 	 	 	z%,,%;s ; ; ;   %Q'''	s   A9B C%,4C  C%c               J   | j          d| }	 | j                            ||                     |                    }|                                 dS # t
          j        $ r@}|j        j        dk    rt          d| dd          |t          |           Y d}~dS d}~ww xY w)	zDelete a snapshot.

        Args:
            snapshot_id: Snapshot UUID.

        Raises:
            ResourceNotFoundError: If snapshot not found.
            SandboxClientError: For other errors.
        r   r|   r   r   r   r   r   Nr   r   s         r!   delete_snapshotzSandboxClient.delete_snapshotn  s     99K99	(z((d6K6KG6T6T(UUH%%'''''$ 	( 	( 	(z%,,+9999   %Q'''''''''	(r   i,  g       @c                  ddl }|                                |z   }	 |                     ||          }|j        dk    r|S |j        dk    rt	          |j        pdd	          ||                                z
  }|dk    rt          d
| d| dd|j                  |                    t          ||                     )a&  Poll until a snapshot reaches "ready" or "failed" status.

        Args:
            snapshot_id: Snapshot UUID.
            timeout: Maximum time to wait in seconds.
            poll_interval: Time between status checks in seconds.

        Returns:
            Snapshot in "ready" status.

        Raises:
            ResourceCreationError: If snapshot status becomes "failed".
            ResourceTimeoutError: If timeout expires.
            ResourceNotFoundError: If snapshot not found.
            SandboxClientError: For other errors.
        r   NTr|   r   r   zSnapshot build failedr   r   r   r   r   r   )	r   r   r   r   r   r   r   r   r   )	r;   rb   r-   r   r0   r   r   r   r   s	            r!   r   zSandboxClient.wait_for_snapshot  s    0 	>>##g-	6((g(FFH'))(**++F/F",    !4>>#3#33IA~~*JJJJJJ", (   
 JJs=)44555!	6r#   )
r,   r$   r-   r1   r.   r$   r/   r2   r0   r3   )r0   r?   r   r@   )r   rC   )r   r*   )rM   rN   rO   rP   rQ   rR   r   rC   r   r   )N)rb   r$   rZ   r$   r[   r$   r-   r2   r\   rc   r]   rc   r^   rc   r_   rc   r`   rc   ra   rd   r0   r?   r   r   )rb   r$   rZ   r$   r[   r$   r-   r2   rj   rk   r\   rc   r]   rc   r^   rc   r_   rc   r`   rc   ra   rd   r0   r?   r   r   )r[   r   r0   r?   r   r   )r0   r?   r   r   )r[   r   r   r$   r\   rc   r]   rc   r0   r?   r   r   )r[   r   r0   r?   r   rC   )r[   r   r0   r?   r   r   )
r[   r   r   r2   r   r2   r0   r?   r   r   )
r[   r   r-   r2   r   r1   r0   r?   r   r   )r[   r   r-   r2   r0   r?   r   r   )r[   r   r   r   r`   r2   r   r$   r   r$   r   r$   r   r$   r-   r2   r0   r?   r   r   )
r   r   r[   r   r-   r2   r0   r?   r   r   )rb   r   r0   r?   r   r   )
r   r$   r   rc   r   rc   r0   r?   r   r   )rb   r   r0   r?   r   rC   )
rb   r   r-   r2   r   r1   r0   r?   r   r   )__name__
__module____qualname____doc__r>   rB   rE   rJ   rL   rT   rW   ri   rf   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r'   r#   r!   r*   r*   3   s        . '+!%,0 
  
  
  
  
  
D: : : :            < < < < &*R (,"%)*.##'+/15"&R R R R R Rl &*m (,"#%)*.##'+/15"&m m m m m m^ CG      : ;?      : #'%)*."&: : : : : :x FJ ( ( ( ( ( (. 7;     L #&"&5 5 5 5 5 5v ""&.6 .6 .6 .6 .6 .6h "&$M $M $M $M $M $ML DH ( ( ( ( ( (D &*&*+/+/"&=U =U =U =U =U =UH "&,U ,U ,U ,U ,U ,U^ >B     @ (,# $"&8 8 8 8 8 8v >B( ( ( ( ( (8 ""&+6 +6 +6 +6 +6 +6 +6 +6r#   r*   r   )r   r$   )%r   
__future__r   collections.abcr   typingr   r   r8   	langsmithr   r   langsmith.sandbox._exceptionsr   r	   r
   r   r   langsmith.sandbox._helpersr   r   r   r   r   langsmith.sandbox._modelsr   r   r   langsmith.sandbox._sandboxr   langsmith.sandbox._transportr   r"   r(   r   r?   r*   r'   r#   r!   <module>r      s   K K " " " " " " # # # # # #                  ' ' ' ' ' '                                   
 / . . . . . 7 7 7 7 7 7. . . .+ + + +
 '#s(+,~6 ~6 ~6 ~6 ~6 ~6 ~6 ~6 ~6 ~6r#   