代码之家  ›  专栏  ›  技术社区  ›  Mark

如何使用python从aws lambda检索格式良好的json

  •  2
  • Mark  · 技术社区  · 7 年前

    我在aws lambda中有一个函数,它连接到twitter api并返回与我通过事件提供的特定搜索查询匹配的tweets。下面是函数的简化版本。我有几个助手函数 get_secret 管理api密钥和 process_tweet 它限制了返回的数据,并将创建日期转换为字符串。最终的结果是我应该得到一份字典列表。

    def lambda_handler(event, context):
        twitter_secret = get_secret("twitter")
    
        auth = tweepy.OAuthHandler(twitter_secret['api-key'],
                                   twitter_secret['api-secret'])
        auth.set_access_token(twitter_secret['access-key'],
                              twitter_secret['access-secret'])
        api = tweepy.API(auth)
    
        cursor = tweepy.Cursor(api.search,
                               q=event['search'],
                               include_entities=True,
                               tweet_mode='extended',
                               lang='en')
    
        tweets = list(cursor.items())
        tweets = [process_tweet(t) for t in tweets if not t.retweeted]
    
        return json.dumps({"tweets": tweets})
    

    在我的桌面上,我有调用lambda函数的代码。

    aws_lambda = boto3.client('lambda', region_name="us-east-1")
    payload = {"search": "paint%20protection%20film filter:safe"}
    lambda_response = aws_lambda.invoke(FunctionName="twitter-searcher",
                                        InvocationType="RequestResponse",
                                        Payload=json.dumps(payload))
    results = lambda_response['Payload'].read()
    tweets = results.decode('utf-8')
    

    问题是 json.dumps 通过lambda的输出和python的有效负载读取,数据变得异常糟糕。例如,换行符应该是 \n 变成 \\\\n ,所有双引号存储为 \\" Unicode字符的前缀都是 \\ . 所以,一切都被逃脱了,当它收到了我的桌面上的Python与逃逸字符被逃脱。考虑返回的列表中的元素(手动格式)。

    '{\\"userid\\": 190764134,
      \\"username\\": \\"CapitalGMC\\",
      \\"created\\": \\"2018-09-02 15:00:00\\",
      \\"tweetid\\": 1036267504673337344,
      \\"text\\": \\"Protect your vehicle\'s paint! Find out how on this week\'s blog.
                  \\\\ud83d\\\\udc47\\\\n\\\\nhttps://url/XYMxPhVhdH https://url/mFL2Zv8nWW\\"}'
    

    我可以用正则表达式来解决一些问题( \n )但是unicode很棘手,因为即使我匹配它,我如何用正确转义的字符替换它?当我在R中使用 aws.lambda 包裹,一切都很好,没有奇怪的逃走。

    在我的桌面上,aws lambda的响应混淆了数据,我做错了什么?

    更新

    处理tweet功能如下。它只是从字面上提取出我想保留的位,将datetime对象格式化为字符串并返回字典。

    def process_tweet(tweet):
        bundle = {
            "userid": tweet.user.id,
            "username": tweet.user.screen_name,
            "created": str(tweet.created_at),
            "tweetid": tweet.id,
            "text": tweet.full_text
        }
        return bundle
    

    仅供参考,r中的代码如下所示。

    payload = list(search="paint%20protection%20film filter:safe")
    results = aws.lambda::invoke_function("twitter-searcher"
                                          ,payload = jsonlite::toJSON(payload
                                                                  ,auto_unbox=TRUE)
                                          ,type = "RequestResponse"
                                          ,key = creds$key
                                          ,secret = creds$secret
                                          ,session_token = creds$session_token
                                          ,region = creds$region)
    tweets = jsonlite::fromJSON(results)
    str(tweets)
    
    #> 'data.frame':    133 obs. of  5 variables:
    #>  $ userid  : num  2231994854 407106716 33553091 7778772 782310 ...
    #>  $ username: chr  "adaniel_080213" "Prestige_AdamL" "exclusivedetail" "tedhu" ...
    #>  $ created : chr  "2018-09-12 14:07:09" "2018-09-12 11:31:56" "2018-09-12 10:46:55" "2018-09-12 07:27:49" ...
    #>  $ tweetid : num  1039878080968323072 1039839019989983232 1039827690151444480 1039777586975526912 1039699310382931968 ...
    #>  $ text    : chr  "I liked a @YouTube video https://url/97sRShN4pM Tesla Model 3 - Front End Package - Suntek Ultra Paint Protection Film" "Another #Corvette #ZO6 full body clearbra wrap completed using @xpeltech ultimate plus PPF ... Paint protection"| __truncated__ "We recently protected this Tesla Model 3 with Paint Protection Film and Ceramic Coating.#teslamodel3 #charlotte"| __truncated__ "Tesla Model 3 - Front End Package - Suntek Ultra Paint Protection Film https://url/AD1cl5dNX3" ...
    
    tweets[131,]
    #>        userid   username             created             tweetid
    #> 131 190764134 CapitalGMC 2018-09-02 15:00:00 1036267504673337344
    #>          text
    #> 131 Protect your vehicle's paint! Find out how on this week's blog.👇\n\nhttps://url/XYMxPhVhdH https://url/mFL2Zv8nWW
    
    0 回复  |  直到 7 年前
        1
  •  2
  •   Richard    7 年前

    在lambda函数中,应该返回响应体中带有json对象的响应对象。

    # Lambda Function
    def get_json(event, context):
        """Retrieve JSON from server."""
        # Business Logic Goes Here.
        response = {
            "statusCode": 200,
            "headers": {},
            "body": json.dumps({
                "message": "This is the message in a JSON object."
            })
        return response
    }