# S3 Reference ## Common Operations Use transfer methods for file upload/download -- they handle multipart automatically: ```python import boto3 s3 = boto3.client("s3") # Upload / download files s3.upload_file("local.txt", "my-bucket", "remote.txt") s3.download_file("my-bucket", "remote.txt", "local.txt") # Upload / download file-like objects with open("local.txt", "rb") as f: s3.upload_fileobj(f, "my-bucket", "remote.txt") # Presigned URL url = s3.generate_presigned_url( "get_object", Params={"Bucket": "my-bucket", "Key": "my-key"}, ExpiresIn=3600, ) ``` **Always close S3 streaming bodies** -- unread `Body` streams hold connections open: ```python response = s3.get_object(Bucket="bucket", Key="key") try: data = response["Body"].read() finally: response["Body"].close() # Or use as context manager with s3.get_object(Bucket="bucket", Key="key")["Body"] as body: data = body.read() ``` ## Transfer Methods The S3 client and resource provide managed transfer methods that handle multipart upload/download, retries, and parallelism automatically: ```python import boto3 s3 = boto3.client("s3") # File transfers s3.upload_file("local.txt", "my-bucket", "remote.txt") s3.download_file("my-bucket", "remote.txt", "local.txt") # File-like object transfers with open("local.txt", "rb") as f: s3.upload_fileobj(f, "my-bucket", "remote.txt") with open("local.txt", "wb") as f: s3.download_fileobj("my-bucket", "remote.txt", f) ``` ### Extra arguments Pass any PutObject/GetObject parameters via `ExtraArgs`: ```python s3.upload_file( "local.txt", "my-bucket", "remote.txt", ExtraArgs={ "ContentType": "text/plain", "ServerSideEncryption": "aws:kms", "Metadata": {"author": "alice"}, }, ) ``` ### Progress callbacks ```python import os file_size = os.path.getsize("large_file.bin") uploaded = 0 def progress(bytes_transferred): nonlocal uploaded uploaded += bytes_transferred pct = (uploaded / file_size) * 100 print(f"\r{pct:.1f}%", end="") s3.upload_file("large_file.bin", "bucket", "key", Callback=progress) ``` ## TransferConfig Control multipart thresholds and concurrency: ```python from boto3.s3.transfer import TransferConfig config = TransferConfig( multipart_threshold=8 * 1024 * 1024, # switch to multipart above 8MB (default 8MB) max_concurrency=10, # parallel transfer threads (default 10) multipart_chunksize=8 * 1024 * 1024, # part size (default 8MB, min 5MB) use_threads=True, # enable threading (default True) ) s3.upload_file("large.bin", "bucket", "key", Config=config) s3.download_file("bucket", "key", "large.bin", Config=config) ``` ## Streaming Body `get_object` returns a `StreamingBody` that must be read or closed: ```python response = s3.get_object(Bucket="bucket", Key="key") body = response["Body"] # Read all at once data = body.read() body.close() # Read in chunks for chunk in body.iter_chunks(chunk_size=4096): process(chunk) body.close() # Read lines (for text content) for line in body.iter_lines(): process(line) # As context manager -- auto-closes with s3.get_object(Bucket="bucket", Key="key")["Body"] as body: data = body.read() ``` `StreamingBody` can only be read once. If you need the data multiple times, save it to a variable. For file downloads, prefer `download_file`/`download_fileobj` over `get_object` -- they handle multipart, retries, and stream cleanup automatically. ## Presigned URLs ### GET (download) ```python url = s3.generate_presigned_url( "get_object", Params={"Bucket": "bucket", "Key": "key"}, ExpiresIn=3600, # seconds (default 3600) ) ``` ### PUT (upload) ```python url = s3.generate_presigned_url( "put_object", Params={ "Bucket": "bucket", "Key": "key", "ContentType": "application/pdf", }, ExpiresIn=3600, ) # Client must include Content-Type: application/pdf in the upload request ``` ### POST (browser form upload) ```python presigned = s3.generate_presigned_post( Bucket="bucket", Key="uploads/${filename}", Conditions=[ ["content-length-range", 0, 10 * 1024 * 1024], # max 10MB {"Content-Type": "image/jpeg"}, ], Fields={"Content-Type": "image/jpeg"}, ExpiresIn=600, ) # presigned["url"] -- POST URL # presigned["fields"] -- form fields to include ``` ## Copy Operations ```python # Client -- simple copy s3.copy_object( Bucket="dest-bucket", Key="dest-key", CopySource={"Bucket": "src-bucket", "Key": "src-key"}, ) # Resource -- handles multipart for large objects automatically s3_resource = boto3.resource("s3") copy_source = {"Bucket": "src-bucket", "Key": "src-key"} s3_resource.Object("dest-bucket", "dest-key").copy(copy_source) ``` ## Resource Interface ```python s3 = boto3.resource("s3") # Bucket operations bucket = s3.Bucket("my-bucket") for obj in bucket.objects.filter(Prefix="logs/"): print(obj.key, obj.size) # Object operations obj = s3.Object("my-bucket", "my-key") obj.upload_file("local.txt") obj.download_file("local.txt") obj.delete() # Read object body response = obj.get() data = response["Body"].read() ```