Issue with corrupted assets flutter, fastapi, Lambda, ApiGateway, S3

Viewed 117

I'm running into a strange issue with the following setup:

Flutter app that uploads an image to a fastapi backend thats served from a lambda function through ApiGateway, which uses bota3 to upload and serve the image from s3.

My python routes look like this.

@router.get("{filePath:path}")
async def read_root(filePath, current_user: CognitoClaims = Depends(get_current_user)):
    user: User = await get_user(current_user.username)
    company: Company = await get_company(user);

    try:
        response = s3.generate_presigned_url('get_object', Params={
            'Bucket': settings.s3_bucket,
            'Key': filePath.strip("/")
        }, ExpiresIn=3600)
    except ClientError as e:
        logging.error(e)
        return None
    return response

@router.post("")
async def add_file(current_user: CognitoClaims = Depends(get_current_user), file: UploadFile = File(...)):
    user: User = await get_user(current_user.username)
    company: Company = await get_company(user);

    file_name = file.filename;

    full_name = f"{current_user.username}/uploads/{file_name}"

    try:
        s3.upload_fileobj(file.file, settings.s3_bucket, full_name)
    
        response = s3.generate_presigned_url('get_object', Params={
                'Bucket': settings.s3_bucket,
                'Key': full_name
            }, ExpiresIn=3600);
    except ClientError as e:
        logging.error(e)
        return None
        
    return {
        "path": full_name,
        'url': response
    };

The endpoints and functions are all successful, but the images uploaded to s3 seem to be corrupted.

The strange part is that I am able to use these endpoints perfectly when hitting using postman, and even stranger than that it runs fine locally from the flutter app. so i can only assume its an issue related to my ApiGateway setup.

1 Answers

This issue is due to REST API Gateways defaulting to handling all payloads as text. In order for a payload to be handled as binary, the media type for the payload must be added to the binaryMediaTypes for the REST API Gateway.

In the specific case of file uploads via UploadFile in FastAPI, the media type is multipart/form-data, and so this needs to be added to the binaryMediaTypes configuration for the gateway. In my case I'm deploying via CDK and so on my lambdaRestApi I needed to set binaryMediaTypes to ["multipart/form-data"].

More information can be found in the AWS Working with binary media types for REST APIs Developer Guide.

Related