2

The question should be how to upload users video to their youtube channel?

for that i am using youtube api V3 and quick search from google i found below code

client_secrets.json

{
  "web": {
    "client_id": "[[INSERT CLIENT ID HERE]]",
    "client_secret": "[[INSERT CLIENT SECRET HERE]]",
    "redirect_uris": [],
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://accounts.google.com/o/oauth2/token"
  }
}

from the terminal

python upload_video.py --file="/tmp/test_video_file.flv"
                       --title="Summer vacation in California"
                       --description="Had a great time surfing in Santa Cruz"
                       --keywords="surfing,Santa Cruz"
                       --category="22"
                       --privacyStatus="private"

How to upload my video to other channels in youtube API

The complete working sample for the upload_video.py script is listed below:

#!/usr/bin/python

import httplib
import httplib2
import os
import random
import sys
import time

from apiclient.discovery import build
from apiclient.errors import HttpError
from apiclient.http import MediaFileUpload
from oauth2client.file import Storage
from oauth2client.client import flow_from_clientsecrets
from oauth2client.tools import run
from optparse import OptionParser


# Explicitly tell the underlying HTTP transport library not to retry, since
# we are handling retry logic ourselves.
httplib2.RETRIES = 1

# Maximum number of times to retry before giving up.
MAX_RETRIES = 10

# Always retry when these exceptions are raised.
RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, httplib.NotConnected,
  httplib.IncompleteRead, httplib.ImproperConnectionState,
  httplib.CannotSendRequest, httplib.CannotSendHeader,
  httplib.ResponseNotReady, httplib.BadStatusLine)

# Always retry when an apiclient.errors.HttpError with one of these status
# codes is raised.
RETRIABLE_STATUS_CODES = [500, 502, 503, 504]

# CLIENT_SECRETS_FILE, name of a file containing the OAuth 2.0 information for
# this application, including client_id and client_secret. You can acquire an
# ID/secret pair from the API Access tab on the Google APIs Console
#   http://code.google.com/apis/console#access
# For more information about using OAuth2 to access Google APIs, please visit:
#   https://developers.google.com/accounts/docs/OAuth2
# For more information about the client_secrets.json file format, please visit:
#   https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
# Please ensure that you have enabled the YouTube Data API for your project.
CLIENT_SECRETS_FILE = "client_secrets.json"

# A limited OAuth 2 access scope that allows for uploading files, but not other
# types of account access.
YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"

# Helpful message to display if the CLIENT_SECRETS_FILE is missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0

To make this sample run you will need to populate the client_secrets.json file
found at:

   %s

with information from the APIs Console
https://code.google.com/apis/console#access

For more information about the client_secrets.json file format, please visit:
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
                                   CLIENT_SECRETS_FILE))

def get_authenticated_service():
  flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE, scope=YOUTUBE_UPLOAD_SCOPE,
    message=MISSING_CLIENT_SECRETS_MESSAGE)

  storage = Storage("%s-oauth2.json" % sys.argv[0])
  credentials = storage.get()

  if credentials is None or credentials.invalid:
    credentials = run(flow, storage)

  return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
    http=credentials.authorize(httplib2.Http()))


def initialize_upload(options):
  youtube = get_authenticated_service()

  tags = None
  if options.keywords:
    tags = options.keywords.split(",")

  insert_request = youtube.videos().insert(
    part="snippet,status",
    body=dict(
      snippet=dict(
        title=options.title,
        description=options.description,
        tags=tags,
        categoryId=options.category
      ),
      status=dict(
        privacyStatus=options.privacyStatus
      )
    ),
    # chunksize=-1 means that the entire file will be uploaded in a single
    # HTTP request. (If the upload fails, it will still be retried where it
    # left off.) This is usually a best practice, but if you're using Python
    # older than 2.6 or if you're running on App Engine, you should set the
    # chunksize to something like 1024 * 1024 (1 megabyte).
    media_body=MediaFileUpload(options.file, chunksize=-1, resumable=True)
  )

  resumable_upload(insert_request)


def resumable_upload(insert_request):
  response = None
  error = None
  retry = 0
  while response is None:
    try:
      print "Uploading file..."
      status, response = insert_request.next_chunk()
      if 'id' in response:
        print "'%s' (video id: %s) was successfully uploaded." % (
          options.title, response['id'])
      else:
        exit("The upload failed with an unexpected response: %s" % response)
    except HttpError, e:
      if e.resp.status in RETRIABLE_STATUS_CODES:
        error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status,
                                                             e.content)
      else:
        raise
    except RETRIABLE_EXCEPTIONS, e:
      error = "A retriable error occurred: %s" % e

    if error is not None:
      print error
      retry += 1
      if retry > MAX_RETRIES:
        exit("No longer attempting to retry.")

      max_sleep = 2 ** retry
      sleep_seconds = random.random() * max_sleep
      print "Sleeping %f seconds and then retrying..." % sleep_seconds
      time.sleep(sleep_seconds)


if __name__ == '__main__':
  parser = OptionParser()
  parser.add_option("--file", dest="file", help="Video file to upload")
  parser.add_option("--title", dest="title", help="Video title",
    default="Test Title")
  parser.add_option("--description", dest="description",
    help="Video description",
    default="Test Description")
  parser.add_option("--category", dest="category",
    help="Numeric video category. " +
      "See https://developers.google.com/youtube/v3/docs/videoCategories/list",
    default="22")
  parser.add_option("--keywords", dest="keywords",
    help="Video keywords, comma separated", default="")
  parser.add_option("--privacyStatus", dest="privacyStatus",
    help="Video privacy status: public, private or unlisted",
    default="public")
  (options, args) = parser.parse_args()

  if options.file is None or not os.path.exists(options.file):
    exit("Please specify a valid file using the --file= parameter.")
  else:
    initialize_upload(options)

Question 1 :

How to integrate with django view function ?

like when user access localhost:8000/upload page then followed by browse & submit button next google will ask for user credential after successful login video will uploaded to given username youtube channel. For this how to integrate above code to django view funtion

Question 2 :

How to change below command to view

python upload_video.py --file="/tmp/test_video_file.flv"
                           --title="Summer vacation in California"
                           --description="Had a great time surfing in Santa Cruz"
                           --keywords="surfing,Santa Cruz"
                           --category="22"
                           --privacyStatus="private" 
Deeban Babu
  • 729
  • 1
  • 15
  • 49

3 Answers3

2

No way to do it as you can't get the CLIENT SECRET FILE of a user until he gives you

  • client_id
  • client_secret

And here is what google says

Warning: Keep your client secret private. If someone obtains your client secret, they could use it to consume your quota, incur charges against your Google APIs Console project, and request access to user data.

Cherif KAOUA
  • 834
  • 12
  • 21
  • No.. I don't want my user's `CLLIENT SECRET FILE`. I have my client secret file in my own server. All i want is when user click the upload button when file select then followed by the google universal login screen ask for the username and password then file will be push to given username youtube channel – Raja Simon Oct 10 '14 at 04:58
  • 2
    In your case, you must obtain an access token and get autorization token from the user to upload on his behalf check this google api link , it should be resolve this https://developers.google.com/youtube/2.0/developers_guide_protocol_oauth2 – Cherif KAOUA Oct 10 '14 at 10:47
  • Like the answer states doing this using the Google provided API and a JSON file for storing the data is the wrong way to go about this. You should store the client_id and client_secret (provided by Google) in the database or in the Django settings file. You then need to provide a view (or use one of the libraries I suggested above) that takes these values and performs an OAuth handshake, this will give you an access_token you can use to post videos as the user (as they have now given you permission to do so). – xxx Oct 15 '14 at 16:18
1

You will almost certainly find it easier using a library like python-social-auth or django-allauth, personally I'd use python-social-auth but as you seem to be just starting out with Django use django-allauth.

https://github.com/pennersr/django-allauth

There is a good tutorial that will take you through it:

http://www.sarahhagstrom.com/2013/09/the-missing-django-allauth-tutorial/

As for turning that script into a view, just call it from inside any django view, you should check to see if the user is logged into Google, if they are then use the access token stored in the database. If not you should redirect them to the Google login url pattern provide by django-allauth.

xxx
  • 1,465
  • 1
  • 14
  • 23
  • so far i tried and now it's almost working, can you tell sometime i am getting ' invalid_grant` – Raja Simon Oct 15 '14 at 15:57
  • This might be related: http://stackoverflow.com/questions/10576386/invalid-grant-trying-to-get-oauth-token-from-google can you provide some more information. When are you getting these errors, what have you tried? – xxx Oct 15 '14 at 16:04
  • yes i looked.. seems created json file `"refresh_token": null,` only.. i don't know how to get that.. – Raja Simon Oct 15 '14 at 16:12
0

Save your upload_video.py file into your video app.

In your view.py try following the post of the form:

form_upload = VideoForm(request.POST, request.FILES)

    if form_upload.is_valid():
        uploaded_video = form_upload.save(commit=True)

        # send this file to youtube
        credentials = get_authenticated_service(uploaded_video)
        initialize_upload(credentials, uploaded_video)

In your videos models.py

file_on_server = models.FileField(max_length=100, null=True, blank=True)

    auth_host_name = 'localhost'
    noauth_local_webserver = True
    auth_host_port = [8080, 8090]
    logging_level = 'ERROR'
    category = 23
    privacyStatus = 'public'

    @property
    def file(self):
        return self.file_on_server.path

Under the Google Developer Console:

  • Create a Google OAuth Client ID for native application not web application.
  • Download JSON to your video app.

Once submitted you should get the following message in your console:

Uploading file...
Video id '' was successfully uploaded.
Ronnie
  • 992
  • 1
  • 9
  • 25
Yannick
  • 3,553
  • 9
  • 43
  • 60