ingestr 0.13.33__tar.gz → 0.13.35__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.

Potentially problematic release.


This version of ingestr might be problematic. Click here for more details.

Files changed (260) hide show
  1. {ingestr-0.13.33 → ingestr-0.13.35}/PKG-INFO +2 -2
  2. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/airtable.md +10 -7
  3. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/athena.md +0 -2
  4. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/hubspot.md +20 -0
  5. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/airtable/__init__.py +3 -2
  6. ingestr-0.13.35/ingestr/src/buildinfo.py +1 -0
  7. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/destinations.py +14 -6
  8. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/hubspot/__init__.py +11 -2
  9. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/hubspot/helpers.py +0 -4
  10. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/sources.py +25 -11
  11. {ingestr-0.13.33 → ingestr-0.13.35}/requirements.in +1 -1
  12. {ingestr-0.13.33 → ingestr-0.13.35}/requirements.txt +1 -1
  13. {ingestr-0.13.33 → ingestr-0.13.35}/requirements_arm64.txt +1 -1
  14. ingestr-0.13.33/ingestr/src/buildinfo.py +0 -1
  15. {ingestr-0.13.33 → ingestr-0.13.35}/.dockerignore +0 -0
  16. {ingestr-0.13.33 → ingestr-0.13.35}/.githooks/pre-commit-hook.sh +0 -0
  17. {ingestr-0.13.33 → ingestr-0.13.35}/.github/workflows/deploy-docs.yml +0 -0
  18. {ingestr-0.13.33 → ingestr-0.13.35}/.github/workflows/release.yml +0 -0
  19. {ingestr-0.13.33 → ingestr-0.13.35}/.github/workflows/secrets-scan.yml +0 -0
  20. {ingestr-0.13.33 → ingestr-0.13.35}/.github/workflows/tests.yml +0 -0
  21. {ingestr-0.13.33 → ingestr-0.13.35}/.gitignore +0 -0
  22. {ingestr-0.13.33 → ingestr-0.13.35}/.gitleaksignore +0 -0
  23. {ingestr-0.13.33 → ingestr-0.13.35}/.python-version +0 -0
  24. {ingestr-0.13.33 → ingestr-0.13.35}/.vale.ini +0 -0
  25. {ingestr-0.13.33 → ingestr-0.13.35}/Dockerfile +0 -0
  26. {ingestr-0.13.33 → ingestr-0.13.35}/LICENSE.md +0 -0
  27. {ingestr-0.13.33 → ingestr-0.13.35}/Makefile +0 -0
  28. {ingestr-0.13.33 → ingestr-0.13.35}/README.md +0 -0
  29. {ingestr-0.13.33 → ingestr-0.13.35}/docs/.vitepress/config.mjs +0 -0
  30. {ingestr-0.13.33 → ingestr-0.13.35}/docs/.vitepress/theme/custom.css +0 -0
  31. {ingestr-0.13.33 → ingestr-0.13.35}/docs/.vitepress/theme/index.js +0 -0
  32. {ingestr-0.13.33 → ingestr-0.13.35}/docs/commands/example-uris.md +0 -0
  33. {ingestr-0.13.33 → ingestr-0.13.35}/docs/commands/ingest.md +0 -0
  34. {ingestr-0.13.33 → ingestr-0.13.35}/docs/getting-started/core-concepts.md +0 -0
  35. {ingestr-0.13.33 → ingestr-0.13.35}/docs/getting-started/incremental-loading.md +0 -0
  36. {ingestr-0.13.33 → ingestr-0.13.35}/docs/getting-started/quickstart.md +0 -0
  37. {ingestr-0.13.33 → ingestr-0.13.35}/docs/getting-started/telemetry.md +0 -0
  38. {ingestr-0.13.33 → ingestr-0.13.35}/docs/index.md +0 -0
  39. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/applovin_max.png +0 -0
  40. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/athena.png +0 -0
  41. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/clickhouse_img.png +0 -0
  42. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/github.png +0 -0
  43. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/googleanalytics.png +0 -0
  44. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/kinesis.bigquery.png +0 -0
  45. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/linkedin_ads.png +0 -0
  46. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/personio.png +0 -0
  47. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/personio_duckdb.png +0 -0
  48. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/pipedrive.png +0 -0
  49. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/stripe_postgres.png +0 -0
  50. {ingestr-0.13.33 → ingestr-0.13.35}/docs/media/tiktok.png +0 -0
  51. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/adjust.md +0 -0
  52. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/applovin.md +0 -0
  53. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/applovin_max.md +0 -0
  54. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/appsflyer.md +0 -0
  55. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/appstore.md +0 -0
  56. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/asana.md +0 -0
  57. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/bigquery.md +0 -0
  58. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/chess.md +0 -0
  59. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/clickhouse.md +0 -0
  60. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/csv.md +0 -0
  61. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/custom_queries.md +0 -0
  62. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/databricks.md +0 -0
  63. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/db2.md +0 -0
  64. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/duckdb.md +0 -0
  65. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/dynamodb.md +0 -0
  66. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/facebook-ads.md +0 -0
  67. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/frankfurter.md +0 -0
  68. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/gcs.md +0 -0
  69. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/github.md +0 -0
  70. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/google-ads.md +0 -0
  71. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/google_analytics.md +0 -0
  72. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/gorgias.md +0 -0
  73. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/gsheets.md +0 -0
  74. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/kafka.md +0 -0
  75. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/kinesis.md +0 -0
  76. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/klaviyo.md +0 -0
  77. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/linkedin_ads.md +0 -0
  78. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/mongodb.md +0 -0
  79. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/mssql.md +0 -0
  80. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/mysql.md +0 -0
  81. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/notion.md +0 -0
  82. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/oracle.md +0 -0
  83. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/personio.md +0 -0
  84. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/pipedrive.md +0 -0
  85. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/postgres.md +0 -0
  86. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/redshift.md +0 -0
  87. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/s3.md +0 -0
  88. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/salesforce.md +0 -0
  89. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/sap-hana.md +0 -0
  90. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/shopify.md +0 -0
  91. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/slack.md +0 -0
  92. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/snowflake.md +0 -0
  93. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/sqlite.md +0 -0
  94. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/stripe.md +0 -0
  95. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/tiktok-ads.md +0 -0
  96. {ingestr-0.13.33 → ingestr-0.13.35}/docs/supported-sources/zendesk.md +0 -0
  97. {ingestr-0.13.33 → ingestr-0.13.35}/docs/tutorials/load-kinesis-bigquery.md +0 -0
  98. {ingestr-0.13.33 → ingestr-0.13.35}/docs/tutorials/load-personio-duckdb.md +0 -0
  99. {ingestr-0.13.33 → ingestr-0.13.35}/docs/tutorials/load-stripe-postgres.md +0 -0
  100. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/conftest.py +0 -0
  101. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/main.py +0 -0
  102. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/.gitignore +0 -0
  103. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/adjust/__init__.py +0 -0
  104. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/adjust/adjust_helpers.py +0 -0
  105. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/applovin/__init__.py +0 -0
  106. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/applovin_max/__init__.py +0 -0
  107. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/appsflyer/__init__.py +0 -0
  108. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/appsflyer/client.py +0 -0
  109. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/appstore/__init__.py +0 -0
  110. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/appstore/client.py +0 -0
  111. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/appstore/errors.py +0 -0
  112. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/appstore/models.py +0 -0
  113. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/appstore/resources.py +0 -0
  114. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/arrow/__init__.py +0 -0
  115. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/asana_source/__init__.py +0 -0
  116. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/asana_source/helpers.py +0 -0
  117. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/asana_source/settings.py +0 -0
  118. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/blob.py +0 -0
  119. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/chess/__init__.py +0 -0
  120. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/chess/helpers.py +0 -0
  121. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/chess/settings.py +0 -0
  122. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/collector/spinner.py +0 -0
  123. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/dynamodb/__init__.py +0 -0
  124. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/errors.py +0 -0
  125. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/facebook_ads/__init__.py +0 -0
  126. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/facebook_ads/exceptions.py +0 -0
  127. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/facebook_ads/helpers.py +0 -0
  128. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/facebook_ads/settings.py +0 -0
  129. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/factory.py +0 -0
  130. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/filesystem/__init__.py +0 -0
  131. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/filesystem/helpers.py +0 -0
  132. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/filesystem/readers.py +0 -0
  133. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/filters.py +0 -0
  134. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/frankfurter/__init__.py +0 -0
  135. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/frankfurter/helpers.py +0 -0
  136. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/github/__init__.py +0 -0
  137. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/github/helpers.py +0 -0
  138. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/github/queries.py +0 -0
  139. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/github/settings.py +0 -0
  140. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_ads/__init__.py +0 -0
  141. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_ads/field.py +0 -0
  142. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_ads/metrics.py +0 -0
  143. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_ads/predicates.py +0 -0
  144. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_ads/reports.py +0 -0
  145. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_analytics/__init__.py +0 -0
  146. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_analytics/helpers.py +0 -0
  147. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_sheets/README.md +0 -0
  148. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_sheets/__init__.py +0 -0
  149. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
  150. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
  151. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
  152. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/gorgias/__init__.py +0 -0
  153. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/gorgias/helpers.py +0 -0
  154. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/hubspot/settings.py +0 -0
  155. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/kafka/__init__.py +0 -0
  156. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/kafka/helpers.py +0 -0
  157. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/kinesis/__init__.py +0 -0
  158. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/kinesis/helpers.py +0 -0
  159. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/klaviyo/__init__.py +0 -0
  160. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/klaviyo/client.py +0 -0
  161. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/klaviyo/helpers.py +0 -0
  162. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/linkedin_ads/__init__.py +0 -0
  163. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
  164. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/linkedin_ads/helpers.py +0 -0
  165. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/loader.py +0 -0
  166. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/mongodb/__init__.py +0 -0
  167. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/mongodb/helpers.py +0 -0
  168. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/notion/__init__.py +0 -0
  169. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/notion/helpers/__init__.py +0 -0
  170. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/notion/helpers/client.py +0 -0
  171. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/notion/helpers/database.py +0 -0
  172. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/notion/settings.py +0 -0
  173. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/partition.py +0 -0
  174. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/personio/__init__.py +0 -0
  175. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/personio/helpers.py +0 -0
  176. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/pipedrive/__init__.py +0 -0
  177. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/pipedrive/helpers/__init__.py +0 -0
  178. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/pipedrive/helpers/custom_fields_munger.py +0 -0
  179. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/pipedrive/helpers/pages.py +0 -0
  180. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/pipedrive/settings.py +0 -0
  181. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/pipedrive/typing.py +0 -0
  182. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/resource.py +0 -0
  183. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/salesforce/__init__.py +0 -0
  184. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/salesforce/helpers.py +0 -0
  185. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/shopify/__init__.py +0 -0
  186. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/shopify/exceptions.py +0 -0
  187. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/shopify/helpers.py +0 -0
  188. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/shopify/settings.py +0 -0
  189. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/slack/__init__.py +0 -0
  190. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/slack/helpers.py +0 -0
  191. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/slack/settings.py +0 -0
  192. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/sql_database/__init__.py +0 -0
  193. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/sql_database/callbacks.py +0 -0
  194. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/stripe_analytics/__init__.py +0 -0
  195. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/stripe_analytics/helpers.py +0 -0
  196. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/stripe_analytics/settings.py +0 -0
  197. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/table_definition.py +0 -0
  198. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/telemetry/event.py +0 -0
  199. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/testdata/fakebqcredentials.json +0 -0
  200. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/tiktok_ads/__init__.py +0 -0
  201. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
  202. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/time.py +0 -0
  203. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/version.py +0 -0
  204. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/zendesk/__init__.py +0 -0
  205. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/zendesk/helpers/__init__.py +0 -0
  206. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
  207. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/zendesk/helpers/credentials.py +0 -0
  208. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
  209. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/src/zendesk/settings.py +0 -0
  210. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/testdata/.gitignore +0 -0
  211. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/testdata/create_replace.csv +0 -0
  212. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/testdata/delete_insert_expected.csv +0 -0
  213. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/testdata/delete_insert_part1.csv +0 -0
  214. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/testdata/delete_insert_part2.csv +0 -0
  215. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/testdata/merge_expected.csv +0 -0
  216. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/testdata/merge_part1.csv +0 -0
  217. {ingestr-0.13.33 → ingestr-0.13.35}/ingestr/testdata/merge_part2.csv +0 -0
  218. {ingestr-0.13.33 → ingestr-0.13.35}/package-lock.json +0 -0
  219. {ingestr-0.13.33 → ingestr-0.13.35}/package.json +0 -0
  220. {ingestr-0.13.33 → ingestr-0.13.35}/pyproject.toml +0 -0
  221. {ingestr-0.13.33 → ingestr-0.13.35}/requirements-dev.txt +0 -0
  222. {ingestr-0.13.33 → ingestr-0.13.35}/resources/demo.gif +0 -0
  223. {ingestr-0.13.33 → ingestr-0.13.35}/resources/demo.tape +0 -0
  224. {ingestr-0.13.33 → ingestr-0.13.35}/resources/ingestr.svg +0 -0
  225. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/AMPM.yml +0 -0
  226. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Acronyms.yml +0 -0
  227. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Colons.yml +0 -0
  228. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Contractions.yml +0 -0
  229. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/DateFormat.yml +0 -0
  230. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Ellipses.yml +0 -0
  231. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/EmDash.yml +0 -0
  232. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Exclamation.yml +0 -0
  233. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/FirstPerson.yml +0 -0
  234. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Gender.yml +0 -0
  235. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/GenderBias.yml +0 -0
  236. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/HeadingPunctuation.yml +0 -0
  237. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Headings.yml +0 -0
  238. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Latin.yml +0 -0
  239. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/LyHyphens.yml +0 -0
  240. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/OptionalPlurals.yml +0 -0
  241. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Ordinal.yml +0 -0
  242. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/OxfordComma.yml +0 -0
  243. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Parens.yml +0 -0
  244. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Passive.yml +0 -0
  245. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Periods.yml +0 -0
  246. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Quotes.yml +0 -0
  247. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Ranges.yml +0 -0
  248. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Semicolons.yml +0 -0
  249. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Slang.yml +0 -0
  250. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Spacing.yml +0 -0
  251. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Spelling.yml +0 -0
  252. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Units.yml +0 -0
  253. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/We.yml +0 -0
  254. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/Will.yml +0 -0
  255. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/WordList.yml +0 -0
  256. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/meta.json +0 -0
  257. {ingestr-0.13.33 → ingestr-0.13.35}/styles/Google/vocab.txt +0 -0
  258. {ingestr-0.13.33 → ingestr-0.13.35}/styles/bruin/Ingestr.yml +0 -0
  259. {ingestr-0.13.33 → ingestr-0.13.35}/styles/config/vocabularies/bruin/accept.txt +0 -0
  260. {ingestr-0.13.33 → ingestr-0.13.35}/test.env.template +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ingestr
3
- Version: 0.13.33
3
+ Version: 0.13.35
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
@@ -46,7 +46,7 @@ Requires-Dist: databricks-sqlalchemy==1.0.2
46
46
  Requires-Dist: dataclasses-json==0.6.7
47
47
  Requires-Dist: decorator==5.2.1
48
48
  Requires-Dist: deprecation==2.1.0
49
- Requires-Dist: dlt==1.9.0
49
+ Requires-Dist: dlt==1.10.0
50
50
  Requires-Dist: dnspython==2.7.0
51
51
  Requires-Dist: duckdb-engine==0.17.0
52
52
  Requires-Dist: duckdb==1.2.1
@@ -9,12 +9,11 @@ ingestr supports Airtable as a source.
9
9
  The URI format for Airtable is as follows:
10
10
 
11
11
  ```plaintext
12
- airtable://?access_token=<access_token>&base_id=<base_id>
12
+ airtable://?access_token=<access_token>
13
13
  ```
14
14
 
15
15
  URI parameters:
16
16
 
17
- - `base_id`: A unique identifier for an Airtable base.
18
17
  - `access_token`: A personal access token for authentication with the Airtable API.
19
18
 
20
19
  The URI is used to connect to the Airtable API for extracting data. More details on setting up Airtable integrations can be found [here](https://airtable.com/developers/web/api).
@@ -23,15 +22,19 @@ The URI is used to connect to the Airtable API for extracting data. More details
23
22
 
24
23
  Airtable requires a few steps to set up an integration, please follow the guide dltHub [has built here](https://dlthub.com/docs/dlt-ecosystem/verified-sources/airtable#setup-guide).
25
24
 
26
- Once you complete the guide, you should have an Access Token and Base Id. Let's say your Access Token is `patr123.abc` and Base Id is `appXYZ`, here's a sample command that will copy the data from Airtable into a DuckDB database:
25
+ Once you complete the guide, you should have an Access Token and a Base ID. The source table you'll use for ingestr will be `<base_id>/<table_name>`.
26
+
27
+ Let's say your access token is `patr123.abc` and the base ID is `appXYZ`, here's a sample command that will copy the data from Airtable into a DuckDB database:
27
28
 
28
29
  ```sh
29
- ingestr ingest --source-uri 'airtable://?base_id=appXYc&access_token=patr123.abc' --source-table 'employee' --dest-uri 'duckdb:///airtable.duckdb' --dest-table 'des.employee'
30
+ ingestr ingest
31
+ --source-uri 'airtable://?access_token=patr123.abc'
32
+ --source-table 'appXYZ/employee'
33
+ --dest-uri 'duckdb:///airtable.duckdb'
34
+ --dest-table 'des.employee'
30
35
  ```
31
36
 
32
- The result of this command will be an `employee` table containing data from the `employee` source in the `Airtable.duckdb` database.
33
-
34
- The `source-table` can include multiple table names that share the same `base_id`, e.g. `--source-table 'employee,users'`, but this will merge all the data from the specified tables into a single destination table.
37
+ The result of this command will be an `employee` table containing data from the `employee` source in the `airtable.duckdb` database.
35
38
 
36
39
  > [!CAUTION]
37
40
  > Airtable does not support incremental loading, which means every time you run the command, the entire table will be copied from Airtable to the destination. This can be slow for large tables.
@@ -10,7 +10,6 @@ The URI format for Athena is as follows:
10
10
 
11
11
  ```plaintext
12
12
  athena://?bucket=<your-destination-bucket> \
13
- query_results_path=<your-query-results-location> \
14
13
  access_key_id=<your-aws-access-key-id> \
15
14
  secret_access_key=<your-aws-secret-access-key> \
16
15
  region_name=<your-aws-region>
@@ -20,7 +19,6 @@ URI parameters:
20
19
  - `access_key_id` and `secret_access_key` (required): These are AWS credentials that will be used to authenticate with AWS services like S3 and Athena.
21
20
  - `session_token` (optional): The session token for temporary credentials.
22
21
  - `region_name` (required if there's no local profile found): The AWS region of the Athena service and S3 buckets, e.g. `eu-central-1`
23
- - `query_results_path` (optional): The query location path where the results of Athena queries will be saved, e.g. `dest_path` or `s3://dest_path`. If not provided, it will default to the bucket specified in the `bucket` parameter.
24
22
  - `workgroup` (optional): The name of the Athena workgroup, e.g. `my_group`
25
23
  - `profile` (optional): The name of the AWS profile to use, e.g. `my_profile`
26
24
 
@@ -42,3 +42,23 @@ HubSpot source allows ingesting the following sources into separate tables:
42
42
  - `contacts`: Retrieves information about visitors, potential customers, and leads.
43
43
 
44
44
  Use these as `--source-table` parameter in the `ingestr ingest` command.
45
+
46
+ ## Custom Objects
47
+
48
+ HubSpot custom objects are supported by using the `custom` table.
49
+
50
+ The format for the custom object is as follows:
51
+
52
+ ```plaintext
53
+ custom:<custom_object_name>:<optional associations>
54
+ ```
55
+
56
+ For example, to ingest the `course` custom object with the `contacts` and `companies` associations, the format would be:
57
+
58
+ ```plaintext
59
+ custom:course:contacts,companies
60
+ ```
61
+
62
+ This would pull all the data for the `course` custom object and include the `contacts` and `companies` associations in the resulting table.
63
+
64
+
@@ -9,7 +9,7 @@ import pyairtable
9
9
  from dlt.sources import DltResource
10
10
 
11
11
 
12
- @dlt.source
12
+ @dlt.source(max_table_nesting=1)
13
13
  def airtable_source(
14
14
  base_id: str = dlt.config.value,
15
15
  table_names: Optional[List[str]] = dlt.config.value,
@@ -50,12 +50,13 @@ def airtable_resource(
50
50
  It starts with "app". See https://support.airtable.com/docs/finding-airtable-ids
51
51
  table (Dict[str, Any]): Metadata about an airtable, does not contain the actual records
52
52
  """
53
+
53
54
  primary_key_id = table["primaryFieldId"]
54
55
  primary_key_field = [
55
56
  field for field in table["fields"] if field["id"] == primary_key_id
56
57
  ][0]
57
58
  table_name: str = table["name"]
58
- primary_key: List[str] = [f"fields__{primary_key_field['name']}"]
59
+ primary_key: List[str] = [f"fields__{primary_key_field['name']}".lower()]
59
60
  air_table = api.table(base_id, table["id"])
60
61
 
61
62
  # Table.iterate() supports rich customization options, such as chunk size, fields, cell format, timezone, locale, and view
@@ -0,0 +1 @@
1
+ version = "v0.13.35"
@@ -235,12 +235,19 @@ class AthenaDestination:
235
235
  if not bucket.startswith("s3://"):
236
236
  bucket = f"s3://{bucket}"
237
237
 
238
- query_result_path = source_params.get("query_results_path", [None])[0]
239
- if query_result_path:
240
- if not query_result_path.startswith("s3://"):
241
- query_result_path = f"s3://{query_result_path}"
242
- else:
243
- query_result_path = bucket
238
+ bucket = bucket.rstrip("/")
239
+
240
+ dest_table = kwargs.get("dest_table", None)
241
+ if not dest_table:
242
+ raise ValueError("A destination table is required to connect to Athena.")
243
+
244
+ dest_table_fields = dest_table.split(".")
245
+ if len(dest_table_fields) != 2:
246
+ raise ValueError(
247
+ f"Table name must be in the format <schema>.<table>, given: {dest_table}"
248
+ )
249
+
250
+ query_result_path = f"{bucket}/{dest_table_fields[0]}_staging/metadata"
244
251
 
245
252
  access_key_id = source_params.get("access_key_id", [None])[0]
246
253
  secret_access_key = source_params.get("secret_access_key", [None])[0]
@@ -285,6 +292,7 @@ class AthenaDestination:
285
292
  region_name=region_name,
286
293
  ),
287
294
  destination_name=bucket,
295
+ force_iceberg=True,
288
296
  )
289
297
 
290
298
  def dlt_run_params(self, uri: str, table: str, **kwargs) -> dict:
@@ -197,11 +197,18 @@ def hubspot(
197
197
  api_key: str = api_key,
198
198
  custom_object_name: str = custom_object,
199
199
  ) -> Iterator[TDataItems]:
200
- get_custom_object = fetch_data_raw(CRM_SCHEMAS_ENDPOINT, api_key)
200
+ custom_objects = fetch_data_raw(CRM_SCHEMAS_ENDPOINT, api_key)
201
201
  object_type_id = None
202
+ associations = None
203
+ if ":" in custom_object_name:
204
+ fields = custom_object_name.split(":")
205
+ if len(fields) == 2:
206
+ custom_object_name = fields[0]
207
+ associations = fields[1]
202
208
 
203
209
  custom_object_lowercase = custom_object_name.lower()
204
- for custom_object in get_custom_object["results"]:
210
+
211
+ for custom_object in custom_objects["results"]:
205
212
  if custom_object["name"].lower() == custom_object_lowercase:
206
213
  object_type_id = custom_object["objectTypeId"]
207
214
  break
@@ -223,6 +230,8 @@ def hubspot(
223
230
  props = ",".join(sorted(list(set(props))))
224
231
 
225
232
  custom_object_endpoint = f"crm/v3/objects/{object_type_id}/?properties={props}"
233
+ if associations:
234
+ custom_object_endpoint += f"&associations={associations}"
226
235
 
227
236
  """Hubspot custom object details resource"""
228
237
  yield from fetch_data(custom_object_endpoint, api_key, resource_name="custom")
@@ -148,10 +148,6 @@ def fetch_data(
148
148
  "updatedAt": _result.get("updatedAt", ""),
149
149
  }
150
150
  )
151
- elif resource_name == "custom":
152
- _objects.append(
153
- _result.get("properties", ""),
154
- )
155
151
  else:
156
152
  _obj = _result.get("properties", _result)
157
153
  if "id" not in _obj and "id" in _result:
@@ -722,7 +722,7 @@ class FacebookAdsSource:
722
722
  ).with_resources("facebook_insights")
723
723
  else:
724
724
  raise ValueError(
725
- "fResource '{table}' is not supported for Facebook Ads source yet, if you are interested in it please create a GitHub issue at https://github.com/bruin-data/ingestr"
725
+ f"Resource '{table}' is not supported for Facebook Ads source yet, if you are interested in it please create a GitHub issue at https://github.com/bruin-data/ingestr"
726
726
  )
727
727
 
728
728
  return facebook_ads_source(
@@ -804,11 +804,16 @@ class HubspotSource:
804
804
 
805
805
  if table.startswith("custom:"):
806
806
  fields = table.split(":", 2)
807
- if len(fields) != 2:
807
+ if len(fields) != 2 and len(fields) != 3:
808
808
  raise ValueError(
809
- "Invalid Hubspot custom table format. Expected format: custom:<custom_object_type>"
809
+ "Invalid Hubspot custom table format. Expected format: custom:<custom_object_type> or custom:<custom_object_type>:<associations>"
810
810
  )
811
- endpoint = fields[1]
811
+
812
+ if len(fields) == 2:
813
+ endpoint = fields[1]
814
+ else:
815
+ endpoint = f"{fields[1]}:{fields[2]}"
816
+
812
817
  return hubspot(
813
818
  api_key=api_key[0],
814
819
  custom_object=endpoint,
@@ -847,22 +852,31 @@ class AirtableSource:
847
852
  if not table:
848
853
  raise ValueError("Source table is required to connect to Airtable")
849
854
 
850
- tables = table.split(",")
851
-
852
855
  source_parts = urlparse(uri)
853
856
  source_fields = parse_qs(source_parts.query)
854
- base_id = source_fields.get("base_id")
855
857
  access_token = source_fields.get("access_token")
856
858
 
857
- if not base_id or not access_token:
859
+ if not access_token:
858
860
  raise ValueError(
859
- "base_id and access_token in the URI are required to connect to Airtable"
861
+ "access_token in the URI is required to connect to Airtable"
860
862
  )
861
863
 
864
+ base_id = source_fields.get("base_id", [None])[0]
865
+ clean_table = table
866
+
867
+ table_fields = table.split("/")
868
+ if len(table_fields) == 2:
869
+ clean_table = table_fields[1]
870
+ if not base_id:
871
+ base_id = table_fields[0]
872
+
873
+ if not base_id:
874
+ raise ValueError("base_id in the URI is required to connect to Airtable")
875
+
862
876
  from ingestr.src.airtable import airtable_source
863
877
 
864
878
  return airtable_source(
865
- base_id=base_id[0], table_names=tables, access_token=access_token[0]
879
+ base_id=base_id, table_names=[clean_table], access_token=access_token[0]
866
880
  )
867
881
 
868
882
 
@@ -1175,7 +1189,7 @@ class ZendeskSource:
1175
1189
  ).with_resources(table)
1176
1190
  else:
1177
1191
  raise ValueError(
1178
- "fResource '{table}' is not supported for Zendesk source yet, if you are interested in it please create a GitHub issue at https://github.com/bruin-data/ingestr"
1192
+ f"Resource '{table}' is not supported for Zendesk source yet, if you are interested in it please create a GitHub issue at https://github.com/bruin-data/ingestr"
1179
1193
  )
1180
1194
 
1181
1195
 
@@ -2,7 +2,7 @@ asana==3.2.3
2
2
  confluent-kafka==2.8.0
3
3
  databricks-sql-connector==2.9.3
4
4
  dataclasses-json==0.6.7
5
- dlt==1.9.0
5
+ dlt==1.10.0
6
6
  duckdb_engine==0.17.0
7
7
  duckdb==1.2.1
8
8
  google-ads==25.1.0
@@ -94,7 +94,7 @@ decorator==5.2.1
94
94
  # via gcsfs
95
95
  deprecation==2.1.0
96
96
  # via rudder-sdk-python
97
- dlt==1.9.0
97
+ dlt==1.10.0
98
98
  # via -r requirements.in
99
99
  dnspython==2.7.0
100
100
  # via pymongo
@@ -94,7 +94,7 @@ decorator==5.2.1
94
94
  # via gcsfs
95
95
  deprecation==2.1.0
96
96
  # via rudder-sdk-python
97
- dlt==1.9.0
97
+ dlt==1.10.0
98
98
  # via -r requirements.in
99
99
  dnspython==2.7.0
100
100
  # via pymongo
@@ -1 +0,0 @@
1
- version = "v0.13.33"
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
File without changes
File without changes
File without changes
File without changes