codekingpro/portable-devtools
114k
1# Copyright 2019 Google LLC2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# https://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14 15"""Get user credentials from interactive code environments.16 17This module contains helpers for getting user credentials from interactive18code environments installed on a development machine, such as Jupyter19notebooks.20"""21 22from __future__ import absolute_import23 24import contextlib25import socket26 27import google_auth_oauthlib.flow28 29 30LOCALHOST = "localhost"31DEFAULT_PORTS_TO_TRY = 10032 33 34def is_port_open(port):35 """Check if a port is open on localhost.36 Based on StackOverflow answer: https://stackoverflow.com/a/43238489/10192337 Parameters38 ----------39 port : int40 A port to check on localhost.41 Returns42 -------43 is_open : bool44 True if a socket can be opened at the requested port.45 """46 with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:47 try:48 sock.bind((LOCALHOST, port))49 sock.listen(1)50 except socket.error:51 is_open = False52 else:53 is_open = True54 return is_open55 56 57def find_open_port(start=8080, stop=None):58 """Find an open port between ``start`` and ``stop``.59 Parameters60 ----------61 start : Optional[int]62 Beginning of range of ports to try. Defaults to 8080.63 stop : Optional[int]64 End of range of ports to try (not including exactly equals ``stop``).65 This function tries 100 possible ports if no ``stop`` is specified.66 Returns67 -------68 Optional[int]69 ``None`` if no open port is found, otherwise an integer indicating an70 open port.71 """72 if not stop:73 stop = start + DEFAULT_PORTS_TO_TRY74 75 for port in range(start, stop):76 if is_port_open(port):77 return port78 79 # No open ports found.80 return None81 82 83def get_user_credentials(84 scopes, client_id, client_secret, minimum_port=8080, maximum_port=None85):86 """Gets credentials associated with your Google user account.87 88 This function authenticates using your user credentials by going through89 the OAuth 2.0 flow. You'll open a browser window to authenticate to your90 Google account. The permissions it requests correspond to the scopes91 you've provided.92 93 To obtain the ``client_id`` and ``client_secret``, create an **OAuth94 client ID** with application type **Other** from the `Credentials page on95 the Google Developer's Console96 <https://console.developers.google.com/apis/credentials>`_. Learn more97 with the `Authenticating as an end user98 <https://cloud.google.com/docs/authentication/end-user>`_ guide.99 100 Args:101 scopes (Sequence[str]):102 A list of scopes to use when authenticating to Google APIs. See103 the `list of OAuth 2.0 scopes for Google APIs104 <https://developers.google.com/identity/protocols/googlescopes>`_.105 client_id (str):106 A string that identifies your application to Google APIs. Find107 this value in the `Credentials page on the Google Developer's108 Console109 <https://console.developers.google.com/apis/credentials>`_.110 client_secret (str):111 A string that verifies your application to Google APIs. Find this112 value in the `Credentials page on the Google Developer's Console113 <https://console.developers.google.com/apis/credentials>`_.114 minimum_port (int):115 Beginning of range of ports to try for redirect URI HTTP server.116 Defaults to 8080.117 maximum_port (Optional[int]):118 End of range of ports to try (not including exactly equals ``stop``).119 This function tries 100 possible ports if no ``stop`` is specified.120 121 Returns:122 google.oauth2.credentials.Credentials:123 The OAuth 2.0 credentials for the user.124 125 Examples:126 Get credentials for your user account and use them to run a query127 with BigQuery::128 129 import google_auth_oauthlib130 131 # TODO: Create a client ID for your project.132 client_id = "YOUR-CLIENT-ID.apps.googleusercontent.com"133 client_secret = "abc_ThIsIsAsEcReT"134 135 # TODO: Choose the needed scopes for your applications.136 scopes = ["https://www.googleapis.com/auth/cloud-platform"]137 138 credentials = google_auth_oauthlib.get_user_credentials(139 scopes, client_id, client_secret140 )141 142 # 1. Open the link.143 # 2. Authorize the application to have access to your account.144 # 3. Copy and paste the authorization code to the prompt.145 146 # Use the credentials to construct a client for Google APIs.147 from google.cloud import bigquery148 149 bigquery_client = bigquery.Client(150 credentials=credentials, project="your-project-id"151 )152 print(list(bigquery_client.query("SELECT 1").result()))153 """154 155 client_config = {156 "installed": {157 "client_id": client_id,158 "client_secret": client_secret,159 "auth_uri": "https://accounts.google.com/o/oauth2/auth",160 "token_uri": "https://oauth2.googleapis.com/token",161 }162 }163 164 app_flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_config(165 client_config, scopes=scopes166 )167 168 port = find_open_port(start=minimum_port, stop=maximum_port)169 if not port:170 raise ConnectionError("Could not find open port.")171 172 return app_flow.run_local_server(host=LOCALHOST, port=port)173 