interloper-google-cloud 0.89.0__tar.gz → 0.91.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/PKG-INFO +1 -1
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/pyproject.toml +1 -1
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/pyproject.toml.orig +1 -1
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/connection.py +8 -8
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/README.md +0 -0
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/__init__.py +0 -0
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/bigquery/__init__.py +0 -0
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/bigquery/destination.py +0 -0
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/bigquery/types.py +0 -0
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/gcs/__init__.py +0 -0
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/gcs/destination.py +0 -0
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/gcs/formats.py +0 -0
- {interloper_google_cloud-0.89.0 → interloper_google_cloud-0.91.0}/src/interloper_google_cloud/serialization.py +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# ###############
|
|
4
4
|
[project]
|
|
5
5
|
name = "interloper-google-cloud"
|
|
6
|
-
version = "0.
|
|
6
|
+
version = "0.91.0"
|
|
7
7
|
description = "Interloper Google Cloud integration: BigQuery and Cloud Storage destinations"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
authors = [{ name = "Guillaume Onfroy", email = "guillaume@digitlcloud.com" }]
|
|
@@ -6,7 +6,7 @@ import json
|
|
|
6
6
|
import time
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import httpx2
|
|
10
10
|
from google.auth import crypt, jwt
|
|
11
11
|
from interloper.connection import Connection, connection
|
|
12
12
|
from interloper.resource.fields import JsonField, fetch_field_provider
|
|
@@ -24,7 +24,7 @@ def _make_assertion(key_info: dict[str, Any], scope: str) -> str:
|
|
|
24
24
|
"""Build a signed JWT-bearer assertion for the service account.
|
|
25
25
|
|
|
26
26
|
Only the signing comes from google-auth; the token exchange itself goes
|
|
27
|
-
through
|
|
27
|
+
through httpx2 like every other external fetch.
|
|
28
28
|
|
|
29
29
|
Args:
|
|
30
30
|
key_info: The parsed service account key.
|
|
@@ -45,7 +45,7 @@ def _make_assertion(key_info: dict[str, Any], scope: str) -> str:
|
|
|
45
45
|
return jwt.encode(signer, payload).decode()
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
async def _get_access_token(client:
|
|
48
|
+
async def _get_access_token(client: httpx2.AsyncClient, key_info: dict[str, Any], scope: str) -> str:
|
|
49
49
|
"""Exchange a service account JWT assertion for an access token.
|
|
50
50
|
|
|
51
51
|
Args:
|
|
@@ -68,7 +68,7 @@ async def _get_access_token(client: httpx.AsyncClient, key_info: dict[str, Any],
|
|
|
68
68
|
return resp.json()["access_token"]
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
async def _list_projects(client:
|
|
71
|
+
async def _list_projects(client: httpx2.AsyncClient, access_token: str) -> list[dict[str, str]]:
|
|
72
72
|
"""List the projects the credential has BigQuery access to, following pagination.
|
|
73
73
|
|
|
74
74
|
Args:
|
|
@@ -101,7 +101,7 @@ async def _list_projects(client: httpx.AsyncClient, access_token: str) -> list[d
|
|
|
101
101
|
return sorted(results, key=lambda p: p["name"].lower())
|
|
102
102
|
|
|
103
103
|
|
|
104
|
-
async def _list_buckets(client:
|
|
104
|
+
async def _list_buckets(client: httpx2.AsyncClient, access_token: str, project: str) -> list[dict[str, str]]:
|
|
105
105
|
"""List the Cloud Storage buckets in *project*, following pagination.
|
|
106
106
|
|
|
107
107
|
Args:
|
|
@@ -158,7 +158,7 @@ class GoogleCloudConnection(Connection):
|
|
|
158
158
|
|
|
159
159
|
Backs the BigQuery destination's ``project`` ``FetchField``. Signs a
|
|
160
160
|
JWT-bearer assertion from the service account key and exchanges it for
|
|
161
|
-
an access token over
|
|
161
|
+
an access token over httpx2 (only the signing uses google-auth), then
|
|
162
162
|
pages through BigQuery's ``projects.list``.
|
|
163
163
|
|
|
164
164
|
Returns:
|
|
@@ -166,7 +166,7 @@ class GoogleCloudConnection(Connection):
|
|
|
166
166
|
|
|
167
167
|
"""
|
|
168
168
|
key_info: dict[str, Any] = json.loads(self.service_account_key)
|
|
169
|
-
async with
|
|
169
|
+
async with httpx2.AsyncClient(timeout=30) as client:
|
|
170
170
|
access_token = await _get_access_token(client, key_info, _BIGQUERY_SCOPE)
|
|
171
171
|
return await _list_projects(client, access_token)
|
|
172
172
|
|
|
@@ -184,7 +184,7 @@ class GoogleCloudConnection(Connection):
|
|
|
184
184
|
|
|
185
185
|
"""
|
|
186
186
|
key_info: dict[str, Any] = json.loads(self.service_account_key)
|
|
187
|
-
async with
|
|
187
|
+
async with httpx2.AsyncClient(timeout=30) as client:
|
|
188
188
|
access_token = await _get_access_token(client, key_info, _STORAGE_SCOPE)
|
|
189
189
|
return await _list_buckets(client, access_token, key_info["project_id"])
|
|
190
190
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|