11# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22# SPDX-License-Identifier: Apache-2.0
33
4+ import boto3
45import logging
56
67from botocore .exceptions import ClientError
1213class S3ConditionalRequests :
1314 """Encapsulates S3 conditional request operations."""
1415
15- def __init__ (self , s3_client , source_bucket : str , dest_bucket : str ):
16+ def __init__ (self , s3_client ):
1617 self .s3 = s3_client
17- self .source_bucket = source_bucket
18- self .dest_bucket = dest_bucket
18+
19+ @classmethod
20+ def from_client (cls ):
21+ """
22+ Instantiates this class from a Boto3 client.
23+ """
24+ s3_client = boto3 .client ("s3" )
25+ return cls (s3_client )
1926
2027 # snippet-start:[python.example_code.s3.GetObjectConditional]
2128
22- def get_object_conditional (self , object_key : str , condition_type : str , condition_value : str ):
29+ def get_object_conditional (
30+ self ,
31+ object_key : str ,
32+ source_bucket : str ,
33+ condition_type : str ,
34+ condition_value : str ,
35+ ):
2336 """
2437 Retrieves an object from Amazon S3 with a conditional request.
2538
2639 :param object_key: The key of the object to retrieve.
40+ :param source_bucket: The source bucket of the object.
2741 :param condition_type: The type of condition: 'IfMatch', 'IfNoneMatch', 'IfModifiedSince', 'IfUnmodifiedSince'.
2842 :param condition_value: The value to use for the condition.
2943 """
3044 try :
3145 response = self .s3 .get_object (
32- Bucket = self . source_bucket ,
46+ Bucket = source_bucket ,
3347 Key = object_key ,
34- ** {condition_type : condition_value }
48+ ** {condition_type : condition_value },
49+ )
50+ sample_bytes = response ["Body" ].read (20 )
51+ print (
52+ f"\t Conditional read successful. Here are the first 20 bytes of the object:\n "
3553 )
36- sample_bytes = response ['Body' ].read (20 )
37- print (f"\t Conditional read successful. Here are the first 20 bytes of the object:\n " )
3854 print (f"\t { sample_bytes } " )
3955 except ClientError as e :
40- error_code = e .response [' Error' ][ ' Code' ]
41- if error_code == '412' :
56+ error_code = e .response [" Error" ][ " Code" ]
57+ if error_code == "PreconditionFailed" :
4258 print ("\t Conditional read failed: Precondition failed" )
43- if error_code == ' 304' :
59+ elif error_code == " 304" : # Not modified error code.
4460 print ("\t Conditional read failed: Object not modified" )
4561 else :
4662 logger .error (f"Unexpected error: { error_code } " )
@@ -50,26 +66,25 @@ def get_object_conditional(self, object_key: str, condition_type: str, condition
5066
5167 # snippet-start:[python.example_code.s3.PutObjectConditional]
5268
53- def put_object_conditional (self , object_key : str , data : bytes , condition_type : str , condition_value : str ):
69+ def put_object_conditional (self , object_key : str , source_bucket : str , data : bytes ):
5470 """
55- Uploads an object to Amazon S3 with a conditional request.
71+ Uploads an object to Amazon S3 with a conditional request. Prevents overwrite
72+ using an IfNoneMatch condition for the object key.
5673
5774 :param object_key: The key of the object to upload.
75+ :param source_bucket: The source bucket of the object.
5876 :param data: The data to upload.
59- :param condition_type: The type of condition to apply, e.g. 'IfNoneMatch'.
60- :param condition_value: The value to use for the condition.
6177 """
6278 try :
63- response = self .s3 .put_object (
64- Bucket = self . source_bucket ,
65- Key = object_key ,
66- Body = data ,
67- ** { condition_type : condition_value }
79+ self .s3 .put_object (
80+ Bucket = source_bucket , Key = object_key , Body = data , IfNoneMatch = "*"
81+ )
82+ print (
83+ f" \t Conditional write successful for key { object_key } in bucket { source_bucket } ."
6884 )
69- return response
7085 except ClientError as e :
71- error_code = e .response [' Error' ][ ' Code' ]
72- if error_code == '412' :
86+ error_code = e .response [" Error" ][ " Code" ]
87+ if error_code == "PreconditionFailed" :
7388 print ("\t Conditional copy failed: Precondition failed" )
7489 else :
7590 logger .error (f"Unexpected error: { error_code } " )
@@ -78,37 +93,44 @@ def put_object_conditional(self, object_key: str, data: bytes, condition_type: s
7893 # snippet-end:[python.example_code.s3.PutObjectConditional]
7994
8095 # snippet-start:[python.example_code.s3.CopyObjectConditional]
81- def copy_object_conditional (self , source_key : str , dest_key : str , condition_type : str , condition_value : str ):
96+ def copy_object_conditional (
97+ self ,
98+ source_key : str ,
99+ dest_key : str ,
100+ source_bucket : str ,
101+ dest_bucket : str ,
102+ condition_type : str ,
103+ condition_value : str ,
104+ ):
82105 """
83106 Copies an object from one Amazon S3 bucket to another with a conditional request.
84107
85108 :param source_key: The key of the source object to copy.
86109 :param dest_key: The key of the destination object.
110+ :param source_bucket: The source bucket of the object.
111+ :param dest_bucket: The destination bucket of the object.
87112 :param condition_type: The type of condition to apply, e.g.
88113 'CopySourceIfMatch', 'CopySourceIfNoneMatch', 'CopySourceIfModifiedSince', 'CopySourceIfUnmodifiedSince'.
89114 :param condition_value: The value to use for the condition.
90115 """
91116 try :
92- response = self .s3 .copy_object (
93- Bucket = self . dest_bucket ,
117+ self .s3 .copy_object (
118+ Bucket = dest_bucket ,
94119 Key = dest_key ,
95- CopySource = {'Bucket' : self .source_bucket , 'Key' : source_key },
96- ** {condition_type : condition_value }
120+ CopySource = {"Bucket" : source_bucket , "Key" : source_key },
121+ ** {condition_type : condition_value },
122+ )
123+ print (
124+ f"\t Conditional copy successful for key { dest_key } in bucket { dest_bucket } ."
97125 )
98- sample_bytes = response ['Body' ].read (20 )
99- print (f"\t Conditional copy successful. Here are the first 20 bytes of the object:\n " )
100- print (f"\t { sample_bytes } " )
101126 except ClientError as e :
102- error_code = e .response [' Error' ][ ' Code' ]
103- if error_code == '412' :
127+ error_code = e .response [" Error" ][ " Code" ]
128+ if error_code == "PreconditionFailed" :
104129 print ("\t Conditional copy failed: Precondition failed" )
105- if error_code == ' 304' :
130+ elif error_code == " 304" : # Not modified error code.
106131 print ("\t Conditional copy failed: Object not modified" )
107132 else :
108133 logger .error (f"Unexpected error: { error_code } " )
109134 raise
110135
111136 # snippet-end:[python.example_code.s3.CopyObjectConditional]
112-
113-
114-
0 commit comments