Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GSpread pass credentials from Python not JSON

Im using GSpread trying to pass the content on my JSON file (Google API Service Application credentials) as a python Dictionary on my script. Im trying to not to carry a json file wherever I take my script.

I get the following error when I tried to pass a dictionary instead of a json file on the following line:

credentials = ServiceAccountCredentials.from_json_keyfile_name(auth_gdrive(), scope)

TypeError: expected str, bytes or os.PathLike object, not set

### auth_gdrive() returns a dictionary like this:

def auth_gdrive():
    dic = {
        "type": "miauuuuuu",
        "pass": "miauuuu"
    }

Im not allow to show whats really in the dic.

like image 866
Alvaro Lamadrid Avatar asked Jan 28 '23 10:01

Alvaro Lamadrid


2 Answers

Since I wanted to pass the credentials details from within my application , and not from a json file I couldn't use:

ServiceAccountCredentials.from_json_keyfile_name()

from_json_keyfile_name() expects a json file. But looking into the docs I found the following:

ServiceAccountCredentials.from_json_keyfile_dict()

This will expect an dict object , this is all I needed.

Link:

https://oauth2client.readthedocs.io/en/latest/source/oauth2client.service_account.html

Thank you everyone again

like image 109
Alvaro Lamadrid Avatar answered Jan 29 '23 22:01

Alvaro Lamadrid


Additional tip: I am using Google API to read Google Drive files, but also using AWS. I stored the service account credentials in AWS Secrets Manager, so that I did not need a file. I copy-pasted each key-value pair from the downloaded JSON file into AWS Secrets Manager. But I kept getting the error:

Traceback (most recent call last):
  File "./copy_from_google_drive_to_s3.py", line 301, in <module>
    sys.exit(main())
  File "./copy_from_google_drive_to_s3.py", line 96, in main
    keyfile_dict=keyDict, scopes=scopes,
  File "/usr/local/lib/python3.7/site-packages/oauth2client/service_account.py", line 253, in from_json_keyfile_dict
    revoke_uri=revoke_uri)
  File "/usr/local/lib/python3.7/site-packages/oauth2client/service_account.py", line 185, in _from_parsed_json_keyfile
    signer = crypt.Signer.from_string(private_key_pkcs8_pem)
  File "/usr/local/lib/python3.7/site-packages/oauth2client/_pure_python_crypt.py", line 182, in from_string
    raise ValueError('No key could be detected.')
ValueError: No key could be detected.

I had to convert the string representation of newline back into newline:

# Last part of using AWS Secrets Manager, returns json string.
sa_creds = get_secret_value_response['SecretString']
# Convert JSON string to dict.
sa_creds = json.loads(sa_creds)
# In the private key, 1-char newline got replaced with 2-char '\n'
sa_creds['private_key'] = sa_creds['private_key'].replace('\\n', '\n')
credentials = ServiceAccountCredentials.from_json_keyfile_dict(
    keyfile_dict=sa_creds,
    scopes=['https://www.googleapis.com/auth/drive.readonly',]
)
like image 24
Bob McCormick Avatar answered Jan 29 '23 23:01

Bob McCormick