(Python 3.7)
У меня ушло несколько часов, чтобы понять это, потому что единственная ошибка, которую вы получаете, - «Указанный вами Content-MD5 недействителен».Супер полезно для отладки ... Во всяком случае, вот код, который я использовал, чтобы получить файл для правильной загрузки перед рефакторингом.
json_results = json_converter.convert_to_json(result)
json_results_utf8 = json_results.encode('utf-8')
content_md5 = md5.get_content_md5(json_results_utf8)
content_md5_string = content_md5.decode('utf-8')
metadata = {
"md5chksum": content_md5_string
}
s3 = boto3.resource('s3', config=Config(signature_version='s3v4'))
obj = s3.Object(bucket, 'filename.json')
obj.put(
Body=json_results_utf8,
ContentMD5=content_md5_string,
ServerSideEncryption='aws:kms',
Metadata=metadata,
SSEKMSKeyId=key_id)
и хэширование
def get_content_md5(data):
digest = hashlib.md5(data).digest()
return base64.b64encode(digest)
Сложная частья выяснил, какая кодировка вам нужна на каждом этапе процесса, и не очень хорошо знал, как в то время хранятся строки в python.
get_content_md5
принимает только объект, похожий на байты utf-8и возвращает то же самое.Но чтобы передать хэш md5 в aws, это должна быть строка.Вы должны расшифровать его перед тем, как передать его ContentMD5
.
Pro-tip - Body
, с другой стороны, необходимо предоставить байты или объект для поиска.Убедитесь, что если вы передаете объект поиска, который вы seek(0)
, в начало файла, прежде чем передать его в AWS, иначе MD5 не будет соответствовать.По этой причине использование байтов менее подвержено ошибкам, imo.