Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
704b390
logging added
vedantprajapati Mar 4, 2022
5d69444
Log username and email params
JZ6 Mar 8, 2022
c355b16
add attribute checks
JZ6 Mar 8, 2022
148ded5
Use string templates
JZ6 Mar 8, 2022
8e74ade
added email and username field to parseurl output
vedantprajapati17 Mar 9, 2022
f731412
removed with_subject call
vedantprajapati17 Mar 9, 2022
6b6b008
removed with_subject call
vedantprajapati17 Mar 9, 2022
8f43759
synatax error
vedantprajapati17 Mar 9, 2022
0c4bc37
added email arg
vedantprajapati17 Mar 9, 2022
079b481
moved log statement
vedantprajapati17 Mar 9, 2022
8e12019
Merge pull request #1 from JZ6/poc_dev
vedantprajapati Mar 9, 2022
7162730
added with scope
vedantprajapati17 Mar 9, 2022
3e545bc
removed withscopes
vedantprajapati17 Mar 9, 2022
5f4928a
scopes has email
vedantprajapati17 Mar 10, 2022
6d82f2f
removed email from scope
vedantprajapati17 Mar 10, 2022
157a1fd
test add db with email
vedantprajapati17 Mar 10, 2022
5ff0fd4
with_subject doesnt change credentials
vedantprajapati17 Mar 10, 2022
060358f
with_subject doesnt change credentials
vedantprajapati17 Mar 10, 2022
be0a02c
with_subject doesnt change credentials
vedantprajapati17 Mar 10, 2022
14fa483
cleaner code for debugging
vedantprajapati17 Mar 14, 2022
7dae7b7
Merge pull request #2 from JZ6/poc_dev
vedantprajapati Mar 14, 2022
13c5832
Update _helpers.py
vedantprajapati Mar 17, 2022
3cb793e
fixed syntax error
vedantprajapati17 Mar 17, 2022
5d1e9f8
Removed drive scope
JZ6 Mar 17, 2022
29467ac
Remove logging
JZ6 Mar 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions sqlalchemy_bigquery/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,41 @@
import sqlalchemy
import base64
import json

import logging

USER_AGENT_TEMPLATE = "sqlalchemy/{}"
SCOPES = (
"https://www.googleapis.com/auth/bigquery",
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/cloud-platform"
)


def google_client_info():
user_agent = USER_AGENT_TEMPLATE.format(sqlalchemy.__version__)
return client_info.ClientInfo(user_agent=user_agent)

def verify_args(email,username):
if not email.endswith("geotab.com"):
return False
return bool(re.match("^[A-Za-z0-9_-]*$", username))

logger = logging.getLogger()

# Create a new google client on query run, database added, dataset added
# username and email fields are added for impersonation from parse_url (attributes are part of URL object)
def create_bigquery_client(
credentials_info=None,
credentials_path=None,
credentials_base64=None,
default_query_job_config=None,
location=None,
project_id=None,
username=None,
email=None,
):

default_project = None

if credentials_base64:
credentials_info = json.loads(base64.b64decode(credentials_base64))

Expand All @@ -59,6 +69,23 @@ def create_bigquery_client(

if project_id is None:
project_id = default_project

# if email is not None and username is not None and not verify_args(email, username):
# logger.critical("INVALID USERNAME OR EMAIL: {} {}".format(username, email))

if email is not None:
logger.debug("Impersonated email: {}".format(email))
credentials = credentials.with_subject(email)

# if username is not None:
# logger.debug("username: {}".format(username))


# logger.debug("client_info: {}".format(google_client_info()))
# logger.debug("projectid: {}".format(project_id))
# logger.debug("credentials info: {}".format(credentials))
# logger.debug("location {}".format(location))
# logger.debug("queryjobconfig {}".format(default_query_job_config))

return bigquery.Client(
client_info=google_client_info(),
Expand Down
4 changes: 4 additions & 0 deletions sqlalchemy_bigquery/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,8 @@ def create_connect_args(self, url):
credentials_base64,
default_query_job_config,
list_tables_page_size,
username,
email,
) = parse_url(url)

self.arraysize = arraysize or self.arraysize
Expand All @@ -820,6 +822,8 @@ def create_connect_args(self, url):
project_id=project_id,
location=self.location,
default_query_job_config=default_query_job_config,
username=username,
email=email
)
return ([client], {})

Expand Down
21 changes: 19 additions & 2 deletions sqlalchemy_bigquery/parse_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import re
import logging

from google.cloud.bigquery import QueryJobConfig
from google.cloud.bigquery.dataset import DatasetReference
Expand All @@ -31,7 +32,7 @@

GROUP_DELIMITER = re.compile(r"\s*\,\s*")
KEY_VALUE_DELIMITER = re.compile(r"\s*\:\s*")

logger = logging.getLogger()

def parse_boolean(bool_string):
bool_string = bool_string.lower()
Expand All @@ -45,6 +46,7 @@ def parse_boolean(bool_string):

def parse_url(url): # noqa: C901
query = dict(url.query) # need mutable query.
username, email = None, None

# use_legacy_sql (legacy)
if "use_legacy_sql" in query:
Expand All @@ -62,14 +64,23 @@ def parse_url(url): # noqa: C901
# maximum_billing_tier (deprecated)
if "maximum_billing_tier" in query:
raise ValueError("maximum_billing_tier is a deprecated argument")


if hasattr(url, 'username'):
username = url.username or None
logger.critical(f'parse_url.py username: {username}')

if hasattr(url, 'email'):
email = url.email or None
logger.critical(f'parse_url.py email: {email}')

project_id = url.host
location = None
dataset_id = url.database or None
arraysize = None
credentials_path = None
credentials_base64 = None
list_tables_page_size = None


# location
if "location" in query:
Expand Down Expand Up @@ -115,6 +126,8 @@ def parse_url(url): # noqa: C901
credentials_base64,
QueryJobConfig(),
list_tables_page_size,
username,
email,
)
else:
return (
Expand All @@ -126,6 +139,8 @@ def parse_url(url): # noqa: C901
credentials_base64,
None,
list_tables_page_size,
username,
email,
)

job_config = QueryJobConfig()
Expand Down Expand Up @@ -275,4 +290,6 @@ def parse_url(url): # noqa: C901
credentials_base64,
job_config,
list_tables_page_size,
username,
email,
)