I’ll try to respond to every comment in case you have any doubts. But, please read each and every line carefully.
Now, this is very popular these days.
Everyone is having an automated YouTube Channel.
But No-Body wants to give away their codebase.
But as always, here we are giving you this for freeeeeee :)
Step: Set Up Your Google Cloud Account
(And yes, it’s free!)
- Log in to your Google Cloud Console using the same Google/YouTube account.
2. Click on New Project and create one with a name of your choice.

3. Click CREATE

4. Select your newly created project.

5. Search for Enabled APIs and Services,
and click + Enable APIs and Services.

6. Enable the YouTube Data API v3.

7. You’ll see a green tick once it’s enabled.
Step: Set Up OAuth Consent Screen

Go to OAuth Consent Screen in your Google Cloud Console.
- Set User Type to External.
Fill in:
- App Name: Any name of your choice.
- User Support Email and Developer Contact Email: Same as your YouTube/Google email.
- Skip the scopes section.
- In the Add Users section, add the same email as above.
- Click Save and Continue.
Step: Create Credentials

Go to Credentials and create a new credential:
- Application Type: Desktop App.
- Name it (e.g., “Client 1” like me).
- Download the JSON file and save it as
client_secret.jsonon your local system.
Disclaimer: You can use this to automate the upload only for one long form video or 4–5 shorts per ‘day’ in the free tier.
Step: Install Required Libraries
Now, let’s install your libraries to download this:
The requirements.txt file:
google-api-python-client
oauth2client
httplib2
pytz
pandasRun the following command to install them:
pip install -r requirements.txtNow,
def getYoutubeService():
credentials = authorize_credentials()
http = credentials.authorize(httplib2.Http())
discoveryUrl = ('https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest')
service = discovery.build('youtube', 'v3', http=http, discoveryServiceUrl=discoveryUrl)
return serviceis needed to authorize.
What will it do? It will first authenticate this on the browser and then it will store a credentials.storage file on the server and you do not need to authenticate forever :)
Let’s add everything in the final code —
Annnnd here is the final code:
from googleapiclient.errors import HttpError
from googleapiclient.http import MediaFileUpload
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run_flow
from googleapiclient import discovery
import httplib2
from datetime import datetime, timedelta
import pytz
def getScheduleDateTime(days=0):
# Set the publish time to 2 PM Eastern Time (US) on the next day
eastern_tz = pytz.timezone('America/Los_Angeles')
publish_time = datetime.now(eastern_tz)
if days > 0:
publish_time = datetime.now(eastern_tz) + timedelta(days)
publish_time = publish_time.replace(hour=14, minute=0, second=0, microsecond=0)
# Set the publish time in the UTC timezone
publish_time_utc = publish_time.astimezone(pytz.utc).strftime('%Y-%m-%dT%H:%M:%S.%fZ')
return publish_time_utc
# Start the OAuth flow to retrieve credentials
def authorize_credentials():
CLIENT_SECRET = 'client_secret.json'
SCOPE = 'https://www.googleapis.com/auth/youtube'
STORAGE = Storage('credentials.storage')
# Fetch credentials from storage
credentials = STORAGE.get()
# If the credentials doesn't exist in the storage location then run the flow
if credentials is None or credentials.invalid:
flow = flow_from_clientsecrets(CLIENT_SECRET, scope=SCOPE)
http = httplib2.Http()
credentials = run_flow(flow, STORAGE, http=http)
return credentials
def getYoutubeService():
credentials = authorize_credentials()
http = credentials.authorize(httplib2.Http())
discoveryUrl = ('https://www.googleapis.com/discovery/v1/apis/youtube/v3/rest')
service = discovery.build('youtube', 'v3', http=http, discoveryServiceUrl=discoveryUrl)
return service
def upload_video(file_path, title, description='', tags=[], privacy_status='public', day=0):
print("Uploading...")
print(f"File Path: {file_path}")
print(f"Title: {title}")
print(f"Description: {description}")
print(f"Privacy Status: {privacy_status}")
print(f"Day: {day}")
print(title)
youtube = getYoutubeService()
try:
# Define the video resource object
body = {
'snippet': {
'title': title,
'description': description,
'tags': tags,
},
'status': {
'privacyStatus': privacy_status
}
}
if privacy_status == 'private':
body['status']['publishAt'] = getScheduleDateTime(day)
# Define the media file object
media_file = MediaFileUpload(file_path)
print(body)
# Call the API's videos.insert method to upload the video
videos = youtube.videos()
response = videos.insert(
part='snippet,status',
body=body,
media_body=media_file
).execute()
# Print the response after the video has been uploaded
print('Video uploaded successfully!\n')
print(f'Title: {response["snippet"]["title"]}')
print(f'URL: https://www.youtube.com/watch?v={response["id"]}')
except HttpError as e:
# print(f'An HTTP error {error.resp.status} occurred:\n{error.content}')
raise Exception(f"An HTTP error {e.resp.status} occurred: {e.content.decode('utf-8')}")
Example use:
vid_path = 'countdown_timer_9_16.mp4'
upload_video(vid_path, 'Timer of 10 sec #shorts', description='#shorts')Self-Promotion:
In case you don’t want to set this up yourself, I can always help here for a nominal fee
In case you don’t have a free server, I can set that up for you for free here for a one time nominal fee
Enjoyed the read? You can support my writing journey here — Buy me a coffee?
In case we are meeting for the first time, come over here, it’ll be worth the roller coaster of articles that are gonna come up in the next few weeks.
You might also like: