[英]Reading an JSON file from S3 using Python boto3
我一直在 S3 存储桶“测试”中关注 JSON
{
'Details' : "Something"
}
我正在使用以下代码来读取此 JSON 并打印密钥“详细信息”
s3 = boto3.resource('s3',
aws_access_key_id=<access_key>,
aws_secret_access_key=<secret_key>
)
content_object = s3.Object('test', 'sample_json.txt')
file_content = content_object.get()['Body'].read().decode('utf-8')
json_content = json.loads(repr(file_content))
print(json_content['Details'])
我收到错误,因为“字符串索引必须是整数”我不想从 S3 下载文件然后读取..
正如上面评论中提到的,必须删除repr
并且json
文件必须使用双引号作为属性。 在 aws/s3 上使用此文件:
{
"Details" : "Something"
}
和下面的 Python 代码,它可以工作:
import boto3
import json
s3 = boto3.resource('s3')
content_object = s3.Object('test', 'sample_json.txt')
file_content = content_object.get()['Body'].read().decode('utf-8')
json_content = json.loads(file_content)
print(json_content['Details'])
# >> Something
以下对我有用。
# read_s3.py
from boto3 import client
BUCKET = 'MY_S3_BUCKET_NAME'
FILE_TO_READ = 'FOLDER_NAME/my_file.json'
client = client('s3',
aws_access_key_id='MY_AWS_KEY_ID',
aws_secret_access_key='MY_AWS_SECRET_ACCESS_KEY'
)
result = client.get_object(Bucket=BUCKET, Key=FILE_TO_READ)
text = result["Body"].read().decode()
print(text['Details']) # Use your desired JSON Key for your value
进一步改进
直接硬编码 AWS Id & Secret Keys 不是一个好主意。 对于最佳实践,您可以考虑以下任一方法:
(1) 从存储在本地存储中的 json 文件 ( aws_cred.json
) 读取您的 AWS 凭证:
from json import load
from boto3 import client
...
credentials = load(open('local_fold/aws_cred.json'))
client = client('s3',
aws_access_key_id=credentials['MY_AWS_KEY_ID'],
aws_secret_access_key=credentials['MY_AWS_SECRET_ACCESS_KEY']
)
(2) 从您的环境变量中读取(我的首选部署选项):
from os import environ
client = boto3.client('s3',
aws_access_key_id=environ['MY_AWS_KEY_ID'],
aws_secret_access_key=environ['MY_AWS_SECRET_ACCESS_KEY']
)
让我们准备一个 shell 脚本(称为read_s3_using_env.sh
)来设置环境变量并添加我们的 python 脚本( read_s3.py
),如下所示:
# read_s3_using_env.sh
export MY_AWS_KEY_ID='YOUR_AWS_ACCESS_KEY_ID'
export MY_AWS_SECRET_ACCESS_KEY='YOUR_AWS_SECRET_ACCESS_KEY'
# execute the python file containing your code as stated above that reads from s3
python read_s3.py # will execute the python script to read from s3
现在在终端中执行 shell 脚本,如下所示:
sh read_s3_using_env.sh
想补充一点, botocore.response.streamingbody
与json.load
配合得很好:
import json
import boto3
s3 = boto3.resource('s3')
obj = s3.Object(bucket, key)
data = json.load(obj.get()['Body'])
您可以在 AWS Lambda 中使用以下代码从 S3 存储桶中读取 JSON 文件并使用 python 对其进行处理。
import json
import boto3
import sys
import logging
# logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
VERSION = 1.0
s3 = boto3.client('s3')
def lambda_handler(event, context):
bucket = 'my_project_bucket'
key = 'sample_payload.json'
response = s3.get_object(Bucket = bucket, Key = key)
content = response['Body']
jsonObject = json.loads(content.read())
print(jsonObject)
由于解码对我不起作用(s3 对象被压缩),我被卡住了一点。
发现这个对我有帮助的讨论: Python gzip: is there a way to decompress from a string?
import boto3
import zlib
key = event["Records"][0]["s3"]["object"]["key"]
bucket_name = event["Records"][0]["s3"]["bucket"]["name"]
s3_object = S3_RESOURCE.Object(bucket_name, key).get()['Body'].read()
jsonData = zlib.decompress(s3_object, 16+zlib.MAX_WBITS)
如果您打印 jsonData,您将看到所需的 JSON 文件! 如果您在 AWS 本身中运行测试,请务必检查 CloudWatch 日志,因为它在 lambda 中如果太长不会输出完整的 JSON 文件。
如果您的 json 文件如下所示:
{
"test": "test123"
}
您可以dict
这样访问它:
BUCKET="Bucket123"
def get_json_from_s3(key: str):
"""
Retrieves the json file containing responses from s3. returns a dict
Args:
key (str): file path to the json file
Returns:
dict: json style dict
"""
data = client.get_object(Bucket=BUCKET, Key=key)
json_text_bytes = data["Body"].read().decode("utf-8")
json_text = json.loads(json_text_bytes)
return json_text
test_dict = get_json_from_s3(key="test.json")
print(test_dict["test"])
这很容易通过cloudpathlib 实现,它支持 S3 以及 Google Cloud Storage 和 Azure Blob Storage。 这是一个示例:
import json
from cloudpathlib import CloudPath
# first, we'll write some json data so then we can later read it
CloudPath("s3://mybucket/asdf.json").write_text('{"field": "value"}')
#> 18
# read data from S3
data = json.loads(
CloudPath("s3://mybucket/asdf.json").read_text()
)
# look at the data
data
#> {'field': 'value'}
# access it now that it is loaded in Python
data["field"] == "value"
#> True
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.