Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
724 views
in Technique[技术] by (71.8m points)

oauth 2.0 - How to bypass entering authentication code to authorize my code everytime I use the YouTube Data API v3

So every time I run my code it gives a link on my terminal that I have to manually press on and choose my Gmail account on browser to login and receive an authorization code. That again I have to paste onto my terminal.

Is there a way to skip this process?

The code I'm using:

# -*- coding: utf-8 -*-

# Sample Python code for youtube.videos.update
# See instructions for running these code samples locally:
# https://developers.google.com/explorer-help/guides/code_samples#python

import os

import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors

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

def main():
    # Disable OAuthlib's HTTPS verification when running locally.
    # *DO NOT* leave this option enabled in production.
    os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"

    api_service_name = "youtube"
    api_version = "v3"

    client_secrets_file = "client_secret_key.json"

    # Get credentials and create an API client
    flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
        client_secrets_file, scopes)
    credentials = flow.run_console()
    youtube = googleapiclient.discovery.build(
        api_service_name, api_version, credentials=credentials)

    request = youtube.videos().update(
        part="id,snippet",
        body={
          "id": "videoid",
          "snippet": {
            "title": "XOXOXO",
            "description": "Through IDE",
            "categoryId": "27"
          }
        }
    )
    response = request.execute()

    print(response)

if __name__ == "__main__":
    main()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Indeed there's the possibility to save your credentials object the first time running successfully an OAuth authorization/authentication flow; then to load the credentials object from that file each time running the program for the n-th time, where n >= 2.

Here is how I recommend to structure your code:

import os, pickle

from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build

def pickle_file_name(
        api_name = 'youtube',
        api_version = 'v3'):
    return f'token_{api_name}_{api_version}.pickle'

def load_credentials(
        api_name = 'youtube',
        api_version = 'v3'):
    pickle_file = pickle_file_name(
        api_name, api_version)

    if not os.path.exists(pickle_file):
        return None

    with open(pickle_file, 'rb') as token:
        return pickle.load(token)

def save_credentials(
        cred, api_name = 'youtube',
        api_version = 'v3'):
    pickle_file = pickle_file_name(
        api_name, api_version)

    with open(pickle_file, 'wb') as token:
        pickle.dump(cred, token)

def create_service(
        client_secret_file, scopes,
        api_name = 'youtube',
        api_version = 'v3'):
    print(client_secret_file, scopes,
        api_name, api_version,
        sep = ', ')

    cred = load_credentials(api_name, api_version)

    if not cred or not cred.valid:
        if cred and cred.expired and cred.refresh_token:
            cred.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                    client_secret_file, scopes)
            cred = flow.run_console()

    save_credentials(cred, api_name, api_version)

    try:
        service = build(api_name, api_version, credentials = cred)
        print(api_name, 'service created successfully')
        return service
    except Exception as e:
        print(api_name, 'service creation failed:', e)
        return None

def main():
    youtube = create_service("client_secret_key.json",
        ["https://www.googleapis.com/auth/youtube.force-ssl"])
    if not youtube: return

    request = youtube.videos().update(
        part="id,snippet",
        body={
          "id": "videoid",
          "snippet": {
            "title": "XOXOXO",
            "description": "Through IDE",
            "categoryId": "27"
          }
        }
    )
    response = request.execute()

    print(response)

if __name__ == '__main__':
    main()

You have to be aware of the following peculiarity of the code above: if you run your script the second time from within a different directory than the one from within you've ran it the first time, the script will reinitiate an OAuth flow when that (current) directory does not contain a credentials pickle file.


Now, if you have installed (or otherwise are willing to install) the package Google Authentication Library for Python, google-auth, version >= 1.21.3 (google-auth v1.3.0 introduced Credentials.from_authorized_user_file, v1.8.0 introduced Credentials.to_json and v1.21.3 fixed this latter function w.r.t. its class' expiry member), then you may have your credentials object saved to and load from a JSON text file.

Here is the code that'll do that:

import os, json, io

...

def json_file_name(
        api_name = 'youtube',
        api_version = 'v3'):
    return f'token_{api_name}_{api_version}.json'

def load_credentials(
        api_name = 'youtube',
        api_version = 'v3'):
    cred_file = json_file_name(
        api_name, api_version)

    if not os.path.exists(cred_file):
        return None

    from google.oauth2.credentials import Credentials
    return Credentials.from_authorized_user_file(cred_file)

def save_credentials(
        cred, api_name = 'youtube',
        api_version = 'v3'):
    cred_file = json_file_name(
        api_name, api_version)

    with io.open(cred_file, 'w', encoding = 'UTF-8') as json_file:
        json_file.write(cred.to_json())

...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...