I’m sure this is pretty simple, but can’t figure it out… I need to authenticate with Google Cloud Platform to access storage buckets using google-cloud-storage (which has been confirmed as installed).
I would typically use a service account and a key file (with appropriately designated permissions), stored e.g. locally for local application development. The code to authenticate and instantiate a GCS client would then be:
import os
from google.cloud import storage
project_id = 'MY_PROJECT_ID'
os.environ["MY_GOOGLE_APPLICATION_CREDENTIALS"] = "MY_PATH_TO_CREDENTIALS/credentials_file.json"
gcs_client = storage.Client(project=project_id)
I know that I want to use the App Secrets service, but I’m not sure exactly what the best pattern would be… do I need to copy and paste the JSON string from the file into the service or should I upload the file to a specific location and give Anvil access to that?
import os.path
if not os.path.exists("/tmp/creds.json"):
with open("/tmp/creds.json", "w") as f:
f.write(anvil.secrets.get_secret("google_creds"))
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "/tmp/creds.json"
…but the Google SDK almost certainly has a way to configure authentication more cleanly than writing it out to a file and then slurping it in. (I just had a look, but I didn’t find anything – Google developer documentation deeply painful to navigate, though, so I might have just missed something.)
OK, I just got around to testing this and am getting the following error when I set the value of the google_creds secret to the JSON (which is valid JSON according to e.g. https://jsonlint.com/):
DefaultCredentialsError: ('File /tmp/creds.json is not a valid json file.', JSONDecodeError('Expecting value: line 1 column 1 (char 0)'))
Which seems to indicate that the first character of the value is not valid JSON. (Obfuscated) JSON is:
Are you sure you pasted the JSON character-for-character correctly into the Secrets Service configuration?
Could you try printing the contents of the JSON file from your app to the logs? Something like:
with open("/tmp/creds.json", "rb") as f:
print(f.read())
(Or even using anvil.media.from_file('/tmp/creds.json') to get the file as a Media object, then making it downloadable as a Link, so you can check you wrote the file correctly?)
Thanks for getting back so quickly. I have printed this to the output and it doesn’t look truncated - it is the valid JSON file wrapped in b’{valid_json}’ as a bytes string