Youtube API - terminal attempt to open the browser and fails - python

I'm trying to build a project using Youtube's API and Python3.
As mentioned in the Quick Start guide:
The sample attempts to open a new window or tab in your default browser. If this fails, copy the URL from the console and manually open it in your browser.
I'm using MacOS Terminal which runs the script but I really do need to copy the URL into my browser.
I guess the problem is in my machine, and I'd like to find a solution how to fix it, as it would be faster and easier, each and every time I run the script.
I've tried to find similar thread, with no luck.
If anyone can guide my through, or send me a link, for how to solve this problem.
Thanks,
Yoav.

You need a BROWSER environment variable set. This points to the location of the browser.
Use getenv BROWSER to see if it is already set
*Command may be different depending on version of Mac OS

Solution (source):
I've used the run_console() which don't attempt to run the browser, but ask for the client to open it manually.
To make it run the browser automatically, you should use run_local_server() method as shown in the example below.
The run_console function instructs the user to open the authorization
URL in their browser. After the user authorizes the application, the
authorization server displays a web page with an authorization code,
which the user then pastes into the application. The authorization
library automatically exchanges the code for an access token.
credentials = flow.run_console()
The run_local_server function attempts to open the authorization URL in the user's browser. It also
starts a local web server to listen for the authorization response.
After the user completes the auth flow, the authorization server
redirects the user's browser to the local web server. That server gets
the authorization code from the browser and shuts down, then exchanges
the code for an access token.
credentials = flow.run_local_server(host='localhost',
> port=8080,
> authorization_prompt_message='Please visit this URL: {url}',
> success_message='The auth flow is complete; you may close this window.',
> open_browser=True)
Thank you #Hassan Voyeau for the help.

Related

Python requests - how to perform SAML SSO login (to login.microsoft.com for example)?

First of all, I googled this question but found some generic explanations which didn't provide me with good understanding how to do things.
Second - I'm a valid system user (not admin) and have access to the data. I.e. I have valid user credentials and may download file manually but for small automation I would like to have it downloaded by python script from my PC.
The download itself is simple, the only thing - I need to provide a valid session id cookie with request. I.e. finally I need to get this cookie by easiest way.
If my understaning is right in terms of SAML I'm a User Agent and want to download a file from Sevice Provider which need to authenticate me with Identity Provider (Microsoft). Usually I do it via browser and now I'm able to emulate it with help of PySide6 (QWebEngineView). I load target URL first in QWebEngineView. Actually it is a small embedded web-browser, it redirects me to login.microsoft.com, asks credentials and then redirects me back to Service Provider site and sets session id cookie. Then I'm able to use this cookie with my requests. It works but I would like to get rid of GUI (PySide) if possible.
I decided to replicate a flow that browser does and failed almost at the begining. What happens:
I'm requesting a file from my Service Provider side with usual get request.
Service provider replies with HTML page (instead of target file) as I'm not authenticated.
This HTML page contains Java script triggered by onPageLoad event - this java script simply redirects browswer to login.microsoft.com (long URL with some parameters).
Next request with this long URL for login.microsoft.com ends with "302 Moved Temporarily" with the same URL in "Location" header. And when I go with this URL it again gives me 302 with the same URL.
With the same scenario browswer gets only two redirections and finally receives an URL of web page with login/password request from microsoft.com.
I understand that I should put some more headers/cookies when I go again with URL provided in "Location" header of 302 response. But... I have no idea what login.microsoft.com expects here.
So my question is - is there any source where this message flow is described? Or maybe someone did it already and may give me advice how to proceed?
I found some SAML-related libraries for python but I see there quite complex configuration with x509 certificates and more stuff - it looks like they are more targeted for implementation on Service Provider side, not for external login.

How to use Google Calendar API for the first time on Linux?

You can use google-calerdar-api from this link.
I use this code(python3.X) to get data of calendar on windows 10.
Python Code:
from __future__ import print_function
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools
SCOPES = 'https://www.googleapis.com/auth/calendar'
def main():
store = file.Storage('token.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('./credentials.json', SCOPES)
creds = tools.run_flow(flow, store)
service = build('calendar', 'v3', http=creds.authorize(Http()))
print('Getting the upcoming 10 events')
events_result = service.events().list(calendarId='primary', alwaysIncludeEmail=True,
timeMin='2017-01-01T00:00:00+09:00',timeMax='2019-01-05T23:59:59+09:00',
maxResults=10, singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])
if not events:
print('No upcoming events found.')
for event in events:
start = event['start'].get('dateTime', event['start'].get('date'))
print(start, event['summary'])
if __name__ == '__main__':
main()
When I first used the example code of this api,this information appears in the pycharm console.
Your browser has been opened to visit:
https://accounts.google.com/o/oauth2/auth?client_id=1132573726-nu1pktj3jt03qjigful1cq32p97eu.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar&access_type=offline&response_type=code
If your browser is on a different machine then exit and re-run this
application with the command-line parameter
--noauth_local_webserver
Then my browser pops up a page like this.
Then I clicked my account.
On this page I clicked Allow.
Then the browser displays the message.
Then the console of pycharm appears this:
Authentication successful.
Getting the upcoming 10 events
2018-01-15T08:30:00+09:00 20180115
2019-01-01T10:00:00+09:00 hello
2019-01-02T11:00:00+09:00 20190102_test1
2019-01-03T11:30:00+09:00 20190103_test1
2019-01-04T11:00:00+09:00 20190104_test1
So the code runs successfully.I see file token.json in the folder of code.
But my question is, I can't use browser on Linux(centos), so how can I allow my account to operate like Windows the first time?
Ouaht2 and user consent
If you want to access a users private data then you will always have to have them authenticate your application at least once. The only way to do that is with a web browser window.
The first thing that happens is that a user must login to their google account via a browser, once they have logged in they will be presented with the consent screen asking them to give your application access to their data.
In this manner a user consents to your application accessing their data.
Development for Linux users.
I am curious as to why you think that Linux users will be running your application. I have not seen many people designing natively applications to run on linux. WTG you.
Users running Linux will have to open the to open a web browser, this can be done though the windows desktop. If they are running command line then they will have to copy the link and open it on a browser. I dont think the command line web browser will work here its going to have to be done though the linux desktop.
Service account
Now as you seam to be worried about Linux users I am wondering if you are not really worried about users of your application actually.
Are you are attempting to run this application in say a cron job on a linux server? Assuming as well that you are only trying to access a single account one that you personally control. Then you could use what is called a service account. Service accounts are intended for server to server communication where there is really no user present at login time to approve the consent. For a service account to work they must be pre-approved. Once you have created the service account in Google developer console you simply take the service account email address and share the calendar you wish it to have access to via the google calendar website. Once the calendar has been shared with the service account it will have access to that calendar and you will not have to worry about the web browser authentication.
You need to complete the authentication part in a web browser. To complete the authentication from a different machine/browser, you can complete the rest of the authentication using the OOB (out of band) flow. The oauth library you're using hinted that you can use this OOB flow by passing the --noauth_local_webserver to the program you're running on (alternatively, you can add the flag to sys.argv somehow), open the provided URL on a browser, and then you will have to copy back the verification code manually.
Note that oauth2client.tools isn't intended to be programmatic interface. Its intended use is for interactive CLI application and as an example of how to integrate the library with your own app.
If you're using Windows and don't have any grahical browser on Linux, an easy solution is to run the application with --noauth_local_webserver on Linux and then on Windows connect to the Linux server with PuTTY and bring the server's TCP port 8888 to your local system.
First make sure you don't have anything on Windows already listening on that port (e.g. by running: netstat -na|findstr ":8888 "|findstr /C:LISTENING).
Then you need to open the SSH connection with PuTTY.
Once connected click the icon in the top left of the PuTTY window and go to Change Settings / Connection / SSH / Tunnels, set Source port to 8888, destination to 127.0.0.1:8888 and select Local and Auto.
You can now check by browsing to http://127.0.0.1:8888/, which should show an error message other than not being able to connect.
Then open the browser on Windows and start the activation. When the browser gets redirected to http://127.0.0.1:8888 it will go straight to the application on the Linux server and activate it.
Note that you can do similar thing from macOS. But instead of PuTTY you need to open a Terminal and run ssh -L 8888:127.0.0.1:8888 <user>#<linuxserver>

Box API OAuth2.0 in script

I am writing a script to automate the process of regularly upload specific files to Box.
After reading the BOX API, I know I have to use client-id and client-secret to get an authentication url which open in browser, then I login in by username and password, click allow, then I get redirect to a url I provided with Auth Code attached to the end of this redirect url.
problem now is, I am writing a script not an web or mobile app. Therefore, I have to avoid these UI web html manual login.
Is there a way??? I can get this authentication url by code in python using BOX's python SDK.Then I can open a browser in python by webbrowser module then I can type in username/password. Then I get redirected. Maybe I can use some special redirect url to send auth code back to my code? I don't know how to do that.
Please help!
You should use JWT authentication.
Unlike the standard OAuth 2 flow, JWT will allow you to use your own identity
provider to bypass the application auth and redirect. Building with JWT will allow
you to hide the Box process behind the scenes.
Authenticate with JWT

Facebook login redirect: incomplete url

I'm trying to implement the manual Facebook login flow as described at:
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow
The step where the user signs in and authorizes the app is all good. The problem starts when Facebook redirects to my service (after success login); I can see on the browser's URL bar something like:
http://some.local.domain:8080/1/share/fb_login_redirect?#access_token=XXYYZZ&expires_in=6285
But oddly my web service "sees" only:
http://some.local.domain:8080/1/share/fb_login_redirect
I think this is caused by "#" symbol just after "?". As a result I cannot get the access_token through query string.
My web service is a Python WSGI-application. And I have tested serving it with both gunicorn and wsgiref.simple_server. I have debugged the WSGI environment dict and I found out that the partial URL is being passed (not the full one with the query params). So it seems to be a problem while the browser delivers the request info to WSGI environment. BTW, I have tested on Chrome and Firefox; and I'm using MacOS X 10.10.5 .
I would appreciate any help with this.
Thanks.
The hash part of a URL is a purely client-side construct, it never gets send to the server.
You either need to capture the access token client-side (JavaScript), or choose the response_type: code in your login dialog call.

How can I make Python's 'webbrowser' block execution?

I want to implement a Python script to act as my OAuth2 endpoint, since I'm trying to write a Soundcloud app. Part of the authentication process involves visiting a Soundcloud page where you can sign in and grant access to the given Soundcloud application.
I'd like to be able to open that webpage in a browser using Python 3, which you can do with the webbrowser object. You can see on the documentation that launching a text-based browser blocks execution; I want to block execution whilst the webpage is open in a GUI-based browser.
Does anyone know whether this is possible?
This might be impossible to do portably. For example, if Firefox is already running on Linux, the second invocation of firefox http://url will find out that an instance using the same profile, will send a message to the other process to open that URL in a tab, then exits immediately.
However, you could accomplish the same thing by sending the authentication tokens to a server, and simultaneously polling the server for credentials in the python script.

Categories