2

I'm trying to upload a video to Youtube using a python script.

So the code given here (upload_video.py) is supposed to work and I've followed the set up which includes enabling the Youtube API and getting OAuth secret keys and what not. You may notice that the code is in Python 2 so I used 2to3 to make it run with python3.7. The issue is that for some reason, I'm asked to login when I execute upload_video.py:

enter image description here

Now this should not be occuring as that's the whole point of having a client_secrets.json file, that you don't need to explicitly login. So once I exit this in-shell browser, Here's what I see:

enter image description here

Here's the first line:

/usr/lib/python3.7/site-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access upload_video.py-oauth2.json: No such file or directory
  warnings.warn(_MISSING_FILE_MESSAGE.format(filename))

Now I don't understand why upload_video.py-oauth2.json is needed as in the upload_video.py file, the oauth2 secret file is set as "client_secrets.json".

Anyways, I created the file upload_video.py-oauth2.json and copied the contents of client_secrets.json to it. I didn't get the weird login then but I got another error:

Traceback (most recent call last):
  File "upload_video.py", line 177, in <module>
    youtube = get_authenticated_service(args)
  File "upload_video.py", line 80, in get_authenticated_service
    credentials = storage.get()
  File "/usr/lib/python3.7/site-packages/oauth2client/client.py", line 407, in get
    return self.locked_get()
  File "/usr/lib/python3.7/site-packages/oauth2client/file.py", line 54, in locked_get
    credentials = client.Credentials.new_from_json(content)
  File "/usr/lib/python3.7/site-packages/oauth2client/client.py", line 302, in new_from_json
    module_name = data['_module']
KeyError: '_module'

So basically now I've hit a dead end. Any ideas about what to do now?

Ayudh
  • 1,673
  • 1
  • 22
  • 55

1 Answers1

1

See the code of function get_authenticated_service in upload_video.py: you should not create the file upload_video.py-oauth2.json by yourself! This file is created upon the completion of the OAuth2 flow via the call to run_flow within get_authenticated_service.

Also you may read the doc OAuth 2.0 for Mobile & Desktop Apps for thorough info about the authorization flow on standalone computers.

stvar
  • 6,551
  • 2
  • 13
  • 28
  • Yeah I saw that it creates the file but is it supposed to be using sys.argv[0] ? shouldn't it be sys.argv[1] as that is actually the client_secrets.json file? Also, I cannot use a browser to sign in but their docs, while stating that apps that cannot use browers to sign in should use OAuth for mobile & desktop apps, do not actually state how to handle that scenario! – Ayudh Apr 25 '20 at 14:01
  • The name of the local file can be anything but the name of the user-supplied secrets JSON file. The two JSON files -- the one given by the user, and the one generated upon authentication -- have different content! – stvar Apr 25 '20 at 15:26
  • The doc specifies [steps 4](https://developers.google.com/youtube/v3/guides/auth/installed-apps#handlingresponse) and [step 5](https://developers.google.com/youtube/v3/guides/auth/installed-apps#exchange-authorization-code). By the initial OAuth flow, you get two tokens: a short-lived access token and a refresh token that produces access tokens on demand. Go through [this thread](https://stackoverflow.com/q/27771324/8327971) for concrete code. Authentication without browser is not possible, but once having a refresh token, it can be traded programmatically for access tokens. – stvar Apr 25 '20 at 15:51
  • If authentication without browser is not possible using OAuth flow then I'm not going to be exploring this option further. Thanks for your help! – Ayudh Apr 26 '20 at 04:30
  • 1
    There's no other way to upload videos via the API but by the procedure described by those docs. However, before abandoning your pursuit, consider once more the following scenario: (1) *Initialization*: obtain via browser authentication a refresh token; (2) *Iterations*: as many times as needed, query the API for an access token -- without any browser interaction! -- using the refresh token from (1), then proceed further with the call to the target API endpoint (again, without any browser interaction). (An access token can be used for calling the target API endpoint multiple times.) – stvar Apr 26 '20 at 12:41
  • Note that the steps (1) and (2) may well be separated such that (1) is executed by a standalone (local) computer that stores the refresh token into a file; then, later, upon a secure transfer of that file on a different remote computer (e.g. a server that does not have a browser installed), execute (2) on that remote computer, repeatedly as needed. – stvar Apr 26 '20 at 12:51
  • See [Using OAuth 2.0 for server-side, standalone scripts](https://developers.google.com/youtube/v3/guides/moving_to_oauth#standalone). – stvar Apr 26 '20 at 13:10
  • My god, you are absolutely right. I'll look into this later this week. Thanks for your suggestion and guidance! – Ayudh Apr 27 '20 at 06:19