There are two easy ways to send files to your Beam endpoints and ASGI web servers.

Sending Files to Endpoints Using Base64

The simplest way to send files to your Beam endpoint is to use Base64 encoding. In the example below, we will use this method to send an image to an endpoint. The first step is to define an endpoint that accepts an encoded string.

import base64
import io
from beam import endpoint
from beam import Image as BeamImage
from PIL import Image

@endpoint(name="image_endpoint", image=BeamImage().add_python_packages(["pillow"]))
def image_endpoint(image: str):
    image = base64.b64decode(image)
    image = Image.open(io.BytesIO(image))
    # do something with the image
    return {"message": "Image processed successfully"}

We can then deploy our endpoint with the command beam deploy app.py:image_endpoint. The simple script below can be used to send an image to the endpoint.

Using S3 to Send Files

With Beam, you can easily mount S3 buckets to your endpoints and web servers. This allows you to upload files to S3 and access them in your endpoint or web server. This method is recommended if you are sending large payloads (20+ MB). Another benefit of using S3 is that you will not need to include decoding logic in your endpoint.

We can modify our previous example by accepting a filename and reading the image from a mounted S3 bucket. Our frontend will need to upload the image to the S3 bucket and then pass the filename to our endpoint.

from beam import CloudBucket, CloudBucketConfig, endpoint
from beam import Image as BeamImage
from PIL import Image

mount_path = "./uploads"
uploads = CloudBucket(
    name="uploads",
    mount_path=mount_path,
    config=CloudBucketConfig(
        access_key="BEAM_S3_KEY",
        secret_key="BEAM_S3_SECRET",
    ),
)

@endpoint(name="image_endpoint", image=BeamImage().add_python_packages(["pillow"]), volumes=[uploads])
def image_endpoint(image_name: str):
    image_path = os.path.join(uploads.mount_path, image_name)
    image = Image.open(image_path)
    # do something with the image
    return {"message": "Image processed successfully"}

In order to correctly mount the S3 bucket, we need to make sure that our secrets are set. We can do this using the Beam CLI.

beam secret create BEAM_S3_KEY "your-access-key"
beam secret create BEAM_S3_SECRET "your-secret-key"

Once again, we can deploy our endpoint with the command beam deploy app.py:image_endpoint.

To test this method, we can upload an image to the S3 bucket using the AWS CLI and then pass the filename to our endpoint.

aws s3 cp ./test.png s3://uploads/

The image will be uploaded to the S3 bucket and the endpoint will be able to read it. We can verify this by invoking our endpoint with the filename.

curl -X POST "https://image-endpoint-53b4230-v1.app.beam.cloud" \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <your-token>' \
-d '{"image_name": "test.png"}'