1212# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313# See the License for the specific language governing permissions and
1414# limitations under the License.
15-
16-
15+ import hashlib
1716import os
1817import re
1918import shutil
@@ -192,6 +191,13 @@ def list_files(self, bucket: str, path: str) -> List[str]:
192191 else :
193192 return [f"{ S3 } ://{ bucket } /{ path .lstrip ('/' )} " ]
194193
194+ def _hash_file (self , local_path : str ):
195+ h = hashlib .sha256 ()
196+ with open (local_path , "rb" ) as f :
197+ for block in iter (lambda : f .read (2 ** 20 ), b"" ):
198+ h .update (block )
199+ return h .hexdigest ()
200+
195201 def upload_file (self , local_path : str , bucket : str , remote_path : str ):
196202 """
197203 Uploads file to s3.
@@ -201,8 +207,36 @@ def upload_file(self, local_path: str, bucket: str, remote_path: str):
201207 bucket (str): s3 Bucket name
202208 remote_path (str): relative path to the folder to which the files need to be uploaded
203209 """
204- with open (local_path , "rb" ) as file :
205- self .s3_client .upload_fileobj (file , bucket , remote_path )
210+
211+ sha256sum = self ._hash_file (local_path )
212+
213+ import botocore
214+
215+ try :
216+ head_response = self .s3_client .head_object (Bucket = bucket , Key = remote_path )
217+ if head_response ["Metadata" ]["sha256sum" ] == sha256sum :
218+ # File already exists
219+ return remote_path
220+ else :
221+ print (f"Uploading { local_path } to { remote_path } " )
222+ self .s3_client .upload_file (
223+ local_path ,
224+ bucket ,
225+ remote_path ,
226+ ExtraArgs = {"Metadata" : {"sha256sum" : sha256sum }},
227+ )
228+ return remote_path
229+ except botocore .exceptions .ClientError as e :
230+ if e .response ["Error" ]["Code" ] != "404" :
231+ raise
232+
233+ self .s3_client .upload_file (
234+ local_path ,
235+ bucket ,
236+ remote_path ,
237+ ExtraArgs = {"Metadata" : {"sha256sum" : sha256sum }},
238+ )
239+ return remote_path
206240
207241
208242class LocalFSClient (AbstractStagingClient ):
0 commit comments