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-by-Step Guide: How To Set Up Python YouTube Upload Automation For Free
Photo by Mohammad Rahmani on Unsplash

Not a Member? I got you.

Step: Set Up Your Google Cloud Account

(And yes, it’s free!)

  1. 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.

Screenshot By Author

3. Click CREATE

Screenshot By Author

4. Select your newly created project.

Screenshot By Author

5. Search for Enabled APIs and Services,

and click + Enable APIs and Services.

Screenshot by Author

6. Enable the YouTube Data API v3.

Screenshot by Author

7. You’ll see a green tick once it’s enabled.

Step: Set Up OAuth Consent Screen

Screenshot By Author

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

Screenshot By Author

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.json on 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
pandas

Run the following command to install them:

pip install -r requirements.txt

Now,

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

is 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:

https://medium.com/long-sweet-valuable/how-i-make-250-a-month-from-the-most-basic-automation-on-youtube-80be0c35931b