Пример #1
0
    def upload(self, file_name: str, remote_path: str) -> str:
        """
        Uploads given file to S3
        :param file_name: Path to the file that will be uploaded
        :param remote_path:  be uploaded
        :return: VersionId of the latest upload
        """

        if self.prefix:
            remote_path = "{0}/{1}".format(self.prefix, remote_path)

        # Check if a file with same data exists
        if not self.force_upload and self.file_exists(remote_path):
            LOG.debug(
                "File with same data is already exists at %s. "
                "Skipping upload", remote_path)
            return self.make_url(remote_path)

        try:

            # Default to regular server-side encryption unless customer has
            # specified their own KMS keys
            additional_args = {"ServerSideEncryption": "AES256"}

            if self.kms_key_id:
                additional_args["ServerSideEncryption"] = "aws:kms"
                additional_args["SSEKMSKeyId"] = self.kms_key_id

            if self.artifact_metadata:
                additional_args["Metadata"] = self.artifact_metadata

            if not self.bucket_name:
                raise BucketNotSpecifiedError()

            if not self.no_progressbar:
                print_progress_callback = ProgressPercentage(
                    file_name, remote_path)
                future = self.transfer_manager.upload(
                    file_name, self.bucket_name, remote_path, additional_args,
                    [print_progress_callback])
            else:
                future = self.transfer_manager.upload(file_name,
                                                      self.bucket_name,
                                                      remote_path,
                                                      additional_args)
            future.result()

            return self.make_url(remote_path)

        except botocore.exceptions.ClientError as ex:
            error_code = ex.response["Error"]["Code"]
            if error_code == "NoSuchBucket":
                raise NoSuchBucketError(bucket_name=self.bucket_name) from ex
            raise ex
Пример #2
0
 def test_s3_upload_no_bucket(self):
     s3_uploader = S3Uploader(
         s3_client=self.s3,
         bucket_name=None,
         prefix=self.prefix,
         kms_key_id=self.kms_key_id,
         force_upload=self.force_upload,
     )
     s3_uploader.artifact_metadata = {"a": "b"}
     remote_path = Path.joinpath(Path(os.getcwd()), Path("tmp"))
     with self.assertRaises(BucketNotSpecifiedError) as ex:
         with tempfile.NamedTemporaryFile(mode="w", delete=False) as f:
             s3_uploader.upload(f.name, remote_path)
         self.assertEqual(BucketNotSpecifiedError().message, str(ex))
Пример #3
0
    def file_exists(self, remote_path: str) -> bool:
        """
        Check if the file we are trying to upload already exists in S3

        :param remote_path:
        :return: True, if file exists. False, otherwise
        """

        try:
            # Find the object that matches this ETag
            if not self.bucket_name:
                raise BucketNotSpecifiedError()
            self.s3.head_object(Bucket=self.bucket_name, Key=remote_path)
            return True
        except botocore.exceptions.ClientError:
            # Either File does not exist or we are unable to get
            # this information.
            return False
Пример #4
0
 def make_url(self, obj_path: str) -> str:
     if not self.bucket_name:
         raise BucketNotSpecifiedError()
     return "s3://{0}/{1}".format(self.bucket_name, obj_path)