You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python开发:Twilio+Polly场景下S3上传及相关技术问题求助

Fixing S3 Content-Type Issues with Boto3 + Twilio, Plus Tinys3 Subdirectory Uploads

Hey there! I’ve worked through similar setups with Twilio, Amazon Polly, and S3, so let’s break down your problems step by step:

1. Fixing Boto3’s Content-Type Not Sticking for MP3 Files

The most common issue here is not explicitly setting the ContentType in the upload arguments, or placing it in the wrong spot. Twilio requires audio/mpeg for MP3 files, so make sure you’re passing this in the ExtraArgs parameter when uploading. Here’s a working code snippet:

import boto3

# Initialize S3 client
s3_client = boto3.client('s3')

local_mp3_path = "generated_polly_voice.mp3"
bucket_name = "your-twilio-audio-bucket"
s3_object_key = "polly-audio/voice-message.mp3"

# Upload with correct content type and public ACL (Twilio needs public access)
with open(local_mp3_path, 'rb') as mp3_file:
    s3_client.upload_fileobj(
        mp3_file,
        bucket_name,
        s3_object_key,
        ExtraArgs={
            "ContentType": "audio/mpeg",
            "ACL": "public-read"
        }
    )

Double-check these potential pitfalls:

  • If you were using upload_file instead of upload_fileobj, the ExtraArgs parameter still applies—don’t skip it.
  • Ensure your S3 bucket doesn’t have a bucket policy or lifecycle rule that overwrites object content types.
  • Verify you’re opening the file in binary read mode ('rb') to avoid corrupting the audio data.

2. Why Boto3 Changes Content-Type to binary/octet-stream

Boto3 tries to auto-detect the content type based on the file’s extension by default. If it can’t recognize the extension (e.g., your file has no extension, or a rare one), it falls back to binary/octet-stream. Other scenarios include:

  • You’re uploading raw bytes instead of a file object, so Boto3 has no filename/extension to infer from.
  • You forgot to include the ContentType parameter in your upload arguments, leaving S3 to apply its default.
  • A previous version of the object had binary/octet-stream and you didn’t overwrite the metadata on re-upload.

3. Uploading to S3 Subdirectories with Tinys3

First, keep in mind: S3 doesn’t have actual subdirectories—they’re just simulated using slashes (/) in the object key. To upload to a "subdirectory", simply include the path in your object key. Here’s how to do it with Tinys3:

from tinys3 import Connection

# Initialize Tinys3 connection
s3_conn = Connection(
    aws_access_key_id="YOUR_AWS_KEY",
    aws_secret_access_key="YOUR_AWS_SECRET",
    default_bucket="your-bucket-name"
)

local_file_path = "polly_output.mp3"
# Key includes the subdirectory path: "audio/subfolder/your-file.mp3"
s3_object_key = "audio/subfolder/polly-voice.mp3"

# Upload with correct content type and public ACL
with open(local_file_path, 'rb') as mp3_file:
    s3_conn.upload(
        s3_object_key,
        mp3_file,
        headers={
            "Content-Type": "audio/mpeg",
            "x-amz-acl": "public-read"
        }
    )

After uploading, you’ll see the "subdirectory" structure in the S3 console—this is just S3 grouping objects by the prefix before the slash. You don’t need to create the subdirectory first; uploading an object with a slash in the key will automatically create the visual structure.

内容的提问来源于stack exchange,提问作者Veysel Kocaman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:01:28