ingestr 0.14.93__py3-none-any.whl → 0.14.98__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.
Potentially problematic release.
This version of ingestr might be problematic. Click here for more details.
- ingestr/src/buildinfo.py +1 -1
- ingestr/src/couchbase_source/__init__.py +118 -0
- ingestr/src/couchbase_source/helpers.py +135 -0
- ingestr/src/cursor/__init__.py +83 -0
- ingestr/src/cursor/helpers.py +188 -0
- ingestr/src/factory.py +8 -0
- ingestr/src/hostaway/__init__.py +302 -0
- ingestr/src/hostaway/client.py +288 -0
- ingestr/src/revenuecat/__init__.py +16 -41
- ingestr/src/revenuecat/helpers.py +19 -73
- ingestr/src/socrata_source/__init__.py +83 -0
- ingestr/src/socrata_source/helpers.py +85 -0
- ingestr/src/socrata_source/settings.py +8 -0
- ingestr/src/sources.py +395 -0
- {ingestr-0.14.93.dist-info → ingestr-0.14.98.dist-info}/METADATA +2 -1
- {ingestr-0.14.93.dist-info → ingestr-0.14.98.dist-info}/RECORD +19 -10
- {ingestr-0.14.93.dist-info → ingestr-0.14.98.dist-info}/WHEEL +0 -0
- {ingestr-0.14.93.dist-info → ingestr-0.14.98.dist-info}/entry_points.txt +0 -0
- {ingestr-0.14.93.dist-info → ingestr-0.14.98.dist-info}/licenses/LICENSE.md +0 -0
ingestr/src/sources.py
CHANGED
|
@@ -4066,3 +4066,398 @@ class AlliumSource:
|
|
|
4066
4066
|
limit=limit,
|
|
4067
4067
|
compute_profile=compute_profile,
|
|
4068
4068
|
)
|
|
4069
|
+
|
|
4070
|
+
|
|
4071
|
+
class CouchbaseSource:
|
|
4072
|
+
table_builder: Callable
|
|
4073
|
+
|
|
4074
|
+
def __init__(self, table_builder=None) -> None:
|
|
4075
|
+
if table_builder is None:
|
|
4076
|
+
from ingestr.src.couchbase_source import couchbase_collection
|
|
4077
|
+
|
|
4078
|
+
table_builder = couchbase_collection
|
|
4079
|
+
|
|
4080
|
+
self.table_builder = table_builder
|
|
4081
|
+
|
|
4082
|
+
def handles_incrementality(self) -> bool:
|
|
4083
|
+
return False
|
|
4084
|
+
|
|
4085
|
+
def dlt_source(self, uri: str, table: str, **kwargs):
|
|
4086
|
+
"""
|
|
4087
|
+
Create a dlt source for reading data from Couchbase.
|
|
4088
|
+
|
|
4089
|
+
URI formats:
|
|
4090
|
+
- couchbase://username:password@host
|
|
4091
|
+
- couchbase://username:password@host/bucket
|
|
4092
|
+
- couchbase://username:password@host?ssl=true
|
|
4093
|
+
- couchbases://username:password@host (SSL enabled)
|
|
4094
|
+
|
|
4095
|
+
Table formats:
|
|
4096
|
+
- bucket.scope.collection (when bucket not in URI)
|
|
4097
|
+
- scope.collection (when bucket specified in URI path)
|
|
4098
|
+
|
|
4099
|
+
Note: If password contains special characters (@, :, /, etc.), they must be URL-encoded.
|
|
4100
|
+
|
|
4101
|
+
Examples:
|
|
4102
|
+
Local/Self-hosted:
|
|
4103
|
+
- couchbase://admin:password123@localhost with table "mybucket.myscope.mycollection"
|
|
4104
|
+
- couchbase://admin:password123@localhost/mybucket with table "myscope.mycollection"
|
|
4105
|
+
- couchbase://admin:password123@localhost?ssl=true with table "mybucket._default._default"
|
|
4106
|
+
|
|
4107
|
+
Capella (Cloud):
|
|
4108
|
+
- couchbases://user:pass@cb.xxx.cloud.couchbase.com with table "travel-sample.inventory.airport"
|
|
4109
|
+
- couchbase://user:pass@cb.xxx.cloud.couchbase.com/travel-sample?ssl=true with table "inventory.airport"
|
|
4110
|
+
|
|
4111
|
+
To encode password in Python:
|
|
4112
|
+
from urllib.parse import quote
|
|
4113
|
+
encoded_pwd = quote("MyPass@123!", safe='')
|
|
4114
|
+
uri = f"couchbase://admin:{encoded_pwd}@localhost?ssl=true"
|
|
4115
|
+
|
|
4116
|
+
Args:
|
|
4117
|
+
uri: Couchbase connection URI (can include /bucket path and ?ssl=true query parameter)
|
|
4118
|
+
table: Format depends on URI:
|
|
4119
|
+
- bucket.scope.collection (if bucket not in URI)
|
|
4120
|
+
- scope.collection (if bucket in URI path)
|
|
4121
|
+
**kwargs: Additional arguments:
|
|
4122
|
+
- limit: Maximum number of documents to fetch
|
|
4123
|
+
- incremental_key: Field to use for incremental loading
|
|
4124
|
+
- interval_start: Start value for incremental loading
|
|
4125
|
+
- interval_end: End value for incremental loading
|
|
4126
|
+
|
|
4127
|
+
Returns:
|
|
4128
|
+
DltResource for the Couchbase collection
|
|
4129
|
+
"""
|
|
4130
|
+
# Parse the URI to extract connection details
|
|
4131
|
+
# urlparse automatically decodes URL-encoded credentials
|
|
4132
|
+
|
|
4133
|
+
parsed = urlparse(uri)
|
|
4134
|
+
|
|
4135
|
+
# Extract username and password from URI
|
|
4136
|
+
# Note: urlparse automatically decodes URL-encoded characters in username/password
|
|
4137
|
+
from urllib.parse import unquote
|
|
4138
|
+
|
|
4139
|
+
username = parsed.username
|
|
4140
|
+
password = unquote(parsed.password) if parsed.password else None
|
|
4141
|
+
|
|
4142
|
+
if not username or not password:
|
|
4143
|
+
raise ValueError(
|
|
4144
|
+
"Username and password must be provided in the URI.\n"
|
|
4145
|
+
"Format: couchbase://username:password@host\n"
|
|
4146
|
+
"If password has special characters (@, :, /), URL-encode them.\n"
|
|
4147
|
+
"Example: couchbase://admin:MyPass%40123@localhost for password 'MyPass@123'"
|
|
4148
|
+
)
|
|
4149
|
+
|
|
4150
|
+
# Reconstruct connection string without credentials
|
|
4151
|
+
scheme = parsed.scheme
|
|
4152
|
+
netloc = parsed.netloc
|
|
4153
|
+
|
|
4154
|
+
# Remove username:password@ from netloc if present
|
|
4155
|
+
if "@" in netloc:
|
|
4156
|
+
netloc = netloc.split("@", 1)[1]
|
|
4157
|
+
|
|
4158
|
+
# Parse query parameters from URI
|
|
4159
|
+
from urllib.parse import parse_qs
|
|
4160
|
+
|
|
4161
|
+
query_params = parse_qs(parsed.query)
|
|
4162
|
+
|
|
4163
|
+
# Check if SSL is requested via URI query parameter (?ssl=true)
|
|
4164
|
+
if "ssl" in query_params:
|
|
4165
|
+
ssl_value = query_params["ssl"][0].lower()
|
|
4166
|
+
use_ssl = ssl_value in ("true", "1", "yes")
|
|
4167
|
+
|
|
4168
|
+
# Apply SSL scheme based on parameter
|
|
4169
|
+
if use_ssl and scheme == "couchbase":
|
|
4170
|
+
scheme = "couchbases"
|
|
4171
|
+
|
|
4172
|
+
connection_string = f"{scheme}://{netloc}"
|
|
4173
|
+
|
|
4174
|
+
# Extract bucket from URI path if present (e.g., couchbase://host/bucket)
|
|
4175
|
+
bucket_from_uri = None
|
|
4176
|
+
if parsed.path and parsed.path.strip("/"):
|
|
4177
|
+
bucket_from_uri = parsed.path.strip("/").split("/")[0]
|
|
4178
|
+
|
|
4179
|
+
# Parse table format: can be "scope.collection" or "bucket.scope.collection"
|
|
4180
|
+
table_parts = table.split(".")
|
|
4181
|
+
|
|
4182
|
+
if len(table_parts) == 3:
|
|
4183
|
+
# Format: bucket.scope.collection
|
|
4184
|
+
bucket, scope, collection = table_parts
|
|
4185
|
+
elif len(table_parts) == 2:
|
|
4186
|
+
# Format: scope.collection (bucket from URI)
|
|
4187
|
+
if bucket_from_uri:
|
|
4188
|
+
bucket = bucket_from_uri
|
|
4189
|
+
scope, collection = table_parts
|
|
4190
|
+
else:
|
|
4191
|
+
raise ValueError(
|
|
4192
|
+
"Table format is 'scope.collection' but no bucket specified in URI.\n"
|
|
4193
|
+
f"Either use URI format: couchbase://user:pass@host/bucket\n"
|
|
4194
|
+
f"Or use table format: bucket.scope.collection\n"
|
|
4195
|
+
f"Got table: {table}"
|
|
4196
|
+
)
|
|
4197
|
+
else:
|
|
4198
|
+
raise ValueError(
|
|
4199
|
+
"Table format must be 'bucket.scope.collection' or 'scope.collection' (with bucket in URI). "
|
|
4200
|
+
f"Got: {table}\n"
|
|
4201
|
+
"Examples:\n"
|
|
4202
|
+
" - URI: couchbase://user:pass@host, Table: travel-sample.inventory.airport\n"
|
|
4203
|
+
" - URI: couchbase://user:pass@host/travel-sample, Table: inventory.airport"
|
|
4204
|
+
)
|
|
4205
|
+
|
|
4206
|
+
# Handle incremental loading
|
|
4207
|
+
incremental = None
|
|
4208
|
+
if kwargs.get("incremental_key"):
|
|
4209
|
+
start_value = kwargs.get("interval_start")
|
|
4210
|
+
end_value = kwargs.get("interval_end")
|
|
4211
|
+
|
|
4212
|
+
incremental = dlt_incremental(
|
|
4213
|
+
kwargs.get("incremental_key", ""),
|
|
4214
|
+
initial_value=start_value,
|
|
4215
|
+
end_value=end_value,
|
|
4216
|
+
range_end="closed",
|
|
4217
|
+
range_start="closed",
|
|
4218
|
+
)
|
|
4219
|
+
|
|
4220
|
+
# Get optional parameters
|
|
4221
|
+
limit = kwargs.get("limit")
|
|
4222
|
+
|
|
4223
|
+
table_instance = self.table_builder(
|
|
4224
|
+
connection_string=connection_string,
|
|
4225
|
+
username=username,
|
|
4226
|
+
password=password,
|
|
4227
|
+
bucket=bucket,
|
|
4228
|
+
scope=scope,
|
|
4229
|
+
collection=collection,
|
|
4230
|
+
incremental=incremental,
|
|
4231
|
+
limit=limit,
|
|
4232
|
+
)
|
|
4233
|
+
table_instance.max_table_nesting = 1
|
|
4234
|
+
|
|
4235
|
+
return table_instance
|
|
4236
|
+
|
|
4237
|
+
|
|
4238
|
+
class CursorSource:
|
|
4239
|
+
resources = [
|
|
4240
|
+
"team_members",
|
|
4241
|
+
"daily_usage_data",
|
|
4242
|
+
"team_spend",
|
|
4243
|
+
"filtered_usage_events",
|
|
4244
|
+
]
|
|
4245
|
+
|
|
4246
|
+
def handles_incrementality(self) -> bool:
|
|
4247
|
+
return True
|
|
4248
|
+
|
|
4249
|
+
def dlt_source(self, uri: str, table: str, **kwargs):
|
|
4250
|
+
# cursor://?api_key=<api_key>
|
|
4251
|
+
parsed_uri = urlparse(uri)
|
|
4252
|
+
params = parse_qs(parsed_uri.query)
|
|
4253
|
+
|
|
4254
|
+
api_key = params.get("api_key")
|
|
4255
|
+
|
|
4256
|
+
if not api_key:
|
|
4257
|
+
raise MissingValueError("api_key", "Cursor")
|
|
4258
|
+
|
|
4259
|
+
if table not in self.resources:
|
|
4260
|
+
raise UnsupportedResourceError(table, "Cursor")
|
|
4261
|
+
|
|
4262
|
+
import dlt
|
|
4263
|
+
|
|
4264
|
+
from ingestr.src.cursor import cursor_source
|
|
4265
|
+
|
|
4266
|
+
dlt.secrets["sources.cursor.api_key"] = api_key[0]
|
|
4267
|
+
|
|
4268
|
+
# Handle interval_start and interval_end for daily_usage_data and filtered_usage_events (optional)
|
|
4269
|
+
if table in ["daily_usage_data", "filtered_usage_events"]:
|
|
4270
|
+
interval_start = kwargs.get("interval_start")
|
|
4271
|
+
interval_end = kwargs.get("interval_end")
|
|
4272
|
+
|
|
4273
|
+
# Both are optional, but if one is provided, both should be provided
|
|
4274
|
+
if interval_start is not None and interval_end is not None:
|
|
4275
|
+
# Convert datetime to epoch milliseconds
|
|
4276
|
+
start_ms = int(interval_start.timestamp() * 1000)
|
|
4277
|
+
end_ms = int(interval_end.timestamp() * 1000)
|
|
4278
|
+
|
|
4279
|
+
dlt.config["sources.cursor.start_date"] = start_ms
|
|
4280
|
+
dlt.config["sources.cursor.end_date"] = end_ms
|
|
4281
|
+
|
|
4282
|
+
src = cursor_source()
|
|
4283
|
+
return src.with_resources(table)
|
|
4284
|
+
|
|
4285
|
+
|
|
4286
|
+
class SocrataSource:
|
|
4287
|
+
def handles_incrementality(self) -> bool:
|
|
4288
|
+
return False
|
|
4289
|
+
|
|
4290
|
+
def dlt_source(self, uri: str, table: str, **kwargs):
|
|
4291
|
+
"""
|
|
4292
|
+
Creates a DLT source for Socrata open data platform.
|
|
4293
|
+
|
|
4294
|
+
URI format: socrata://domain?app_token=TOKEN
|
|
4295
|
+
Table: dataset_id (e.g., "6udu-fhnu")
|
|
4296
|
+
|
|
4297
|
+
Args:
|
|
4298
|
+
uri: Socrata connection URI with domain and optional auth params
|
|
4299
|
+
table: Dataset ID (e.g., "6udu-fhnu")
|
|
4300
|
+
**kwargs: Additional arguments:
|
|
4301
|
+
- incremental_key: Field to use for incremental loading (e.g., ":updated_at")
|
|
4302
|
+
- interval_start: Start date for initial load
|
|
4303
|
+
- interval_end: End date for load
|
|
4304
|
+
- primary_key: Primary key field for merge operations
|
|
4305
|
+
|
|
4306
|
+
Returns:
|
|
4307
|
+
DltResource for the Socrata dataset
|
|
4308
|
+
"""
|
|
4309
|
+
from urllib.parse import parse_qs, urlparse
|
|
4310
|
+
|
|
4311
|
+
parsed = urlparse(uri)
|
|
4312
|
+
|
|
4313
|
+
domain = parsed.netloc
|
|
4314
|
+
if not domain:
|
|
4315
|
+
raise ValueError(
|
|
4316
|
+
"Domain must be provided in the URI.\n"
|
|
4317
|
+
"Format: socrata://domain?app_token=TOKEN\n"
|
|
4318
|
+
"Example: socrata://evergreen.data.socrata.com?app_token=mytoken"
|
|
4319
|
+
)
|
|
4320
|
+
|
|
4321
|
+
query_params = parse_qs(parsed.query)
|
|
4322
|
+
|
|
4323
|
+
dataset_id = table
|
|
4324
|
+
if not dataset_id:
|
|
4325
|
+
raise ValueError(
|
|
4326
|
+
"Dataset ID must be provided as the table parameter.\n"
|
|
4327
|
+
"Example: --source-table 6udu-fhnu"
|
|
4328
|
+
)
|
|
4329
|
+
|
|
4330
|
+
app_token = query_params.get("app_token", [None])[0]
|
|
4331
|
+
username = query_params.get("username", [None])[0]
|
|
4332
|
+
password = query_params.get("password", [None])[0]
|
|
4333
|
+
|
|
4334
|
+
incremental = None
|
|
4335
|
+
if kwargs.get("incremental_key"):
|
|
4336
|
+
start_value = kwargs.get("interval_start")
|
|
4337
|
+
end_value = kwargs.get("interval_end")
|
|
4338
|
+
|
|
4339
|
+
if start_value:
|
|
4340
|
+
start_value = (
|
|
4341
|
+
start_value.isoformat()
|
|
4342
|
+
if hasattr(start_value, "isoformat")
|
|
4343
|
+
else str(start_value)
|
|
4344
|
+
)
|
|
4345
|
+
|
|
4346
|
+
if end_value:
|
|
4347
|
+
end_value = (
|
|
4348
|
+
end_value.isoformat()
|
|
4349
|
+
if hasattr(end_value, "isoformat")
|
|
4350
|
+
else str(end_value)
|
|
4351
|
+
)
|
|
4352
|
+
|
|
4353
|
+
incremental = dlt_incremental(
|
|
4354
|
+
kwargs.get("incremental_key", ""),
|
|
4355
|
+
initial_value=start_value,
|
|
4356
|
+
end_value=end_value,
|
|
4357
|
+
range_end="open",
|
|
4358
|
+
range_start="closed",
|
|
4359
|
+
)
|
|
4360
|
+
|
|
4361
|
+
primary_key = kwargs.get("primary_key")
|
|
4362
|
+
|
|
4363
|
+
from ingestr.src.socrata_source import source
|
|
4364
|
+
|
|
4365
|
+
return source(
|
|
4366
|
+
domain=domain,
|
|
4367
|
+
dataset_id=dataset_id,
|
|
4368
|
+
app_token=app_token,
|
|
4369
|
+
username=username,
|
|
4370
|
+
password=password,
|
|
4371
|
+
incremental=incremental,
|
|
4372
|
+
primary_key=primary_key,
|
|
4373
|
+
).with_resources("dataset")
|
|
4374
|
+
|
|
4375
|
+
|
|
4376
|
+
class HostawaySource:
|
|
4377
|
+
def handles_incrementality(self) -> bool:
|
|
4378
|
+
return True
|
|
4379
|
+
|
|
4380
|
+
def dlt_source(self, uri: str, table: str, **kwargs):
|
|
4381
|
+
if kwargs.get("incremental_key"):
|
|
4382
|
+
raise ValueError(
|
|
4383
|
+
"Hostaway takes care of incrementality on its own, you should not provide incremental_key"
|
|
4384
|
+
)
|
|
4385
|
+
|
|
4386
|
+
source_parts = urlparse(uri)
|
|
4387
|
+
source_params = parse_qs(source_parts.query)
|
|
4388
|
+
api_key = source_params.get("api_key")
|
|
4389
|
+
|
|
4390
|
+
if not api_key:
|
|
4391
|
+
raise ValueError("api_key in the URI is required to connect to Hostaway")
|
|
4392
|
+
|
|
4393
|
+
match table:
|
|
4394
|
+
case "listings":
|
|
4395
|
+
resource_name = "listings"
|
|
4396
|
+
case "listing_fee_settings":
|
|
4397
|
+
resource_name = "listing_fee_settings"
|
|
4398
|
+
case "listing_agreements":
|
|
4399
|
+
resource_name = "listing_agreements"
|
|
4400
|
+
case "listing_pricing_settings":
|
|
4401
|
+
resource_name = "listing_pricing_settings"
|
|
4402
|
+
case "cancellation_policies":
|
|
4403
|
+
resource_name = "cancellation_policies"
|
|
4404
|
+
case "cancellation_policies_airbnb":
|
|
4405
|
+
resource_name = "cancellation_policies_airbnb"
|
|
4406
|
+
case "cancellation_policies_marriott":
|
|
4407
|
+
resource_name = "cancellation_policies_marriott"
|
|
4408
|
+
case "cancellation_policies_vrbo":
|
|
4409
|
+
resource_name = "cancellation_policies_vrbo"
|
|
4410
|
+
case "reservations":
|
|
4411
|
+
resource_name = "reservations"
|
|
4412
|
+
case "finance_fields":
|
|
4413
|
+
resource_name = "finance_fields"
|
|
4414
|
+
case "reservation_payment_methods":
|
|
4415
|
+
resource_name = "reservation_payment_methods"
|
|
4416
|
+
case "reservation_rental_agreements":
|
|
4417
|
+
resource_name = "reservation_rental_agreements"
|
|
4418
|
+
case "listing_calendars":
|
|
4419
|
+
resource_name = "listing_calendars"
|
|
4420
|
+
case "conversations":
|
|
4421
|
+
resource_name = "conversations"
|
|
4422
|
+
case "message_templates":
|
|
4423
|
+
resource_name = "message_templates"
|
|
4424
|
+
case "bed_types":
|
|
4425
|
+
resource_name = "bed_types"
|
|
4426
|
+
case "property_types":
|
|
4427
|
+
resource_name = "property_types"
|
|
4428
|
+
case "countries":
|
|
4429
|
+
resource_name = "countries"
|
|
4430
|
+
case "account_tax_settings":
|
|
4431
|
+
resource_name = "account_tax_settings"
|
|
4432
|
+
case "user_groups":
|
|
4433
|
+
resource_name = "user_groups"
|
|
4434
|
+
case "guest_payment_charges":
|
|
4435
|
+
resource_name = "guest_payment_charges"
|
|
4436
|
+
case "coupons":
|
|
4437
|
+
resource_name = "coupons"
|
|
4438
|
+
case "webhook_reservations":
|
|
4439
|
+
resource_name = "webhook_reservations"
|
|
4440
|
+
case "tasks":
|
|
4441
|
+
resource_name = "tasks"
|
|
4442
|
+
case _:
|
|
4443
|
+
raise ValueError(
|
|
4444
|
+
f"Resource '{table}' is not supported for Hostaway source yet, if you are interested in it please create a GitHub issue at https://github.com/bruin-data/ingestr"
|
|
4445
|
+
)
|
|
4446
|
+
|
|
4447
|
+
start_date = kwargs.get("interval_start")
|
|
4448
|
+
if start_date:
|
|
4449
|
+
start_date = ensure_pendulum_datetime(start_date).in_timezone("UTC")
|
|
4450
|
+
else:
|
|
4451
|
+
start_date = pendulum.datetime(1970, 1, 1).in_timezone("UTC")
|
|
4452
|
+
|
|
4453
|
+
end_date = kwargs.get("interval_end")
|
|
4454
|
+
if end_date:
|
|
4455
|
+
end_date = ensure_pendulum_datetime(end_date).in_timezone("UTC")
|
|
4456
|
+
|
|
4457
|
+
from ingestr.src.hostaway import hostaway_source
|
|
4458
|
+
|
|
4459
|
+
return hostaway_source(
|
|
4460
|
+
api_key=api_key[0],
|
|
4461
|
+
start_date=start_date,
|
|
4462
|
+
end_date=end_date,
|
|
4463
|
+
).with_resources(resource_name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ingestr
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.98
|
|
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
|
|
@@ -39,6 +39,7 @@ Requires-Dist: clickhouse-connect==0.8.14
|
|
|
39
39
|
Requires-Dist: clickhouse-driver==0.2.9
|
|
40
40
|
Requires-Dist: clickhouse-sqlalchemy==0.2.7
|
|
41
41
|
Requires-Dist: confluent-kafka==2.8.0
|
|
42
|
+
Requires-Dist: couchbase==4.3.6
|
|
42
43
|
Requires-Dist: crate==2.0.0
|
|
43
44
|
Requires-Dist: cryptography==44.0.2
|
|
44
45
|
Requires-Dist: curlify==2.2.1
|
|
@@ -2,17 +2,17 @@ ingestr/conftest.py,sha256=OE2yxeTCosS9CUFVuqNypm-2ftYvVBeeq7egm3878cI,1981
|
|
|
2
2
|
ingestr/main.py,sha256=qo0g3wCFl8a_1jUwXagX8L1Q8PKKQlTF7md9pfnzW0Y,27155
|
|
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=
|
|
5
|
+
ingestr/src/buildinfo.py,sha256=KNsPSfI9LisbrdhHPJs5mXHNNECHiURo6eMddW-GXEA,21
|
|
6
6
|
ingestr/src/destinations.py,sha256=QtjE0AGs0WkPHaI2snWPHJ8HHi4lwXUBYLJPklz8Mvk,27772
|
|
7
7
|
ingestr/src/errors.py,sha256=fhJ2BxOqOsBfOxuTDKfZblvawBrPG3x_1VikIxMZBRI,874
|
|
8
|
-
ingestr/src/factory.py,sha256=
|
|
8
|
+
ingestr/src/factory.py,sha256=J1j5l8Sr-rY1IEUP08HY1iT3NysNOx6Y3gz3g06vq2I,7988
|
|
9
9
|
ingestr/src/filters.py,sha256=0n0sNAVG_f-B_1r7lW5iNtw9z_G1bxWzPaiL1i6tnbU,1665
|
|
10
10
|
ingestr/src/http_client.py,sha256=bxqsk6nJNXCo-79gW04B53DQO-yr25vaSsqP0AKtjx4,732
|
|
11
11
|
ingestr/src/loader.py,sha256=9NaWAyfkXdqAZSS-N72Iwo36Lbx4PyqIfaaH1dNdkFs,1712
|
|
12
12
|
ingestr/src/masking.py,sha256=VN0LdfvExhQ1bZMRylGtaBUIoH-vjuIUmRnYKwo3yiY,11358
|
|
13
13
|
ingestr/src/partition.py,sha256=BrIP6wFJvyR7Nus_3ElnfxknUXeCipK_E_bB8kZowfc,969
|
|
14
14
|
ingestr/src/resource.py,sha256=ZqmZxFQVGlF8rFPhBiUB08HES0yoTj8sZ--jKfaaVps,1164
|
|
15
|
-
ingestr/src/sources.py,sha256=
|
|
15
|
+
ingestr/src/sources.py,sha256=jEJjJOcdpSRIztf355uaKanzAbj6GoJxlz4vSERW6KU,157053
|
|
16
16
|
ingestr/src/table_definition.py,sha256=REbAbqdlmUMUuRh8nEQRreWjPVOQ5ZcfqGkScKdCrmk,390
|
|
17
17
|
ingestr/src/time.py,sha256=H_Fk2J4ShXyUM-EMY7MqCLZQhlnZMZvO952bmZPc4yE,254
|
|
18
18
|
ingestr/src/version.py,sha256=J_2xgZ0mKlvuHcjdKCx2nlioneLH0I47JiU_Slr_Nwc,189
|
|
@@ -43,6 +43,10 @@ ingestr/src/chess/settings.py,sha256=p0RlCGgtXUacPDEvZmwzSWmzX0Apj1riwfz-nrMK89k
|
|
|
43
43
|
ingestr/src/clickup/__init__.py,sha256=uvfAqNturT4bMvU4NS3E8BdL6nvDFzNuh7bMlih8HJk,2547
|
|
44
44
|
ingestr/src/clickup/helpers.py,sha256=RzDKMUAHccuDhocIQ2ToBXfCERo8CBJqA3t-IPltBCE,1519
|
|
45
45
|
ingestr/src/collector/spinner.py,sha256=_ZUqF5MI43hVIULdjF5s5mrAZbhEFXaiWirQmrv3Yk4,1201
|
|
46
|
+
ingestr/src/couchbase_source/__init__.py,sha256=IPmb55mBxGWtt_9ywbY6chAwUp6jRmJTu-qEVFBhJ_s,4381
|
|
47
|
+
ingestr/src/couchbase_source/helpers.py,sha256=RA0aFT0GfLJ2pHy7emvKmm0yVXgQOQ-hMVJvw-FExNo,4487
|
|
48
|
+
ingestr/src/cursor/__init__.py,sha256=sNVzCzIT9FxC3Q0Otydjg2_cCjj7HjRlT2u_7xfsx1o,1914
|
|
49
|
+
ingestr/src/cursor/helpers.py,sha256=gaNBA1uZJJCx0rGOfg5IMLtqLxQA1QulEi5t4qf2vbo,5781
|
|
46
50
|
ingestr/src/docebo/__init__.py,sha256=RBBjlt405PIIDOLEt78g9yBNJfhUMeJxR5DZD7oufXY,27543
|
|
47
51
|
ingestr/src/docebo/client.py,sha256=nki0kNQhN8VDz5cdqlQQPhr1JMPlcNEYKnWK3umAyOc,15663
|
|
48
52
|
ingestr/src/docebo/helpers.py,sha256=SaEjta6k3Lj-S5fvrheA5_xj7zfASMdOc_ihsqno5ko,3238
|
|
@@ -84,6 +88,8 @@ ingestr/src/google_sheets/helpers/api_calls.py,sha256=RiVfdacbaneszhmuhYilkJnkc9
|
|
|
84
88
|
ingestr/src/google_sheets/helpers/data_processing.py,sha256=RNt2MYfdJhk4bRahnQVezpNg2x9z0vx60YFq2ukZ8vI,11004
|
|
85
89
|
ingestr/src/gorgias/__init__.py,sha256=_mFkMYwlY5OKEY0o_FK1OKol03A-8uk7bm1cKlmt5cs,21432
|
|
86
90
|
ingestr/src/gorgias/helpers.py,sha256=DamuijnvhGY9hysQO4txrVMf4izkGbh5qfBKImdOINE,5427
|
|
91
|
+
ingestr/src/hostaway/__init__.py,sha256=sq7qG5J4XcyoYoHBSgAszYPByN9bMLzWjhSmvzJuTeI,8887
|
|
92
|
+
ingestr/src/hostaway/client.py,sha256=omzoT4gPQ_nvMWDcm7-bm2AyFwwRDgV8D1sI0gkkydw,10452
|
|
87
93
|
ingestr/src/http/__init__.py,sha256=Y9mQIE0RolHOh6dPjW41qzYXSG8BC0GPKxEtz2CJGpU,902
|
|
88
94
|
ingestr/src/http/readers.py,sha256=rgBwYG5SOQ7P2uzBAFMOQIevKxV51ZW41VSiRTZ0Xvo,3863
|
|
89
95
|
ingestr/src/hubspot/__init__.py,sha256=FCqjLeOjijdc9JC_NoDwtRqy3FDyY-szDi6UV7CdDN0,11548
|
|
@@ -140,8 +146,8 @@ ingestr/src/plusvibeai/__init__.py,sha256=Uo-N2-1kbq5RJw8ym5tm8rqVchVbJJ2hOd6bws
|
|
|
140
146
|
ingestr/src/plusvibeai/helpers.py,sha256=5hxxA2-XUtkZA1xrstZ39ilzUh4EouNDOiiL-NzGu9w,17939
|
|
141
147
|
ingestr/src/plusvibeai/settings.py,sha256=3Hb7jcUNshSlGO4E27yUe_8n3f0VArX9XTmkTkN-Tvo,5366
|
|
142
148
|
ingestr/src/quickbooks/__init__.py,sha256=cZUuVCOTGPHTscRj6i0DytO63_fWF-4ieMxoU4PcyTg,3727
|
|
143
|
-
ingestr/src/revenuecat/__init__.py,sha256=
|
|
144
|
-
ingestr/src/revenuecat/helpers.py,sha256=
|
|
149
|
+
ingestr/src/revenuecat/__init__.py,sha256=j75jkHBqd_9FsFKjsSLLwKrPcmUKOE3HJ95Qzonzmbk,2779
|
|
150
|
+
ingestr/src/revenuecat/helpers.py,sha256=ej_bR6cuNOer4bTQfd_IuyMmt-xevcPgvRShKlxO8Xo,7998
|
|
145
151
|
ingestr/src/salesforce/__init__.py,sha256=Ijveo8gyo_wLzQRBklxIm3RV0y2Gta9-mR44RbJljpI,4901
|
|
146
152
|
ingestr/src/salesforce/helpers.py,sha256=QTdazBt-qRTBbCQMZnyclIaDQFmBixBy_RDKD00Lt-8,2492
|
|
147
153
|
ingestr/src/shopify/__init__.py,sha256=RzSSG93g-Qlkz6TAxi1XasFDdxxtVXIo53ZTtjGczW4,62602
|
|
@@ -152,6 +158,9 @@ ingestr/src/slack/__init__.py,sha256=pyDukxcilqTAe_bBzfWJ8Vxi83S-XEdEFBH2pEgILrM
|
|
|
152
158
|
ingestr/src/slack/helpers.py,sha256=08TLK7vhFvH_uekdLVOLF3bTDe1zgH0QxHObXHzk1a8,6545
|
|
153
159
|
ingestr/src/slack/settings.py,sha256=NhKn4y1zokEa5EmIZ05wtj_-I0GOASXZ5V81M1zXCtY,457
|
|
154
160
|
ingestr/src/smartsheets/__init__.py,sha256=RIEfN1T2TMFg8T0RvN4o6sqC58YusJRDrmE9Isos5P4,2375
|
|
161
|
+
ingestr/src/socrata_source/__init__.py,sha256=K5DVpsVXTMfunZd5YoEsn1nipfo1zavFS59g3m2tsc8,2984
|
|
162
|
+
ingestr/src/socrata_source/helpers.py,sha256=KbVojFSmMLXb0ajh8bhqfZfxDHH7rQ3nyI8p2jxVifA,2500
|
|
163
|
+
ingestr/src/socrata_source/settings.py,sha256=DLfu-4HOa5nR7h9tbOySEa2ye3w_Z6TYZ9_zPqWaNQk,220
|
|
155
164
|
ingestr/src/solidgate/__init__.py,sha256=Ts83j-JSnFsFuF4tDhVOfZKg7H0-bIpfn3kg1ZOR58A,8003
|
|
156
165
|
ingestr/src/solidgate/helpers.py,sha256=mAsW_1hpD7ab3Y2vw8fxHi4yD3aT1geLdIYZ7ycyxBc,5690
|
|
157
166
|
ingestr/src/sql_database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -184,8 +193,8 @@ ingestr/testdata/merge_expected.csv,sha256=DReHqWGnQMsf2PBv_Q2pfjsgvikYFnf1zYcQZ
|
|
|
184
193
|
ingestr/testdata/merge_part1.csv,sha256=Pw8Z9IDKcNU0qQHx1z6BUf4rF_-SxKGFOvymCt4OY9I,185
|
|
185
194
|
ingestr/testdata/merge_part2.csv,sha256=T_GiWxA81SN63_tMOIuemcvboEFeAmbKc7xRXvL9esw,287
|
|
186
195
|
ingestr/tests/unit/test_smartsheets.py,sha256=zf3DXT29Y4TH2lNPBFphdjlaelUUyPJcsW2UO68RzDs,4862
|
|
187
|
-
ingestr-0.14.
|
|
188
|
-
ingestr-0.14.
|
|
189
|
-
ingestr-0.14.
|
|
190
|
-
ingestr-0.14.
|
|
191
|
-
ingestr-0.14.
|
|
196
|
+
ingestr-0.14.98.dist-info/METADATA,sha256=0vOiSrADz46mM9t5ltLm_SLdbLxqd2NEjQmMjj9G2og,15359
|
|
197
|
+
ingestr-0.14.98.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
198
|
+
ingestr-0.14.98.dist-info/entry_points.txt,sha256=oPJy0KBnPWYjDtP1k8qwAihcTLHSZokSQvRAw_wtfJM,46
|
|
199
|
+
ingestr-0.14.98.dist-info/licenses/LICENSE.md,sha256=cW8wIhn8HFE-KLStDF9jHQ1O_ARWP3kTpk_-eOccL24,1075
|
|
200
|
+
ingestr-0.14.98.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|