o
    ;i}                     @   s   d dl mZ d dlmZ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mZ eG d	d
 d
Zdeeeef  deej fddZe
eZdS )    )	dataclass)OptionalSequence)urlparse)api_pb2   )synchronize_api)logger)_Secretc                   @   s~   e Zd ZU dZeed< dZee ed< dZee ed< dZ	ee
 ed< dZee ed< dZeed	< dZeed
< dZeed< dS )_CloudBucketMounta
  Mounts a cloud bucket to your container. Currently supports AWS S3 buckets.

    S3 buckets are mounted using [AWS S3 Mountpoint](https://github.com/awslabs/mountpoint-s3).
    S3 mounts are optimized for reading large files sequentially. It does not support every file operation; consult
    [the AWS S3 Mountpoint documentation](https://github.com/awslabs/mountpoint-s3/blob/main/doc/SEMANTICS.md)
    for more information.

    **AWS S3 Usage**

    ```python
    import subprocess

    app = modal.App()
    secret = modal.Secret.from_name(
        "aws-secret",
        required_keys=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
        # Note: providing AWS_REGION can help when automatic detection of the bucket region fails.
    )

    @app.function(
        volumes={
            "/my-mount": modal.CloudBucketMount(
                bucket_name="s3-bucket-name",
                secret=secret,
                read_only=True
            )
        }
    )
    def f():
        subprocess.run(["ls", "/my-mount"], check=True)
    ```

    **Cloudflare R2 Usage**

    Cloudflare R2 is [S3-compatible](https://developers.cloudflare.com/r2/api/s3/api/) so its setup looks
    very similar to S3. But additionally the `bucket_endpoint_url` argument must be passed.

    ```python
    import subprocess

    app = modal.App()
    secret = modal.Secret.from_name(
        "r2-secret",
        required_keys=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
    )

    @app.function(
        volumes={
            "/my-mount": modal.CloudBucketMount(
                bucket_name="my-r2-bucket",
                bucket_endpoint_url="https://<ACCOUNT ID>.r2.cloudflarestorage.com",
                secret=secret,
                read_only=True
            )
        }
    )
    def f():
        subprocess.run(["ls", "/my-mount"], check=True)
    ```

    **Google GCS Usage**

    Google Cloud Storage (GCS) is [S3-compatible](https://cloud.google.com/storage/docs/interoperability).
    GCS Buckets also require a secret with Google-specific key names (see below) populated with
    a [HMAC key](https://cloud.google.com/storage/docs/authentication/managing-hmackeys#create).

    ```python
    import subprocess

    app = modal.App()
    gcp_hmac_secret = modal.Secret.from_name(
        "gcp-secret",
        required_keys=["GOOGLE_ACCESS_KEY_ID", "GOOGLE_ACCESS_KEY_SECRET"]
    )

    @app.function(
        volumes={
            "/my-mount": modal.CloudBucketMount(
                bucket_name="my-gcs-bucket",
                bucket_endpoint_url="https://storage.googleapis.com",
                secret=gcp_hmac_secret,
            )
        }
    )
    def f():
        subprocess.run(["ls", "/my-mount"], check=True)
    ```
    bucket_nameNbucket_endpoint_url
key_prefixsecretoidc_auth_role_arnF	read_onlyrequester_paysforce_path_style)__name__
__module____qualname____doc__str__annotations__r   r   r   r   r
   r   r   boolr   r    r   r   L/home/ubuntu/.local/lib/python3.10/site-packages/modal/cloud_bucket_mount.pyr      s   
 Yr   mountsreturnc                 C   s   g }| D ]o\}}|j r3t|j }|jdrtjjj}n|jdr(tjjj}nt	
d tjjj}ntjjj}|jrB|jsBtd|jrO|jdsOtd|j}tj|j|j ||jr`|jjnd|j||j||j|jd
}|| q|S )	zfHelper function to convert `CloudBucketMount` to a list of protobufs that can be passed to the server.zr2.cloudflarestorage.comzstorage.googleapis.comzfCloudBucketMount received unrecognized bucket endpoint URL. Assuming AWS S3 configuration as fallback.z4Credentials required in order to use Requester Pays./zHkey_prefix will be prefixed to all object paths, so it must end in a '/' )
r   r   
mount_pathcredentials_secret_idr   bucket_typer   r   r   r   )r   r   hostnameendswithr   CloudBucketMount
BucketTypeR2GCPr	   infoS3r   r   
ValueErrorr   r   	object_idr   r   r   append)r   cloud_bucket_mountspathmountparse_resultr#   r   cloud_bucket_mountr   r   r   cloud_bucket_mounts_to_proto{   s@   

r4   N)dataclassesr   typingr   r   urllib.parser   modal_protor   _utils.async_utilsr   configr	   r   r
   r   tupler   listr&   r4   r   r   r   r   <module>   s   $m/