pythonjson

How to read into JSON with Python? OSError: [Errno 36] File name too long:


I am using CircleCI,my credentilas are decoded at this step

echo 'export SERVICE_ACCOUNT_DECODED="$(echo $SERVICE_ACCOUNT | base64 -di)"' >> $BASH_ENV

Later I am using Python code

service_account_file = json.dumps(os.environ['SERVICE_ACCOUNT_DECODED'])
    # Authenticate using the service account for Google Drive
credentials = service_account.Credentials.from_service_account_file(service_account_file, scopes=SCOPES)

My goal is that service_account_file is JSON.

but got error

  File "final_script.py", line 28, in <module>
    credentials = service_account.Credentials.from_service_account_file(service_account_file, scopes=SCOPES)
  File "/home/circleci/.pyenv/versions/3.8.20/lib/python3.8/site-packages/google/oauth2/service_account.py", line 260, in from_service_account_file
    info, signer = _service_account_info.from_filename(
  File "/home/circleci/.pyenv/versions/3.8.20/lib/python3.8/site-packages/google/auth/_service_account_info.py", line 78, in from_filename
    with io.open(filename, "r", encoding="utf-8") as json_file:
OSError: [Errno 36] File name too long: '"{\\n

I tried json.loads before but it did not work also.

How to fix this?


Solution

  • You are trying to pass a JSON string containing the credentials to a function which expects the filename of a JSON file containing the credentials.

    From the documentation, we can see in the second example provided that there also is another function for creating a Credentials object which is suitable for your case:

    Or if you already have the service account file loaded:

    service_account_info = json.load(open('service_account.json'))
    credentials = service_account.Credentials.from_service_account_info(
        service_account_info)
    

    The SERVICE_ACCOUNT_DECODED already is a JSON string. You should not be using json.dumps on it again (which is used to convert Python objects to JSON, so you would get a JSON string containing another JSON string).

    Instead, use json.loads to unpack the contents from the string, which correspond to service_account_info above:

    service_account_info = json.loads(os.environ['SERVICE_ACCOUNT_DECODED'])
    credentials = service_account.Credentials.from_service_account_info(
        service_account_info, scopes=SCOPES
    )