【问题标题】:Reading an JSON file from S3 using Python boto3使用 Python boto3 从 S3 读取 JSON 文件
【发布时间】:2017-04-21 02:03:08
【问题描述】:

我一直在 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
  • @AlexHall 最初我尝试删除 repr ,但它没有用,它给出了 ValueError: Expecting property name included in double quotes
  • 我解决了这个问题.. JSON 应该有用双引号括起来的属性.. 我改变了我的 json 格式
  • 您在哪一行出现错误?把那条线分开。 file_content = content_object... 是一行 4 步。现在,将其分成 4 个单独的行,其中包含 4 个中间变量。然后看看哪一行失败。
  • 我的问题只需要 '.read().decode('utf-8')' 所以谢谢你的提问 (-;

标签: python json amazon-web-services amazon-s3 boto3


【解决方案1】:

您可以在 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)

【讨论】:

    【解决方案2】:

    以下对我有用。

    # read_s3.py
    import boto3
    BUCKET = 'MY_S3_BUCKET_NAME'
    FILE_TO_READ = 'FOLDER_PATH/my_file.json'
    client = boto3.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 凭证:

    import json
    credentials = json.load(open('aws_cred.json'))
    client = boto3.client('s3',
                           aws_access_key_id=credentials['MY_AWS_KEY_ID'],
                           aws_secret_access_key=credentials['MY_AWS_SECRET_ACCESS_KEY']
                         )
    

    (2) 从您的环境变量中读取(我的首选部署选项):

    import os
    client = boto3.client('s3',
                           aws_access_key_id=os.environ['MY_AWS_KEY_ID'],
                           aws_secret_access_key=os.environ['MY_AWS_SECRET_ACCESS_KEY']
                         )
    

    让我们准备一个shell脚本(set_env.sh)来设置环境变量并添加我们的python脚本(read_s3.py)如下:

    # set_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 set_env.sh
    

    【讨论】:

    • 您无需在客户端初始化时指定凭证,它由 boto3 和其他 AWS 开发工具包自动处理。这允许用户以他们选择的任何方式自动进行身份验证(可以是 IAM 角色)
    【解决方案3】:

    想补充一点,botocore.response.streamingbodyjson.load 配合得很好:

    import json
    import boto3
    
    s3 = boto3.resource('s3')
    
    obj = s3.Object(bucket, key)
    data = json.load(obj.get()['Body']) 
    

    【讨论】:

    • 注意:json.loads(带 s)在这里不起作用
    【解决方案4】:

    由于解码对我不起作用(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 文件。

    【讨论】:

      【解决方案5】:

      正如上面 cmets 中提到的,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
      

      【讨论】:

      猜你喜欢
      • 2021-05-22
      • 1970-01-01
      • 2017-09-29
      • 1970-01-01
      • 2019-05-02
      • 2019-09-07
      • 2016-07-12
      • 2021-12-28
      • 1970-01-01
      相关资源
      最近更新 更多