Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .doc_gen/metadata/s3_metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,11 @@ s3_CopyObject:
snippet_tags:
- python.example_code.s3.helper.ObjectWrapper
- python.example_code.s3.CopyObject
- description: Copy an object using a conditional request.
genai: some
snippet_tags:
- python.example_code.s3.helper.S3ConditionalRequests
- python.example_code.s3.CopyObjectConditional
Ruby:
versions:
- sdk_version: 3
Expand Down Expand Up @@ -872,6 +877,11 @@ s3_GetObject:
snippet_tags:
- python.example_code.s3.helper.ObjectWrapper
- python.example_code.s3.GetObject
- description: Get an object using a conditional request.
genai: some
snippet_tags:
- python.example_code.s3.helper.S3ConditionalRequests
- python.example_code.s3.GetObjectConditional
JavaScript:
versions:
- sdk_version: 3
Expand Down Expand Up @@ -1510,6 +1520,11 @@ s3_PutObject:
snippet_tags:
- python.example_code.s3.helper.ObjectWrapper
- python.example_code.s3.PutObject
- description: Upload an object using a conditional request.
genai: some
snippet_tags:
- python.example_code.s3.helper.S3ConditionalRequests
- python.example_code.s3.PutObjectConditional
Rust:
versions:
- sdk_version: 1
Expand Down Expand Up @@ -3456,6 +3471,28 @@ s3_Scenario_DeleteAllObjects:
- javascriptv3/example_code/s3/scenarios/delete-all-objects.js
services:
s3: {DeleteObjects, ListObjectsV2}
s3_Scenario_ConditionalRequests:
title: Make &S3; conditional requests using an &AWS; SDK.
title_abbrev: Make conditional requests
synopsis: add preconditions to &S3; requests.
category: Scenarios
languages:
Python:
versions:
- sdk_version: 3
github: python/example_code/s3/scenarios/conditional_requests
sdkguide:
excerpts:
- description: Run an interactive scenario demonstrating &S3; conditional requests.
genai: some
snippet_tags:
- python.example_code.s3.S3ConditionalRequests.scenario
- description: A wrapper class that defines the conditional request operations.
genai: some
snippet_tags:
- python.example_code.s3.S3ConditionalRequests.wrapper
services:
s3: {GetObject, PutObject, CopyObject}
s3_Scenario_ExpressBasics:
title: Learn the basics of Amazon S3 Express One Zone with an &AWS; SDK
title_abbrev: Learn the basics of S3 Express One Zone
Expand Down
19 changes: 19 additions & 0 deletions python/example_code/s3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ functions within the same service.
- [Create an Amazon Textract explorer application](../../cross_service/textract_explorer)
- [Detect entities in text extracted from an image](../../cross_service/textract_comprehend_notebook)
- [Detect objects in images](../../cross_service/photo_analyzer)
- [Make conditional requests](scenarios/conditional_requests/scenario.py)
- [Manage versioned objects in batches with a Lambda function](../../example_code/s3/s3_versioning)
- [Upload or download large files](file_transfer/file_transfer.py)
- [Work with versioned objects](s3_versioning/versioning.py)
Expand Down Expand Up @@ -190,6 +191,24 @@ This example shows you how to build an app that uses Amazon Rekognition to detec
<!--custom.scenarios.cross_RekognitionPhotoAnalyzer.start-->
<!--custom.scenarios.cross_RekognitionPhotoAnalyzer.end-->

#### Make conditional requests

This example shows you how to add preconditions to Amazon S3 requests.


<!--custom.scenario_prereqs.s3_Scenario_ConditionalRequests.start-->
<!--custom.scenario_prereqs.s3_Scenario_ConditionalRequests.end-->

Start the example by running the following at a command prompt:

```
python scenarios/conditional_requests/scenario.py
```


<!--custom.scenarios.s3_Scenario_ConditionalRequests.start-->
<!--custom.scenarios.s3_Scenario_ConditionalRequests.end-->

#### Manage versioned objects in batches with a Lambda function

This example shows you how to manage versioned S3 objects in batches with a Lambda function.
Expand Down
2 changes: 1 addition & 1 deletion python/example_code/s3/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
boto3>=1.34.4
boto3>=1.35.49
pytest>=7.2.1
requests>=2.28.2
53 changes: 53 additions & 0 deletions python/example_code/s3/scenarios/conditional_requests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

# Amazon S3 Conditional Requests Feature Scenario for the SDK for Python (boto3)

## Overview

This example demonstrates how to use the AWS SDK for Python (boto3) to work with Amazon Simple Storage Service (Amazon S3) conditional request features. The scenario demonstrates how to add preconditions to S3 operations, and how those operations will succeed or fail based on the conditional requests.

[Amazon S3 Conditional Requests](https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-requests.html) are used to add preconditions to S3 read, copy, or write requests.

## ⚠ Important

- Running this code might result in charges to your AWS account. For more details, see [AWS Pricing](https://aws.amazon.com/pricing/) and [Free Tier](https://aws.amazon.com/free/).
- Running the tests might result in charges to your AWS account.
- We recommend that you grant your code least privilege. At most, grant only the minimum permissions required to perform the task. For more information, see [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege).
- This code is not tested in every AWS Region. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services).

## Code examples

### Prerequisites

To run these examples, you need:

- Python 3.x installed.
- Run `python pip install -r requirements.txt`
- AWS credentials configured. For more information, see [Configuring the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html).

### Scenario

This example uses a feature scenario to demonstrate various aspects of S3 conditional requests. The scenario is divided into three stages:

1. **Setup**: Create test buckets and objects.
2. **Conditional Reads and Writes**: Explore S3 conditional requests by listing objects, attempting to read or write with conditional requests, and viewing request results.
3. **Clean**: Delete all objects and buckets.

#### Running the scenario
To run this feature scenario, run the command below from this directory:

```
python scenario.py
```


## Additional resources

- [Amazon S3 Developer Guide](https://docs.aws.amazon.com/AmazonS3/latest/userguide/conditional-requests.html)
- [Amazon S3 API Reference](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html)
- [boto3 Amazon S3 reference](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html)

---

© Amazon.com, Inc. or its affiliates. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# snippet-start:[python.example_code.s3.S3ConditionalRequests.wrapper]

import boto3
import logging

from botocore.exceptions import ClientError

# Configure logging
logger = logging.getLogger(__name__)


# snippet-start:[python.example_code.s3.helper.S3ConditionalRequests]
class S3ConditionalRequests:
"""Encapsulates S3 conditional request operations."""

def __init__(self, s3_client):
self.s3 = s3_client

@classmethod
def from_client(cls):
"""
Instantiates this class from a Boto3 client.
"""
s3_client = boto3.client("s3")
return cls(s3_client)

# snippet-end:[python.example_code.s3.helper.S3ConditionalRequests]

# snippet-start:[python.example_code.s3.GetObjectConditional]

def get_object_conditional(
self,
object_key: str,
source_bucket: str,
condition_type: str,
condition_value: str,
):
"""
Retrieves an object from Amazon S3 with a conditional request.

:param object_key: The key of the object to retrieve.
:param source_bucket: The source bucket of the object.
:param condition_type: The type of condition: 'IfMatch', 'IfNoneMatch', 'IfModifiedSince', 'IfUnmodifiedSince'.
:param condition_value: The value to use for the condition.
"""
try:
response = self.s3.get_object(
Bucket=source_bucket,
Key=object_key,
**{condition_type: condition_value},
)
sample_bytes = response["Body"].read(20)
print(
f"\tConditional read successful. Here are the first 20 bytes of the object:\n"
)
print(f"\t{sample_bytes}")
except ClientError as e:
error_code = e.response["Error"]["Code"]
if error_code == "PreconditionFailed":
print("\tConditional read failed: Precondition failed")
elif error_code == "304": # Not modified error code.
print("\tConditional read failed: Object not modified")
else:
logger.error(f"Unexpected error: {error_code}")
raise

# snippet-end:[python.example_code.s3.GetObjectConditional]

# snippet-start:[python.example_code.s3.PutObjectConditional]

def put_object_conditional(self, object_key: str, source_bucket: str, data: bytes):
"""
Uploads an object to Amazon S3 with a conditional request. Prevents overwrite
using an IfNoneMatch condition for the object key.

:param object_key: The key of the object to upload.
:param source_bucket: The source bucket of the object.
:param data: The data to upload.
"""
try:
self.s3.put_object(
Bucket=source_bucket, Key=object_key, Body=data, IfNoneMatch="*"
)
print(
f"\tConditional write successful for key {object_key} in bucket {source_bucket}."
)
except ClientError as e:
error_code = e.response["Error"]["Code"]
if error_code == "PreconditionFailed":
print("\tConditional write failed: Precondition failed")
else:
logger.error(f"Unexpected error: {error_code}")
raise

# snippet-end:[python.example_code.s3.PutObjectConditional]

# snippet-start:[python.example_code.s3.CopyObjectConditional]
def copy_object_conditional(
self,
source_key: str,
dest_key: str,
source_bucket: str,
dest_bucket: str,
condition_type: str,
condition_value: str,
):
"""
Copies an object from one Amazon S3 bucket to another with a conditional request.

:param source_key: The key of the source object to copy.
:param dest_key: The key of the destination object.
:param source_bucket: The source bucket of the object.
:param dest_bucket: The destination bucket of the object.
:param condition_type: The type of condition to apply, e.g.
'CopySourceIfMatch', 'CopySourceIfNoneMatch', 'CopySourceIfModifiedSince', 'CopySourceIfUnmodifiedSince'.
:param condition_value: The value to use for the condition.
"""
try:
self.s3.copy_object(
Bucket=dest_bucket,
Key=dest_key,
CopySource={"Bucket": source_bucket, "Key": source_key},
**{condition_type: condition_value},
)
print(
f"\tConditional copy successful for key {dest_key} in bucket {dest_bucket}."
)
except ClientError as e:
error_code = e.response["Error"]["Code"]
if error_code == "PreconditionFailed":
print("\tConditional copy failed: Precondition failed")
elif error_code == "304": # Not modified error code.
print("\tConditional copy failed: Object not modified")
else:
logger.error(f"Unexpected error: {error_code}")
raise

# snippet-end:[python.example_code.s3.CopyObjectConditional]
# snippet-end:[python.example_code.s3.S3ConditionalRequests.wrapper]
Loading
Loading