Here is my code that I am trying to run without errors. I was having troubles with the Oauth in Streamlit since it’s a headless server, but got this to at least give me the link to go to in order to perform the Oauth. Once access is granted though the app does not continue to process the info already input and I get a 403 Error. The project number in the error also does not match my cloud-console project for the API. But in my project I do have the YouTube Data api enabled.
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://youtube.googleapis.com/youtube/v3/channels?part=brandingSettings%2CcontentDetails%2CcontentOwnerDetails%2Cid%2Clocalizations%2Csnippet%2Cstatistics%2Cstatus%2CtopicDetails&id=UCz4LzmevHDOY4dFiHw9I-kQ&alt=json returned “YouTube Data API v3 has not been used in project 868231854759 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=868231854759 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.”. Details: “[{‘message’: ‘YouTube Data API v3 has not been used in project XXXXXXXXXXXXXX before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/youtube.googleapis.com/overview?project=868231854759 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.’, ‘domain’: ‘usageLimits’, ‘reason’: ‘accessNotConfigured’, ‘extendedHelp’: ‘https://console.developers.google.com’}]”>
import streamlit as st
import googleapiclient.discovery
import pandas as pd
from google.oauth2 import service_account
from google_auth_oauthlib.flow import Flow
# My Modules
from extract_channel_info import extract_info
# Define the scopes you need to access
SCOPES = ['https://www.googleapis.com/auth/youtube.readonly']
def authorize():
# Create a flow instance using the client ID and client secret obtained from the Google Developers Console
flow = Flow.from_client_secrets_file(
'client_secrets.json', # Replace this with the path to your client secret JSON file
scopes=SCOPES,
redirect_uri='https://concordmusic.streamlit.app'
)
# Construct the authorization URL
auth_url, _ = flow.authorization_url(prompt="consent")
# Print the authorization URL and prompt the user to visit it
st.write("Please visit this URL to authorize access:", auth_url)
# Ask the user to enter the authorization code obtained after authorizing access
authorization_code = st.text_input("Enter the authorization code: ")
# Check if the authorization code has been provided
if authorization_code:
# Fetch the access token using the authorization code
flow.fetch_token(code=authorization_code)
# Get the credentials
credentials = flow.credentials
return credentials
else:
st.write("Authorization code is required.")
def get_authenticated_service():
# Authorize and get the credentials
credentials = authorize()
# Build the YouTube Data API service
service = googleapiclient.discovery.build('youtube', 'v3', credentials=credentials)
return service
def get_single_channel_info():
channel_id = st.text_input("What is the Channel ID?")
filename = st.text_input("Output File Name:")
if st.button("Perform Call"):
# Check if either input field is blank
if not channel_id or not filename:
st.warning("Both Channel ID and Output File Name are required.")
return # Stop further execution
st.write("Running your request now...")
# Authenticate and get the service
service = get_authenticated_service()
channel_info_list = []
request = service.channels().list(
part="brandingSettings,contentDetails,contentOwnerDetails,id,localizations,snippet,statistics,status,topicDetails",
id=channel_id
)
response = request.execute()
if "items" in response:
for item in response["items"]:
channel_info = extract_info(item)
channel_info_list.append(channel_info)
# Create a DataFrame from the video information
df = pd.DataFrame(channel_info_list)
if filename:
# Ensure file name ends with ".xlsx"
if not filename.endswith(".xlsx"):
filename += ".xlsx"
# Save the DataFrame to an Excel file
df.to_excel(filename, index=False, engine="openpyxl")
st.write("Results have been saved to", filename)
# Provide a download button for the output file
with open(filename, 'rb') as file:
file_content = file.read()
st.download_button(label="Download Excel File", data=file_content, key='download_excel', file_name=filename)
print(f"Channel info saved to {filename}")
if __name__ == "__main__":
get_single_channel_info()