IntegrationsIntermediate

How to Upload a Video to YouTube with Python and the Data API

Use the official Google API client for Python to authenticate once and upload an MP4 to your channel from a script.

11 minIntermediate

If you render or edit videos in a pipeline, uploading by hand is the slow part. This guide uploads a finished MP4 straight to your channel with a short Python script using the resumable upload endpoint, so even large files survive a flaky connection.

What you need

  • Python 3.9 or newer installed
  • A client_secret.json from the Get a YouTube Data API Key guide
  • An MP4 file ready to publish
  • Terminal access to run pip and the script

Step 1: Install the client libraries

The Google API Python client handles the request signing, and the auth libraries handle the OAuth dance for you.

zsh — youtube-upload
$pip install google-api-python-client google-auth-oauthlib google-auth-httplib2
Successfully installed google-api-python-client-2.x ...
$

Step 2: Write the upload script

The script runs the OAuth flow on first launch (opening a browser to grant access), caches the token to token.json, then uploads with a MediaFileUpload set to resumable.

upload.py
import os
from google_auth_oauthlib.flow import InstalledAppFlow
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload

SCOPES = ["https://www.googleapis.com/auth/youtube.force-ssl"]

def service():
    if os.path.exists("token.json"):
        creds = Credentials.from_authorized_user_file("token.json", SCOPES)
    else:
        flow = InstalledAppFlow.from_client_secrets_file("client_secret.json", SCOPES)
        creds = flow.run_local_server(port=0)
        open("token.json", "w").write(creds.to_json())
    return build("youtube", "v3", credentials=creds)

def upload(path):
    body = {
        "snippet": {
            "title": "My automated upload",
            "description": "Uploaded via the YouTube Data API.",
            "tags": ["automation", "api"],
            "categoryId": "22",
        },
        "status": {"privacyStatus": "private"},
    }
    media = MediaFileUpload(path, chunksize=-1, resumable=True)
    req = service().videos().insert(part="snippet,status", body=body, media_body=media)
    res = None
    while res is None:
        status, res = req.next_chunk()
        if status:
            print(f"{int(status.progress() * 100)}%")
    print("Done. Video id:", res["id"])

if __name__ == "__main__":
    upload("final.mp4")

Step 3: Run it and authorize

The first run opens your browser. Sign in with the channel owner account, accept the consent screen (the unverified app warning is fine for your own test user), and the script writes token.json so later runs skip the prompt.

zsh — youtube-upload
$python upload.py
browser opens for consent on first run only
0%
47%
100%
Done. Video id: dQw4w9WgXcQ
$
YouTube Studio — Content
Video Visibility Date
------------------------------------------
My automated upload Private just now
Last week's stream Public 7 days ago
The uploaded video appears as Private until you publish it.
Stay private until checked
Set privacyStatus to private during testing. Switch to public (or scheduled with a publishAt timestamp) only once you have confirmed the title, thumbnail, and captions are right.

Result

Running python upload.py final.mp4 now pushes a video to your channel and prints its video id, which you can feed into other steps like setting a thumbnail or adding captions.

Watch related tutorials

Tags
#youtube#python#upload#api#oauth