Iβm using the Google Drive API for a project, which now I want to move to Streamlit.
I was using a client_secrets.json
to create the API service using a function provided by Google:
CLIENT_SECRET_FILE = 'client_secrets.json' # π JSON File with the API KEY and other config stuff
API_NAME = 'drive'
API_VERSION = 'v3'
SCOPES = ['https://www.googleapis.com/auth/drive']
#This function expects a json file/route as the "CLIENT_SECRET_FILE" parameter π
service = Create_Service(CLIENT_SECRET_FILE, API_NAME, API_VERSION, SCOPES)
I know about the secrets.toml
and already created it using the content of the client_secrets.json
.
Now, when I declare
CLIENT_SECRET_FILE = st.secrets['something']
#or
CLIENT_SECRET_FILE = st.secrets
I get this error:
with open(client_secrets_file, "r") as json_file:
TypeError: expected str, bytes or os.PathLike object, not Secrets
How can I use the Create_Service()
function using TOML instead of JSON?
Thanks for your help!!!
Hi @gmepscon, welcome to the Streamlit community!
In this case, when you are using the secrets functionality, you often need to change the authentication method. For example, in this example where we show how to connect Streamlit to a private Google Sheet, there is a method service_account.Credentials.from_service_account_info
where you can pass the values in, rather than a JSON file.
If you can post the code or the library you are using, I can quickly look at the Google library documentation and suggest what function it might be.
Best,
Randy
2 Likes
Hello @randyzwitch ! Thank you for your answer, I appreciate it!!
I actually got that working, but another error came up when I tried to deploy the app:
I think itβs got something to do about not running it on the local server anymore. This is the function that contains the error:
def Create_Service(client_secret_file, api_name, api_version, *scopes):
print(client_secret_file, api_name, api_version, scopes, sep='-')
CLIENT_SECRET_FILE = client_secret_file
API_SERVICE_NAME = api_name
API_VERSION = api_version
SCOPES = [scope for scope in scopes[0]]
print(SCOPES)
cred = None
pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle'
# print(pickle_file)
if os.path.exists(pickle_file):
with open(pickle_file, 'rb') as token:
cred = pickle.load(token)
if not cred or not cred.valid:
if cred and cred.expired and cred.refresh_token:
cred.refresh(Request())
else:
# βThis was solved the original question of my forum post (using .from_client_config)
# flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES)
flow = InstalledAppFlow.from_client_config(CLIENT_SECRET_FILE, SCOPES)
# βπβ π
cred = flow.run_local_server() # Where I think the new error is originating:
# βββ π
with open(pickle_file, 'wb') as token:
pickle.dump(cred, token)
try:
service = build(API_SERVICE_NAME, API_VERSION, credentials=cred)
print(API_SERVICE_NAME, 'service created successfully')
return service
except Exception as e:
print('Unable to connect.')
print(e)
return None
Any ideas on how I might fix this???
Thank you Randy, you are awesome!!
@randyzwitch I am experiencing a similar problem. I am unsure how to adapt my code to have my streamlit app download a Google Drive Folder. I am using this library for a Google-Drive-Folder-Downloader. Can you let me know how to modify this code to make it work for Streamlit?