Home > other >  Lambda - Retrieve tokens from file (Yahoo API)
Lambda - Retrieve tokens from file (Yahoo API)

Time:09-18

I am trying to invoke a Yahoo Fantasy Sports API from Lambda. Per Yahoo's oauth documentation Yahoo's OAuth function expects to load a JSON file containing all of the tokens. This has been no problem on my local machine, where I would just pass the file as an argument. But now that I am migrating to Lambda it is not so simple.

I've tried multiple variations getting the oauth file from s3 (client/resource/bytes/dumps) and passing the contents of the file into the function. Without fail I get the same error message for each approach:

s3x = boto3.client('s3')
o_bucket='mysportss3bucket'
o_path = 'oauth2.json'
resp = s3x.get_object(Bucket=o_bucket, Key = o_path)['Body'].read()
sc = OAuth2(None, None, resp)

TypeError                                 Traceback (most recent call last)
<ipython-input-49-fd439f281ac6> in <module>
      1 print(resp)
----> 2 sc = OAuth2(None, None, resp)

TypeError: __init__() takes 3 positional arguments but 4 were given

I've also attempted storing the JSON file in the Lambda function itself, both in the parent directory and in a tmp directory where I am still getting this error in both scenarios.

{
  "errorMessage": "[Errno 30] Read-only file system: 'tmp/oauth2.json'",
  "errorType": "OSError",
  "requestId": "7f23496c-50fa-4a49-b567-fd6bb66cabbc",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 13, in lambda_handler\n    sc = OAuth2(None, None, from_file=x)\n",
    "  File \"/opt/python/lib/python3.9/site-packages/yahoo_oauth/oauth.py\", line 234, in __init__\n    super(OAuth2, self).__init__('oauth2', consumer_key, consumer_secret, **kwargs)\n",
    "  File \"/opt/python/lib/python3.9/site-packages/yahoo_oauth/oauth.py\", line 100, in __init__\n    write_data(data, vars(self).get('from_file', 'secrets.json'))\n",
    "  File \"/opt/python/lib/python3.9/site-packages/yahoo_oauth/utils.py\", line 41, in write_data\n    return func(data, filename)\n",
    "  File \"/opt/python/lib/python3.9/site-packages/yahoo_oauth/utils.py\", line 46, in json_write_data\n    with open(filename, 'w') as fp:\n"
  ]
}

I'm pretty new to Lambda and have spent several hours troubleshooting so I would greatly appreciate anyone's help. Thank you.

CodePudding user response:

There are a few things going on here. First, /tmp is the only writeable directory in lambda. Second, the s3 contents are of type bytes, not str. Third, you are either passing in from a file, or you can just grab the desired contents from your s3 object. Exploring both:

from_file

s3x = boto3.client('s3')
o_bucket='mysportss3bucket'
o_path = 'oauth2.json'

# write to the temporary file
with open('/tmp/auth.json', 'wb') as fh:
    fh.write(s3x.get_object(Bucket=o_bucket, Key = o_path)['Body'].read())

# pass in that path here
sc = OAuth2(None, None, from_file='/tmp/auth.json')

json parsing

import json

s3x = boto3.client('s3')
o_bucket='mysportss3bucket'
o_path = 'oauth2.json'

# parse into dictionary here
resp = json.loads(
    s3x.get_object(Bucket=o_bucket, Key = o_path)['Body'].read().decode()
)

# pass the required fields here
sc = OAuth2(resp['consumer_key'], resp['consumer_secret'])
  • Related