#python #amazon-s3 #google-cloud-storage #boto3 #gcloud
#python #amazon-s3 #google-облачное хранилище #boto3 #gcloud
Вопрос:
Я ищу pythonic способ копирования файла из AWS S3 в GCS.
Я не хочу открывать / читать файл, а затем использовать метод blob.upload_from_string(). Я хочу передать его «как есть».
Я не могу использовать ‘gsutils’. Объем библиотек, с которыми я работаю, — gcloud, boto3 (также экспериментировал с s3fs).
Вот простой пример (который, похоже, работает) с использованием метода blob.upload_from_string(), которого я пытаюсь избежать, потому что я не хочу открывать / читать файл. Я не могу заставить его работать с помощью метода blob.upload_from_file(), потому что GCS api требует доступного, читаемого, файлоподобного объекта, который я не могу предоставить должным образом.
Чего мне не хватает? Предложения?
import boto3
from gcloud import storage
from oauth2client.service_account import ServiceAccountCredentials
GSC_Token_File = 'path/to/GSC_token'
s3 = boto3.client('s3', region_name='MyRegion') # im running from AWS Lambda, no authentication required
gcs_credentials = ServiceAccountCredentials.from_json_keyfile_dict(GSC_Token_File)
gcs_storage_client = storage.Client(credentials=gcs_credentials, project='MyGCP_project')
gcs_bucket = gcs_storage_client.get_bucket('MyGCS_bucket')
s3_file_to_load = str(s3.get_object(Bucket='MyS3_bucket', Key='path/to/file_to_copy.txt')['Body'].read().decode('utf-8'))
blob = gcs_bucket.blob('file_to_copy.txt')
blob.upload_from_string(s3_file_to_load)
Ответ №1:
Итак, я еще немного покопался и наткнулся на эту статью, которая в конечном итоге привела меня к этому решению. По-видимому, API GCS можно вызвать с помощью AWS boto3 SDK.
Пожалуйста, обратите внимание на обязательное условие ключа HMAC, которое можно легко создать с помощью этих инструкций.
import boto3
# im using GCP Service Account so my HMAC was created accordingly.
# HMAC for User Account can be created just as well
service_Access_key = 'YourAccessKey'
service_Secret = 'YourSecretKey'
# Reminder: I am copying from S3 to GCS
s3_client = boto3.client('s3', region_name='MyRegion')
gcs_client =boto3.client(
"s3", # !just like that
region_name="auto",
endpoint_url="https://storage.googleapis.com",
aws_access_key_id=service_Access_key,
aws_secret_access_key=service_Secret,
)
file_to_transfer = s3_client.get_object(Bucket='MyS3_bucket', Key='path/to/file_to_copy.txt')
gcs_client.upload_fileobj(file_to_transfer['Body'], 'MyGCS_bucket', 'file_to_copy.txt')
Ответ №2:
Я понимаю, что вы пытаетесь переместить файлы из S3 в CGS, используя Python в функции AWS Lambda. Есть одна вещь, которую я хотел бы прояснить из заявления «Я не хочу открывать / читать файл», которая заключается в том, что когда файл загружается с S3, вы действительно читаете его и записываете куда-то, будь то в строку в памяти или во временный файл. В этом смысле на самом деле не имеет значения, какой из blob.upload_from_file()
or blob.upload_from_string()
используется, поскольку они эквивалентны; первый будет считываться из файла, а второй — нет, потому что данные уже считаны в памяти. Поэтому я предлагаю сохранить код таким, какой он есть, я не вижу пользы в его изменении.
В любом случае должен быть возможен подход к файлу, делающий что-то вроде приведенных ниже строк (непроверенный, у меня нет S3 для проверки):
# From S3 boto docs: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-example-download-file.html
s3.download_file('BUCKET_NAME', 'OBJECT_NAME', 'FILE_NAME')
blob.upload_from_file('FILE_NAME')
Наконец, стоит упомянуть инструмент переноса хранилища, который предназначен для перемещения огромных объемов данных из S3 в GCS. Если это похоже на ваш вариант использования, вы можете взглянуть на примеры кода для Python.