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/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.93
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=gpczaxQtINGa_cWhMVJsfeFoUxh-gKIyba1YESpTmpk,21
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=k_8jgehOM2sHwCsjliYXmQhICl2B1UYoAs6vspjadv8,7770
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=D4VxA-yqilzTG0VBJBxnw9MUJ1Qeo2EpKjVGJfoMKoY,142289
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=5HbyZuEOekkbeeT72sM_bnGygSyYdmd_vczfAUz7xoM,4029
144
- ingestr/src/revenuecat/helpers.py,sha256=CYU6l79kplnfL87GfdxyGeEBrBSWEZfGP0GyjPHuVDk,9619
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.93.dist-info/METADATA,sha256=ttKTQKjoXX_xzXbQb2LisUnePWrFx5GXQf2dHCsG48g,15327
188
- ingestr-0.14.93.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
189
- ingestr-0.14.93.dist-info/entry_points.txt,sha256=oPJy0KBnPWYjDtP1k8qwAihcTLHSZokSQvRAw_wtfJM,46
190
- ingestr-0.14.93.dist-info/licenses/LICENSE.md,sha256=cW8wIhn8HFE-KLStDF9jHQ1O_ARWP3kTpk_-eOccL24,1075
191
- ingestr-0.14.93.dist-info/RECORD,,
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,,