ingestr 0.13.67__py3-none-any.whl → 0.13.69__py3-none-any.whl
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.
- ingestr/conftest.py +9 -0
- ingestr/main.py +2 -2
- ingestr/src/applovin_max/__init__.py +1 -0
- ingestr/src/buildinfo.py +1 -1
- ingestr/src/destinations.py +2 -2
- ingestr/src/linear/__init__.py +5 -3
- ingestr/src/linear/helpers.py +16 -4
- ingestr/src/solidgate/__init__.py +108 -12
- ingestr/src/solidgate/helpers.py +29 -21
- ingestr/src/sources.py +21 -1
- ingestr/src/stripe_analytics/helpers.py +0 -1
- ingestr/src/zoom/__init__.py +2 -2
- ingestr/src/zoom/helpers.py +1 -1
- {ingestr-0.13.67.dist-info → ingestr-0.13.69.dist-info}/METADATA +2 -2
- {ingestr-0.13.67.dist-info → ingestr-0.13.69.dist-info}/RECORD +18 -18
- {ingestr-0.13.67.dist-info → ingestr-0.13.69.dist-info}/WHEEL +0 -0
- {ingestr-0.13.67.dist-info → ingestr-0.13.69.dist-info}/entry_points.txt +0 -0
- {ingestr-0.13.67.dist-info → ingestr-0.13.69.dist-info}/licenses/LICENSE.md +0 -0
ingestr/conftest.py
CHANGED
@@ -2,6 +2,7 @@ import os
|
|
2
2
|
import tempfile
|
3
3
|
from concurrent.futures import ThreadPoolExecutor
|
4
4
|
|
5
|
+
import pytest
|
5
6
|
from main_test import DESTINATIONS, SOURCES # type: ignore
|
6
7
|
|
7
8
|
|
@@ -15,6 +16,14 @@ def pytest_configure_node(node):
|
|
15
16
|
node.workerinput["shared_directory"] = node.config.shared_directory
|
16
17
|
|
17
18
|
|
19
|
+
@pytest.fixture(scope="session")
|
20
|
+
def shared_directory(request):
|
21
|
+
if is_master(request.config):
|
22
|
+
return request.config.shared_directory
|
23
|
+
else:
|
24
|
+
return request.config.workerinput["shared_directory"]
|
25
|
+
|
26
|
+
|
18
27
|
def is_master(config):
|
19
28
|
"""True if the code running the given pytest.config object is running in a xdist master
|
20
29
|
node or not running xdist at all.
|
ingestr/main.py
CHANGED
@@ -256,7 +256,7 @@ def ingest(
|
|
256
256
|
Optional[list[str]],
|
257
257
|
typer.Option(
|
258
258
|
help="The column types to be used for the destination table in the format of 'column_name:column_type'",
|
259
|
-
envvar=["
|
259
|
+
envvar=["INGESTR_COLUMNS"],
|
260
260
|
),
|
261
261
|
] = None, # type: ignore
|
262
262
|
yield_limit: Annotated[
|
@@ -455,7 +455,7 @@ def ingest(
|
|
455
455
|
|
456
456
|
column_hints[key]["primary_key"] = True
|
457
457
|
|
458
|
-
pipeline = dlt.pipeline(
|
458
|
+
pipeline = dlt.pipeline( # type: ignore
|
459
459
|
pipeline_name=m.hexdigest(),
|
460
460
|
destination=dlt_dest,
|
461
461
|
progress=progressInstance,
|
ingestr/src/buildinfo.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
version = "v0.13.
|
1
|
+
version = "v0.13.69"
|
ingestr/src/destinations.py
CHANGED
@@ -90,7 +90,7 @@ class BigQueryDestination:
|
|
90
90
|
|
91
91
|
return dlt.destinations.bigquery(
|
92
92
|
credentials=credentials, # type: ignore
|
93
|
-
location=location,
|
93
|
+
location=location, # type: ignore
|
94
94
|
project_id=project_id,
|
95
95
|
**kwargs,
|
96
96
|
)
|
@@ -398,7 +398,7 @@ class AthenaDestination:
|
|
398
398
|
|
399
399
|
return dlt.destinations.athena(
|
400
400
|
query_result_bucket=query_result_path,
|
401
|
-
athena_work_group=source_params.get("workgroup", [None])[0],
|
401
|
+
athena_work_group=source_params.get("workgroup", [None])[0], # type: ignore
|
402
402
|
credentials=AwsCredentials(
|
403
403
|
aws_access_key_id=access_key_id, # type: ignore
|
404
404
|
aws_secret_access_key=secret_access_key, # type: ignore
|
ingestr/src/linear/__init__.py
CHANGED
@@ -3,7 +3,7 @@ from typing import Any, Dict, Iterable, Iterator
|
|
3
3
|
import dlt
|
4
4
|
import pendulum
|
5
5
|
|
6
|
-
from .helpers import
|
6
|
+
from .helpers import _normalize_issue, _normalize_team, _paginate
|
7
7
|
|
8
8
|
ISSUES_QUERY = """
|
9
9
|
query Issues($cursor: String) {
|
@@ -143,13 +143,15 @@ def linear_source(
|
|
143
143
|
yield item
|
144
144
|
|
145
145
|
@dlt.resource(name="teams", primary_key="id", write_disposition="merge")
|
146
|
-
def teams(
|
146
|
+
def teams(
|
147
|
+
updated_at: dlt.sources.incremental[str] = dlt.sources.incremental(
|
147
148
|
"updatedAt",
|
148
149
|
initial_value=start_date.isoformat(),
|
149
150
|
end_value=end_date.isoformat() if end_date else None,
|
150
151
|
range_start="closed",
|
151
152
|
range_end="closed",
|
152
|
-
),
|
153
|
+
),
|
154
|
+
) -> Iterator[Dict[str, Any]]:
|
153
155
|
print(start_date)
|
154
156
|
if updated_at.last_value:
|
155
157
|
current_start_date = pendulum.parse(updated_at.last_value)
|
ingestr/src/linear/helpers.py
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
import json
|
2
1
|
from typing import Any, Dict, Iterator, Optional
|
3
2
|
|
4
3
|
import requests
|
5
4
|
|
6
5
|
LINEAR_GRAPHQL_ENDPOINT = "https://api.linear.app/graphql"
|
7
6
|
|
7
|
+
|
8
8
|
def _graphql(
|
9
9
|
api_key: str, query: str, variables: Optional[Dict[str, Any]] = None
|
10
10
|
) -> Dict[str, Any]:
|
@@ -20,6 +20,7 @@ def _graphql(
|
|
20
20
|
raise ValueError(str(payload["errors"]))
|
21
21
|
return payload["data"]
|
22
22
|
|
23
|
+
|
23
24
|
def _paginate(api_key: str, query: str, root: str) -> Iterator[Dict[str, Any]]:
|
24
25
|
cursor: Optional[str] = None
|
25
26
|
while True:
|
@@ -30,6 +31,7 @@ def _paginate(api_key: str, query: str, root: str) -> Iterator[Dict[str, Any]]:
|
|
30
31
|
break
|
31
32
|
cursor = data["pageInfo"]["endCursor"]
|
32
33
|
|
34
|
+
|
33
35
|
def _normalize_issue(item: Dict[str, Any]) -> Dict[str, Any]:
|
34
36
|
field_mapping = {
|
35
37
|
"assignee": "assignee_id",
|
@@ -45,16 +47,26 @@ def _normalize_issue(item: Dict[str, Any]) -> Dict[str, Any]:
|
|
45
47
|
else:
|
46
48
|
item[value] = None
|
47
49
|
del item[key]
|
48
|
-
json_fields = [
|
50
|
+
json_fields = [
|
51
|
+
"comments",
|
52
|
+
"subscribers",
|
53
|
+
"attachments",
|
54
|
+
"labels",
|
55
|
+
"subtasks",
|
56
|
+
"projects",
|
57
|
+
"memberships",
|
58
|
+
"members",
|
59
|
+
]
|
49
60
|
for field in json_fields:
|
50
61
|
if item.get(field):
|
51
62
|
item[f"{field}"] = item[field].get("nodes", [])
|
52
|
-
|
63
|
+
|
53
64
|
return item
|
54
65
|
|
66
|
+
|
55
67
|
def _normalize_team(item: Dict[str, Any]) -> Dict[str, Any]:
|
56
68
|
json_fields = ["memberships", "members", "projects"]
|
57
69
|
for field in json_fields:
|
58
70
|
if item.get(field):
|
59
71
|
item[f"{field}"] = item[field].get("nodes", [])
|
60
|
-
return item
|
72
|
+
return item
|
@@ -6,6 +6,110 @@ from dlt.sources import DltResource
|
|
6
6
|
|
7
7
|
from .helpers import SolidgateClient
|
8
8
|
|
9
|
+
COLUMN_HINTS = {
|
10
|
+
"subscriptions": {
|
11
|
+
"id": {"data_type": "text", "nullable": False, "primary_key": True},
|
12
|
+
"created_at": {"data_type": "timestamp", "partition": True},
|
13
|
+
"status": {"data_type": "text"},
|
14
|
+
"started_at": {"data_type": "timestamp"},
|
15
|
+
"updated_at": {"data_type": "timestamp"},
|
16
|
+
"expired_at": {"data_type": "timestamp"},
|
17
|
+
"next_charge_at": {"data_type": "timestamp"},
|
18
|
+
"payment_type": {"data_type": "text"},
|
19
|
+
"trial": {"data_type": "bool"},
|
20
|
+
"cancelled_at": {"data_type": "timestamp"},
|
21
|
+
"cancellation_requested_at": {"data_type": "timestamp"},
|
22
|
+
"cancel_code": {"data_type": "text"},
|
23
|
+
"cancel_message": {"data_type": "text"},
|
24
|
+
"customer": {"data_type": "json"},
|
25
|
+
"product": {"data_type": "json"},
|
26
|
+
"invoices": {"data_type": "json"},
|
27
|
+
},
|
28
|
+
"apm_orders": {
|
29
|
+
"order_id": {"data_type": "text", "nullable": False, "primary_key": True},
|
30
|
+
"created_at": {"data_type": "timestamp", "partition": True},
|
31
|
+
"updated_at": {"data_type": "timestamp"},
|
32
|
+
"order_description": {"data_type": "text"},
|
33
|
+
"method": {"data_type": "text"},
|
34
|
+
"amount": {"data_type": "bigint"},
|
35
|
+
"currency": {"data_type": "text"},
|
36
|
+
"processing_amount": {"data_type": "bigint"},
|
37
|
+
"processing_currency": {"data_type": "text"},
|
38
|
+
"status": {"data_type": "text"},
|
39
|
+
"customer_account_id": {"data_type": "text"},
|
40
|
+
"customer_email": {"data_type": "text"},
|
41
|
+
"ip_address": {"data_type": "text"},
|
42
|
+
"geo_country": {"data_type": "text"},
|
43
|
+
"error_code": {"data_type": "text"},
|
44
|
+
"transactions": {"data_type": "json"},
|
45
|
+
"order_metadata": {"data_type": "json"},
|
46
|
+
},
|
47
|
+
"card_orders": {
|
48
|
+
"order_id": {"data_type": "text", "nullable": False, "primary_key": True},
|
49
|
+
"created_at": {"data_type": "timestamp", "partition": True},
|
50
|
+
"updated_at": {"data_type": "timestamp"},
|
51
|
+
"order_description": {"data_type": "text"},
|
52
|
+
"psp_order_id": {"data_type": "text"},
|
53
|
+
"provider_payment_id": {"data_type": "text"},
|
54
|
+
"amount": {"data_type": "bigint"},
|
55
|
+
"currency": {"data_type": "text"},
|
56
|
+
"processing_amount": {"data_type": "bigint"},
|
57
|
+
"processing_currency": {"data_type": "text"},
|
58
|
+
"status": {"data_type": "text"},
|
59
|
+
"payment_type": {"data_type": "text"},
|
60
|
+
"type": {"data_type": "text"},
|
61
|
+
"is_secured": {"data_type": "bool"},
|
62
|
+
"routing": {"data_type": "json"},
|
63
|
+
"customer_account_id": {"data_type": "text"},
|
64
|
+
"customer_email": {"data_type": "text"},
|
65
|
+
"customer_first_name": {"data_type": "text"},
|
66
|
+
"customer_last_name": {"data_type": "text"},
|
67
|
+
"ip_address": {"data_type": "text"},
|
68
|
+
"mid": {"data_type": "text"},
|
69
|
+
"traffic_source": {"data_type": "text"},
|
70
|
+
"platform": {"data_type": "text"},
|
71
|
+
"geo_country": {"data_type": "text"},
|
72
|
+
"error_code": {"data_type": "text"},
|
73
|
+
"transactions": {"data_type": "json"},
|
74
|
+
"order_metadata": {"data_type": "json"},
|
75
|
+
"fraudulent": {"data_type": "bool"},
|
76
|
+
},
|
77
|
+
"financial_entries": {
|
78
|
+
"id": {
|
79
|
+
"data_type": "text",
|
80
|
+
"nullable": False,
|
81
|
+
"primary_key": True,
|
82
|
+
},
|
83
|
+
"order_id": {"data_type": "text"},
|
84
|
+
"external_psp_order_id": {"data_type": "text"},
|
85
|
+
"created_at": {"data_type": "timestamp", "partition": True},
|
86
|
+
"transaction_datetime_provider": {"data_type": "timestamp"},
|
87
|
+
"transaction_datetime_utc": {"data_type": "timestamp"},
|
88
|
+
"accounting_date": {"data_type": "date"},
|
89
|
+
"amount": {"data_type": "decimal", "precision": 18, "scale": 4},
|
90
|
+
"amount_in_major_units": {"data_type": "decimal", "precision": 18, "scale": 4},
|
91
|
+
"currency": {"data_type": "text"},
|
92
|
+
"currency_minor_units": {"data_type": "bigint"},
|
93
|
+
"payout_amount": {"data_type": "decimal", "precision": 18, "scale": 4},
|
94
|
+
"payout_amount_in_major_units": {
|
95
|
+
"data_type": "decimal",
|
96
|
+
"precision": 18,
|
97
|
+
"scale": 4,
|
98
|
+
},
|
99
|
+
"payout_currency": {"data_type": "text"},
|
100
|
+
"payout_currency_minor_units": {"data_type": "bigint"},
|
101
|
+
"record_type_key": {"data_type": "text"},
|
102
|
+
"provider": {"data_type": "text"},
|
103
|
+
"payment_method": {"data_type": "text"},
|
104
|
+
"card_brand": {"data_type": "text"},
|
105
|
+
"geo_country": {"data_type": "text"},
|
106
|
+
"issuing_country": {"data_type": "text"},
|
107
|
+
"transaction_id": {"data_type": "text"},
|
108
|
+
"chargeback_id": {"data_type": "text"},
|
109
|
+
"legal_entity": {"data_type": "text"},
|
110
|
+
},
|
111
|
+
}
|
112
|
+
|
9
113
|
|
10
114
|
@dlt.source(max_table_nesting=0)
|
11
115
|
def solidgate_source(
|
@@ -20,9 +124,7 @@ def solidgate_source(
|
|
20
124
|
name="subscriptions",
|
21
125
|
write_disposition="merge",
|
22
126
|
primary_key="id",
|
23
|
-
columns=
|
24
|
-
"created_at": {"data_type": "timestamp", "partition": True},
|
25
|
-
},
|
127
|
+
columns=COLUMN_HINTS["subscriptions"], # type: ignore
|
26
128
|
)
|
27
129
|
def fetch_all_subscriptions(
|
28
130
|
dateTime=dlt.sources.incremental(
|
@@ -46,9 +148,7 @@ def solidgate_source(
|
|
46
148
|
name="apm_orders",
|
47
149
|
write_disposition="merge",
|
48
150
|
primary_key="order_id",
|
49
|
-
columns=
|
50
|
-
"created_at": {"data_type": "timestamp", "partition": True},
|
51
|
-
},
|
151
|
+
columns=COLUMN_HINTS["apm_orders"], # type: ignore
|
52
152
|
)
|
53
153
|
def fetch_apm_orders(
|
54
154
|
dateTime=dlt.sources.incremental(
|
@@ -72,9 +172,7 @@ def solidgate_source(
|
|
72
172
|
name="card_orders",
|
73
173
|
write_disposition="merge",
|
74
174
|
primary_key="order_id",
|
75
|
-
columns=
|
76
|
-
"created_at": {"data_type": "timestamp", "partition": True},
|
77
|
-
},
|
175
|
+
columns=COLUMN_HINTS["card_orders"], # type: ignore
|
78
176
|
)
|
79
177
|
def fetch_card_orders(
|
80
178
|
dateTime=dlt.sources.incremental(
|
@@ -98,9 +196,7 @@ def solidgate_source(
|
|
98
196
|
name="financial_entries",
|
99
197
|
write_disposition="merge",
|
100
198
|
primary_key="id",
|
101
|
-
columns=
|
102
|
-
"created_at": {"data_type": "timestamp", "partition": True},
|
103
|
-
},
|
199
|
+
columns=COLUMN_HINTS["financial_entries"], # type: ignore
|
104
200
|
)
|
105
201
|
def fetch_financial_entries(
|
106
202
|
dateTime=dlt.sources.incremental(
|
ingestr/src/solidgate/helpers.py
CHANGED
@@ -92,9 +92,6 @@ class SolidgateClient:
|
|
92
92
|
if not report_url:
|
93
93
|
return f"Report URL not found in the response: {post_response.json()}", 400
|
94
94
|
|
95
|
-
# Wait for 5 seconds before attempting to download the report as report may not be immediately available
|
96
|
-
time.sleep(5)
|
97
|
-
|
98
95
|
data = self.public_key + self.public_key
|
99
96
|
hmac_hash = hmac.new(
|
100
97
|
self.secret_key.encode("utf-8"), data.encode("utf-8"), hashlib.sha512
|
@@ -109,27 +106,38 @@ class SolidgateClient:
|
|
109
106
|
"Content-Type": "application/json",
|
110
107
|
}
|
111
108
|
|
112
|
-
|
109
|
+
# Retry getting the report for up to 10 minutes (600 seconds) with 5-second intervals
|
110
|
+
max_retries = 120 # 10 minutes / 5 seconds = 120 attempts
|
111
|
+
retry_count = 0
|
112
|
+
|
113
|
+
while retry_count < max_retries:
|
114
|
+
get_response = self.client.get(report_url, headers=headers_get)
|
113
115
|
|
114
|
-
|
115
|
-
try:
|
116
|
-
response_json = json.loads(get_response.content)
|
117
|
-
if "error" in response_json:
|
118
|
-
raise Exception(f"API Error: {response_json['error']['messages']}")
|
119
|
-
except json.JSONDecodeError:
|
116
|
+
if get_response.status_code == 200:
|
120
117
|
try:
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
118
|
+
response_json = json.loads(get_response.content)
|
119
|
+
if "error" in response_json:
|
120
|
+
raise Exception(
|
121
|
+
f"API Error: {response_json['error']['messages']}"
|
122
|
+
)
|
123
|
+
except json.JSONDecodeError:
|
124
|
+
try:
|
125
|
+
csv_data = get_response.content.decode("utf-8")
|
126
|
+
df = pd.read_csv(StringIO(csv_data))
|
127
|
+
df["created_at"] = df["created_at"].apply(
|
128
|
+
lambda x: pendulum.parse(x)
|
129
|
+
)
|
130
|
+
return df
|
131
|
+
except Exception as e:
|
132
|
+
raise Exception(f"Error reading CSV: {e}")
|
133
|
+
else:
|
134
|
+
# Report might not be ready yet, wait and retry
|
135
|
+
retry_count += 1
|
136
|
+
if retry_count >= max_retries:
|
137
|
+
raise Exception(
|
138
|
+
f"Failed to get report after {max_retries} attempts. Status code: {get_response.status_code}"
|
125
139
|
)
|
126
|
-
|
127
|
-
except Exception as e:
|
128
|
-
raise Exception(f"Error reading CSV: {e}")
|
129
|
-
else:
|
130
|
-
raise Exception(
|
131
|
-
f"Failed to get report. Status code: {get_response.status_code}"
|
132
|
-
)
|
140
|
+
time.sleep(5) # Wait 5 seconds before retrying
|
133
141
|
|
134
142
|
def generateSignature(self, json_string):
|
135
143
|
data = self.public_key + json_string + self.public_key
|
ingestr/src/sources.py
CHANGED
@@ -76,6 +76,27 @@ class SqlSource:
|
|
76
76
|
if uri.startswith("mysql://"):
|
77
77
|
uri = uri.replace("mysql://", "mysql+pymysql://")
|
78
78
|
|
79
|
+
# Process Snowflake private key authentication
|
80
|
+
if uri.startswith("snowflake://"):
|
81
|
+
parsed_uri = urlparse(uri)
|
82
|
+
query_params = parse_qs(parsed_uri.query)
|
83
|
+
|
84
|
+
if "private_key" in query_params:
|
85
|
+
from dlt.common.libs.cryptography import decode_private_key
|
86
|
+
|
87
|
+
private_key = query_params["private_key"][0]
|
88
|
+
passphrase = query_params.get("private_key_passphrase", [None])[0]
|
89
|
+
decoded_key = decode_private_key(private_key, passphrase)
|
90
|
+
|
91
|
+
query_params["private_key"] = [base64.b64encode(decoded_key).decode()]
|
92
|
+
if "private_key_passphrase" in query_params:
|
93
|
+
del query_params["private_key_passphrase"]
|
94
|
+
|
95
|
+
# Rebuild URI
|
96
|
+
uri = parsed_uri._replace(
|
97
|
+
query=urlencode(query_params, doseq=True)
|
98
|
+
).geturl()
|
99
|
+
|
79
100
|
# clickhouse://<username>:<password>@<host>:<port>?secure=<secure>
|
80
101
|
if uri.startswith("clickhouse://"):
|
81
102
|
parsed_uri = urlparse(uri)
|
@@ -139,7 +160,6 @@ class SqlSource:
|
|
139
160
|
return engine.execution_options(read_only=True)
|
140
161
|
|
141
162
|
engine_adapter_callback = eng_callback
|
142
|
-
|
143
163
|
from dlt.common.libs.sql_alchemy import (
|
144
164
|
Engine,
|
145
165
|
MetaData,
|
ingestr/src/zoom/__init__.py
CHANGED
@@ -42,14 +42,14 @@ def zoom_source(
|
|
42
42
|
end_dt = pendulum.now("UTC")
|
43
43
|
else:
|
44
44
|
end_dt = pendulum.parse(datetime.end_value)
|
45
|
-
|
45
|
+
|
46
46
|
base_params: Dict[str, Any] = {
|
47
47
|
"type": "scheduled",
|
48
48
|
"page_size": 300,
|
49
49
|
"from": start_dt.to_date_string(),
|
50
50
|
"to": end_dt.to_date_string(),
|
51
51
|
}
|
52
|
-
|
52
|
+
|
53
53
|
for user in client.get_users():
|
54
54
|
user_id = user["id"]
|
55
55
|
yield from client.get_meetings(user_id, base_params)
|
ingestr/src/zoom/helpers.py
CHANGED
@@ -62,7 +62,7 @@ class ZoomClient:
|
|
62
62
|
break
|
63
63
|
params["next_page_token"] = token
|
64
64
|
|
65
|
-
#https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meetings
|
65
|
+
# https://developers.zoom.us/docs/api/rest/reference/zoom-api/methods/#operation/meetings
|
66
66
|
def get_meetings(
|
67
67
|
self, user_id: str, params: Dict[str, Any]
|
68
68
|
) -> Iterator[Dict[str, Any]]:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ingestr
|
3
|
-
Version: 0.13.
|
3
|
+
Version: 0.13.69
|
4
4
|
Summary: ingestr is a command-line application that ingests data from various sources and stores them in any database.
|
5
5
|
Project-URL: Homepage, https://github.com/bruin-data/ingestr
|
6
6
|
Project-URL: Issues, https://github.com/bruin-data/ingestr/issues
|
@@ -48,7 +48,7 @@ Requires-Dist: dataclasses-json==0.6.7
|
|
48
48
|
Requires-Dist: decorator==5.2.1
|
49
49
|
Requires-Dist: deprecation==2.1.0
|
50
50
|
Requires-Dist: dlt-cratedb==0.0.1
|
51
|
-
Requires-Dist: dlt==1.
|
51
|
+
Requires-Dist: dlt==1.11.0
|
52
52
|
Requires-Dist: dnspython==2.7.0
|
53
53
|
Requires-Dist: duckdb-engine==0.17.0
|
54
54
|
Requires-Dist: duckdb==1.2.1
|
@@ -1,9 +1,9 @@
|
|
1
|
-
ingestr/conftest.py,sha256=
|
2
|
-
ingestr/main.py,sha256=
|
1
|
+
ingestr/conftest.py,sha256=OE2yxeTCosS9CUFVuqNypm-2ftYvVBeeq7egm3878cI,1981
|
2
|
+
ingestr/main.py,sha256=wu4c_4nit3c5v2K1af68DjT2hIfEiCvzQ8EZJxOkJjo,26369
|
3
3
|
ingestr/src/.gitignore,sha256=8cX1AZTSI0TcdZFGTmS_oyBjpfCzhOEt0DdAo2dFIY8,203
|
4
4
|
ingestr/src/blob.py,sha256=UUWMjHUuoR9xP1XZQ6UANQmnMVyDx3d0X4-2FQC271I,2138
|
5
|
-
ingestr/src/buildinfo.py,sha256=
|
6
|
-
ingestr/src/destinations.py,sha256=
|
5
|
+
ingestr/src/buildinfo.py,sha256=Ke17ObaAtICcxQMwBjBfKvBywicwCyo9pp8D2NmSsjk,21
|
6
|
+
ingestr/src/destinations.py,sha256=ivTPio0zzqLRx22i597pxZHMNClz-XvYSyCaCPuGd8g,22248
|
7
7
|
ingestr/src/errors.py,sha256=Ufs4_DfE77_E3vnA1fOQdi6cmuLVNm7_SbFLkL1XPGk,686
|
8
8
|
ingestr/src/factory.py,sha256=AJCvlK4M1sIpAAks1K-xsR_uxziIxru74mj572zixhg,6546
|
9
9
|
ingestr/src/filters.py,sha256=LLecXe9QkLFkFLUZ92OXNdcANr1a8edDxrflc2ko_KA,1452
|
@@ -11,7 +11,7 @@ ingestr/src/http_client.py,sha256=bxqsk6nJNXCo-79gW04B53DQO-yr25vaSsqP0AKtjx4,73
|
|
11
11
|
ingestr/src/loader.py,sha256=9NaWAyfkXdqAZSS-N72Iwo36Lbx4PyqIfaaH1dNdkFs,1712
|
12
12
|
ingestr/src/partition.py,sha256=BrIP6wFJvyR7Nus_3ElnfxknUXeCipK_E_bB8kZowfc,969
|
13
13
|
ingestr/src/resource.py,sha256=ZqmZxFQVGlF8rFPhBiUB08HES0yoTj8sZ--jKfaaVps,1164
|
14
|
-
ingestr/src/sources.py,sha256=
|
14
|
+
ingestr/src/sources.py,sha256=Ey3fI-SZ08fVMZf5_uCdLku87UuT3bjM8SmesgoSSY8,104292
|
15
15
|
ingestr/src/table_definition.py,sha256=REbAbqdlmUMUuRh8nEQRreWjPVOQ5ZcfqGkScKdCrmk,390
|
16
16
|
ingestr/src/time.py,sha256=H_Fk2J4ShXyUM-EMY7MqCLZQhlnZMZvO952bmZPc4yE,254
|
17
17
|
ingestr/src/version.py,sha256=J_2xgZ0mKlvuHcjdKCx2nlioneLH0I47JiU_Slr_Nwc,189
|
@@ -19,7 +19,7 @@ ingestr/src/adjust/__init__.py,sha256=ULjtJqrNS6XDvUyGl0tjl12-tLyXlCgeFe2icTbtu3
|
|
19
19
|
ingestr/src/adjust/adjust_helpers.py,sha256=IHSS94A7enOWkZ8cP5iW3RdYt0Xl3qZGAmDc1Xy4qkI,3802
|
20
20
|
ingestr/src/airtable/__init__.py,sha256=XzRsS39xszUlh_s7P1_zq5v8vLfjz3m-NtTPaa8TTZU,2818
|
21
21
|
ingestr/src/applovin/__init__.py,sha256=X_YCLppPrnL8KXfYWICE_uDfMzHHH3JZ-DBGZ1RlaOI,6984
|
22
|
-
ingestr/src/applovin_max/__init__.py,sha256=
|
22
|
+
ingestr/src/applovin_max/__init__.py,sha256=fxXqsIibJarp5NOGe08G964HftwLDymTtYS_LqPJht4,3315
|
23
23
|
ingestr/src/appsflyer/__init__.py,sha256=QoK-B3cYYMD3bqzQaLWNH6FkJyjRbzRkBF2n6urxubs,8071
|
24
24
|
ingestr/src/appsflyer/client.py,sha256=E6xPW4KlbBnQZ0K4eq2Xgb3AmGrtrzIX9bX8EnQr-D4,3615
|
25
25
|
ingestr/src/appstore/__init__.py,sha256=3P4VZH2WJF477QjW19jMTwu6L8DXcLkYSdutnvp3AmM,4742
|
@@ -81,8 +81,8 @@ ingestr/src/kinesis/helpers.py,sha256=SO2cFmWNGcykUYmjHdfxWsOQSkLQXyhFtfWnkcUOM0
|
|
81
81
|
ingestr/src/klaviyo/__init__.py,sha256=o_noUgbxLk36s4f9W56_ibPorF0n7kVapPUlV0p-jfA,7875
|
82
82
|
ingestr/src/klaviyo/client.py,sha256=tPj79ia7AW0ZOJhzlKNPCliGbdojRNwUFp8HvB2ym5s,7434
|
83
83
|
ingestr/src/klaviyo/helpers.py,sha256=_i-SHffhv25feLDcjy6Blj1UxYLISCwVCMgGtrlnYHk,496
|
84
|
-
ingestr/src/linear/__init__.py,sha256=
|
85
|
-
ingestr/src/linear/helpers.py,sha256=
|
84
|
+
ingestr/src/linear/__init__.py,sha256=Qbf8EPHVh-8pVNe_fqLVinds7qQ3O4ymDuPPPD560Ng,5953
|
85
|
+
ingestr/src/linear/helpers.py,sha256=Mb7oKpUTRnHl-CvO1fubjJlJFDkhTuA7PUldWglvagI,2044
|
86
86
|
ingestr/src/linkedin_ads/__init__.py,sha256=CAPWFyV24loziiphbLmODxZUXZJwm4JxlFkr56q0jfo,1855
|
87
87
|
ingestr/src/linkedin_ads/dimension_time_enum.py,sha256=EmHRdkFyTAfo4chGjThrwqffWJxmAadZMbpTvf0xkQc,198
|
88
88
|
ingestr/src/linkedin_ads/helpers.py,sha256=eUWudRVlXl4kqIhfXQ1eVsUpZwJn7UFqKSpnbLfxzds,4498
|
@@ -117,12 +117,12 @@ ingestr/src/slack/__init__.py,sha256=pyDukxcilqTAe_bBzfWJ8Vxi83S-XEdEFBH2pEgILrM
|
|
117
117
|
ingestr/src/slack/helpers.py,sha256=08TLK7vhFvH_uekdLVOLF3bTDe1zgH0QxHObXHzk1a8,6545
|
118
118
|
ingestr/src/slack/settings.py,sha256=NhKn4y1zokEa5EmIZ05wtj_-I0GOASXZ5V81M1zXCtY,457
|
119
119
|
ingestr/src/smartsheets/__init__.py,sha256=pdzSV7rA0XYD5Xa1u4zb6vziy5iFXIQNROkpJ9oYas0,1623
|
120
|
-
ingestr/src/solidgate/__init__.py,sha256=
|
121
|
-
ingestr/src/solidgate/helpers.py,sha256=
|
120
|
+
ingestr/src/solidgate/__init__.py,sha256=as3m-lrs8teI3BW_8__5SY7BY8Af7SetzuU8Cj3L80U,8170
|
121
|
+
ingestr/src/solidgate/helpers.py,sha256=j8FjYHyUJTwkJ8VY8nre2qMesLeRq3eTwU22Ff-2K8M,5426
|
122
122
|
ingestr/src/sql_database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
123
123
|
ingestr/src/sql_database/callbacks.py,sha256=sEFFmXxAURY3yeBjnawigDtq9LBCvi8HFqG4kLd7tMU,2002
|
124
124
|
ingestr/src/stripe_analytics/__init__.py,sha256=mK8dGKAlMPVqGE9gG30XfbvOvgVD0yWhNpt-D3iavDY,6385
|
125
|
-
ingestr/src/stripe_analytics/helpers.py,sha256=
|
125
|
+
ingestr/src/stripe_analytics/helpers.py,sha256=KGtRcSrhKEqzJ3AWpgDV2o4cuBFaIwu2Gc1KgvVWTtg,11764
|
126
126
|
ingestr/src/stripe_analytics/settings.py,sha256=xt1-ljwP4nLTNUa8l3KwFbtK8FtQHgHpzGF5uPKfRsw,2246
|
127
127
|
ingestr/src/telemetry/event.py,sha256=W7bs4uVfPakQ5otmiqgqu1l5SqjYx1p87wudnWXckBc,949
|
128
128
|
ingestr/src/testdata/fakebqcredentials.json,sha256=scc6TUc963KAbKTLZCfcmqVzbtzDCW1_8JNRnyAXyy8,628
|
@@ -136,8 +136,8 @@ ingestr/src/zendesk/helpers/__init__.py,sha256=YTJejCiUjfIcsj9FrkY0l-JGYDI7RRte1
|
|
136
136
|
ingestr/src/zendesk/helpers/api_helpers.py,sha256=dMkNn4ZQXgJTDOXAAXdmRt41phNFoRhYyPaLJih0pZY,4184
|
137
137
|
ingestr/src/zendesk/helpers/credentials.py,sha256=EWyi0ZlxWFgd1huD86KNF4dApLHgmabqWksFpEg1cf0,1332
|
138
138
|
ingestr/src/zendesk/helpers/talk_api.py,sha256=TSVSOErsBZvxcX91LMhAgvy6yLSYvpuVfOyKViOHtvA,4718
|
139
|
-
ingestr/src/zoom/__init__.py,sha256=
|
140
|
-
ingestr/src/zoom/helpers.py,sha256=
|
139
|
+
ingestr/src/zoom/__init__.py,sha256=hgx_27kQTE9p26cXdp6yE6x5tjw0g8gY5pTB1qeg4L0,3264
|
140
|
+
ingestr/src/zoom/helpers.py,sha256=jJuBkiK8OEUVYnulbemIFOO5rfg_iKI-7wql8hGNbZ0,3715
|
141
141
|
ingestr/testdata/.gitignore,sha256=DFzYYOpqdTiT7S1HjCT-jffZSmEvFZge295_upAB0FY,13
|
142
142
|
ingestr/testdata/create_replace.csv,sha256=TQDbOSkRKq9ZZv1d68Qjwh94aIyUQ-oEwxpJIrd3YK8,1060
|
143
143
|
ingestr/testdata/delete_insert_expected.csv,sha256=wbj7uboVWwm3sNMh1n7f4-OKFEQJv1s96snjEHp9nkg,336
|
@@ -147,8 +147,8 @@ ingestr/testdata/merge_expected.csv,sha256=DReHqWGnQMsf2PBv_Q2pfjsgvikYFnf1zYcQZ
|
|
147
147
|
ingestr/testdata/merge_part1.csv,sha256=Pw8Z9IDKcNU0qQHx1z6BUf4rF_-SxKGFOvymCt4OY9I,185
|
148
148
|
ingestr/testdata/merge_part2.csv,sha256=T_GiWxA81SN63_tMOIuemcvboEFeAmbKc7xRXvL9esw,287
|
149
149
|
ingestr/tests/unit/test_smartsheets.py,sha256=eiC2CCO4iNJcuN36ONvqmEDryCA1bA1REpayHpu42lk,5058
|
150
|
-
ingestr-0.13.
|
151
|
-
ingestr-0.13.
|
152
|
-
ingestr-0.13.
|
153
|
-
ingestr-0.13.
|
154
|
-
ingestr-0.13.
|
150
|
+
ingestr-0.13.69.dist-info/METADATA,sha256=DNrbX4KACx_XBhLJuMTig_hG3m_jjPw9GQrOXlsG6BQ,15022
|
151
|
+
ingestr-0.13.69.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
152
|
+
ingestr-0.13.69.dist-info/entry_points.txt,sha256=oPJy0KBnPWYjDtP1k8qwAihcTLHSZokSQvRAw_wtfJM,46
|
153
|
+
ingestr-0.13.69.dist-info/licenses/LICENSE.md,sha256=cW8wIhn8HFE-KLStDF9jHQ1O_ARWP3kTpk_-eOccL24,1075
|
154
|
+
ingestr-0.13.69.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|