ingestr 0.14.8__tar.gz → 0.14.91__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 (370) hide show
  1. {ingestr-0.14.8 → ingestr-0.14.91}/.github/workflows/tests.yml +17 -0
  2. {ingestr-0.14.8 → ingestr-0.14.91}/PKG-INFO +1 -1
  3. {ingestr-0.14.8 → ingestr-0.14.91}/docs/.vitepress/config.mjs +1 -0
  4. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/freshdesk.md +1 -1
  5. ingestr-0.14.91/docs/supported-sources/mailchimp.md +99 -0
  6. ingestr-0.14.91/ingestr/src/buildinfo.py +1 -0
  7. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/factory.py +2 -0
  8. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/freshdesk/freshdesk_client.py +9 -1
  9. ingestr-0.14.91/ingestr/src/mailchimp/__init__.py +126 -0
  10. ingestr-0.14.91/ingestr/src/mailchimp/helpers.py +226 -0
  11. ingestr-0.14.91/ingestr/src/mailchimp/settings.py +164 -0
  12. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/sources.py +26 -0
  13. ingestr-0.14.8/ingestr/src/buildinfo.py +0 -1
  14. {ingestr-0.14.8 → ingestr-0.14.91}/.dlt/config.toml +0 -0
  15. {ingestr-0.14.8 → ingestr-0.14.91}/.dockerignore +0 -0
  16. {ingestr-0.14.8 → ingestr-0.14.91}/.githooks/pre-commit-hook.sh +0 -0
  17. {ingestr-0.14.8 → ingestr-0.14.91}/.github/workflows/deploy-docs.yml +0 -0
  18. {ingestr-0.14.8 → ingestr-0.14.91}/.github/workflows/release.yml +0 -0
  19. {ingestr-0.14.8 → ingestr-0.14.91}/.github/workflows/secrets-scan.yml +0 -0
  20. {ingestr-0.14.8 → ingestr-0.14.91}/.gitignore +0 -0
  21. {ingestr-0.14.8 → ingestr-0.14.91}/.gitleaksignore +0 -0
  22. {ingestr-0.14.8 → ingestr-0.14.91}/.python-version +0 -0
  23. {ingestr-0.14.8 → ingestr-0.14.91}/.vale.ini +0 -0
  24. {ingestr-0.14.8 → ingestr-0.14.91}/Dockerfile +0 -0
  25. {ingestr-0.14.8 → ingestr-0.14.91}/LICENSE.md +0 -0
  26. {ingestr-0.14.8 → ingestr-0.14.91}/Makefile +0 -0
  27. {ingestr-0.14.8 → ingestr-0.14.91}/README.md +0 -0
  28. {ingestr-0.14.8 → ingestr-0.14.91}/docs/.vitepress/theme/custom.css +0 -0
  29. {ingestr-0.14.8 → ingestr-0.14.91}/docs/.vitepress/theme/index.js +0 -0
  30. {ingestr-0.14.8 → ingestr-0.14.91}/docs/commands/example-uris.md +0 -0
  31. {ingestr-0.14.8 → ingestr-0.14.91}/docs/commands/ingest.md +0 -0
  32. {ingestr-0.14.8 → ingestr-0.14.91}/docs/getting-started/core-concepts.md +0 -0
  33. {ingestr-0.14.8 → ingestr-0.14.91}/docs/getting-started/data-masking.md +0 -0
  34. {ingestr-0.14.8 → ingestr-0.14.91}/docs/getting-started/incremental-loading.md +0 -0
  35. {ingestr-0.14.8 → ingestr-0.14.91}/docs/getting-started/quickstart.md +0 -0
  36. {ingestr-0.14.8 → ingestr-0.14.91}/docs/getting-started/telemetry.md +0 -0
  37. {ingestr-0.14.8 → ingestr-0.14.91}/docs/index.md +0 -0
  38. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/applovin_max.png +0 -0
  39. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/athena.png +0 -0
  40. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/clickhouse_img.png +0 -0
  41. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/clickup_ingestion.png +0 -0
  42. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/cratedb-destination.png +0 -0
  43. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/cratedb-source.png +0 -0
  44. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/freshdesk_ingestion.png +0 -0
  45. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/gcp_spanner_ingestion.png +0 -0
  46. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/github.png +0 -0
  47. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/google_analytics_realtime_report.png +0 -0
  48. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/googleanalytics.png +0 -0
  49. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/ingestion_elasticsearch_img.png +0 -0
  50. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/kinesis.bigquery.png +0 -0
  51. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/linear.png +0 -0
  52. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/linkedin_ads.png +0 -0
  53. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/mixpanel_ingestion.png +0 -0
  54. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/personio.png +0 -0
  55. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/personio_duckdb.png +0 -0
  56. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/phantombuster.png +0 -0
  57. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/pipedrive.png +0 -0
  58. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/quickbook_ingestion.png +0 -0
  59. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/sftp.png +0 -0
  60. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/stripe_postgres.png +0 -0
  61. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/tiktok.png +0 -0
  62. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/wise_ingestion.png +0 -0
  63. {ingestr-0.14.8 → ingestr-0.14.91}/docs/media/zoom_ingestion.png +0 -0
  64. {ingestr-0.14.8 → ingestr-0.14.91}/docs/public/demo.gif +0 -0
  65. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/adjust.md +0 -0
  66. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/airtable.md +0 -0
  67. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/anthropic.md +0 -0
  68. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/applovin.md +0 -0
  69. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/applovin_max.md +0 -0
  70. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/appsflyer.md +0 -0
  71. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/appstore.md +0 -0
  72. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/asana.md +0 -0
  73. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/athena.md +0 -0
  74. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/attio.md +0 -0
  75. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/bigquery.md +0 -0
  76. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/chess.md +0 -0
  77. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/clickhouse.md +0 -0
  78. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/clickup.md +0 -0
  79. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/cratedb.md +0 -0
  80. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/csv.md +0 -0
  81. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/custom_queries.md +0 -0
  82. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/databricks.md +0 -0
  83. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/db2.md +0 -0
  84. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/docebo.md +0 -0
  85. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/duckdb.md +0 -0
  86. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/dynamodb.md +0 -0
  87. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/elasticsearch.md +0 -0
  88. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/facebook-ads.md +0 -0
  89. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/fluxx.md +0 -0
  90. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/frankfurter.md +0 -0
  91. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/fundraiseup.md +0 -0
  92. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/gcs.md +0 -0
  93. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/github.md +0 -0
  94. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/google-ads.md +0 -0
  95. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/google_analytics.md +0 -0
  96. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/gorgias.md +0 -0
  97. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/gsheets.md +0 -0
  98. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/http.md +0 -0
  99. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/hubspot.md +0 -0
  100. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/influxdb.md +0 -0
  101. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/intercom.md +0 -0
  102. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/isoc-pulse.md +0 -0
  103. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/jira.md +0 -0
  104. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/kafka.md +0 -0
  105. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/kinesis.md +0 -0
  106. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/klaviyo.md +0 -0
  107. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/linear.md +0 -0
  108. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/linkedin_ads.md +0 -0
  109. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/mixpanel.md +0 -0
  110. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/monday.md +0 -0
  111. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/mongodb.md +0 -0
  112. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/motherduck.md +0 -0
  113. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/mssql.md +0 -0
  114. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/mysql.md +0 -0
  115. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/notion.md +0 -0
  116. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/oracle.md +0 -0
  117. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/personio.md +0 -0
  118. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/phantombuster.md +0 -0
  119. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/pinterest.md +0 -0
  120. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/pipedrive.md +0 -0
  121. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/plusvibeai.md +0 -0
  122. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/postgres.md +0 -0
  123. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/quickbooks.md +0 -0
  124. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/redshift.md +0 -0
  125. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/revenuecat.md +0 -0
  126. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/s3.md +0 -0
  127. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/salesforce.md +0 -0
  128. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/sap-hana.md +0 -0
  129. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/sftp.md +0 -0
  130. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/shopify.md +0 -0
  131. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/slack.md +0 -0
  132. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/smartsheets.md +0 -0
  133. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/snowflake.md +0 -0
  134. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/solidgate.md +0 -0
  135. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/spanner.md +0 -0
  136. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/sqlite.md +0 -0
  137. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/stripe.md +0 -0
  138. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/tiktok-ads.md +0 -0
  139. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/trino.md +0 -0
  140. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/trustpilot.md +0 -0
  141. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/wise.md +0 -0
  142. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/zendesk.md +0 -0
  143. {ingestr-0.14.8 → ingestr-0.14.91}/docs/supported-sources/zoom.md +0 -0
  144. {ingestr-0.14.8 → ingestr-0.14.91}/docs/tutorials/load-kinesis-bigquery.md +0 -0
  145. {ingestr-0.14.8 → ingestr-0.14.91}/docs/tutorials/load-personio-duckdb.md +0 -0
  146. {ingestr-0.14.8 → ingestr-0.14.91}/docs/tutorials/load-stripe-postgres.md +0 -0
  147. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/conftest.py +0 -0
  148. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/main.py +0 -0
  149. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/.gitignore +0 -0
  150. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/adjust/__init__.py +0 -0
  151. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/adjust/adjust_helpers.py +0 -0
  152. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/airtable/__init__.py +0 -0
  153. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/anthropic/__init__.py +0 -0
  154. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/anthropic/helpers.py +0 -0
  155. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/applovin/__init__.py +0 -0
  156. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/applovin_max/__init__.py +0 -0
  157. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/appsflyer/__init__.py +0 -0
  158. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/appsflyer/client.py +0 -0
  159. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/appstore/__init__.py +0 -0
  160. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/appstore/client.py +0 -0
  161. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/appstore/errors.py +0 -0
  162. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/appstore/models.py +0 -0
  163. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/appstore/resources.py +0 -0
  164. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/arrow/__init__.py +0 -0
  165. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/asana_source/__init__.py +0 -0
  166. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/asana_source/helpers.py +0 -0
  167. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/asana_source/settings.py +0 -0
  168. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/attio/__init__.py +0 -0
  169. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/attio/helpers.py +0 -0
  170. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/blob.py +0 -0
  171. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/chess/__init__.py +0 -0
  172. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/chess/helpers.py +0 -0
  173. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/chess/settings.py +0 -0
  174. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/clickup/__init__.py +0 -0
  175. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/clickup/helpers.py +0 -0
  176. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/collector/spinner.py +0 -0
  177. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/destinations.py +0 -0
  178. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/docebo/__init__.py +0 -0
  179. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/docebo/client.py +0 -0
  180. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/docebo/helpers.py +0 -0
  181. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/dynamodb/__init__.py +0 -0
  182. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/elasticsearch/__init__.py +0 -0
  183. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/elasticsearch/helpers.py +0 -0
  184. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/errors.py +0 -0
  185. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/facebook_ads/__init__.py +0 -0
  186. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/facebook_ads/exceptions.py +0 -0
  187. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/facebook_ads/helpers.py +0 -0
  188. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/facebook_ads/settings.py +0 -0
  189. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/facebook_ads/utils.py +0 -0
  190. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/filesystem/__init__.py +0 -0
  191. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/filesystem/helpers.py +0 -0
  192. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/filesystem/readers.py +0 -0
  193. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/filters.py +0 -0
  194. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/fluxx/__init__.py +0 -0
  195. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/fluxx/helpers.py +0 -0
  196. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/frankfurter/__init__.py +0 -0
  197. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/frankfurter/helpers.py +0 -0
  198. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/freshdesk/__init__.py +0 -0
  199. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/freshdesk/settings.py +0 -0
  200. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/fundraiseup/__init__.py +0 -0
  201. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/fundraiseup/client.py +0 -0
  202. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/github/__init__.py +0 -0
  203. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/github/helpers.py +0 -0
  204. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/github/queries.py +0 -0
  205. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/github/settings.py +0 -0
  206. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_ads/__init__.py +0 -0
  207. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_ads/field.py +0 -0
  208. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_ads/metrics.py +0 -0
  209. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_ads/predicates.py +0 -0
  210. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_ads/reports.py +0 -0
  211. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_analytics/__init__.py +0 -0
  212. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_analytics/helpers.py +0 -0
  213. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_sheets/README.md +0 -0
  214. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_sheets/__init__.py +0 -0
  215. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
  216. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
  217. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
  218. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/gorgias/__init__.py +0 -0
  219. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/gorgias/helpers.py +0 -0
  220. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/http/__init__.py +0 -0
  221. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/http/readers.py +0 -0
  222. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/http_client.py +0 -0
  223. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/hubspot/__init__.py +0 -0
  224. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/hubspot/helpers.py +0 -0
  225. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/hubspot/settings.py +0 -0
  226. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/influxdb/__init__.py +0 -0
  227. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/influxdb/client.py +0 -0
  228. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/intercom/__init__.py +0 -0
  229. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/intercom/helpers.py +0 -0
  230. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/intercom/settings.py +0 -0
  231. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/isoc_pulse/__init__.py +0 -0
  232. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/jira_source/__init__.py +0 -0
  233. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/jira_source/helpers.py +0 -0
  234. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/jira_source/settings.py +0 -0
  235. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/kafka/__init__.py +0 -0
  236. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/kafka/helpers.py +0 -0
  237. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/kinesis/__init__.py +0 -0
  238. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/kinesis/helpers.py +0 -0
  239. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/klaviyo/__init__.py +0 -0
  240. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/klaviyo/client.py +0 -0
  241. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/klaviyo/helpers.py +0 -0
  242. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/linear/__init__.py +0 -0
  243. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/linear/helpers.py +0 -0
  244. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/linkedin_ads/__init__.py +0 -0
  245. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
  246. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/linkedin_ads/helpers.py +0 -0
  247. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/loader.py +0 -0
  248. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/masking.py +0 -0
  249. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/mixpanel/__init__.py +0 -0
  250. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/mixpanel/client.py +0 -0
  251. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/monday/__init__.py +0 -0
  252. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/monday/helpers.py +0 -0
  253. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/monday/settings.py +0 -0
  254. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/mongodb/__init__.py +0 -0
  255. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/mongodb/helpers.py +0 -0
  256. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/notion/__init__.py +0 -0
  257. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/notion/helpers/__init__.py +0 -0
  258. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/notion/helpers/client.py +0 -0
  259. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/notion/helpers/database.py +0 -0
  260. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/notion/settings.py +0 -0
  261. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/partition.py +0 -0
  262. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/personio/__init__.py +0 -0
  263. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/personio/helpers.py +0 -0
  264. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/phantombuster/__init__.py +0 -0
  265. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/phantombuster/client.py +0 -0
  266. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/pinterest/__init__.py +0 -0
  267. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/pipedrive/__init__.py +0 -0
  268. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/pipedrive/helpers/__init__.py +0 -0
  269. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/pipedrive/helpers/custom_fields_munger.py +0 -0
  270. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/pipedrive/helpers/pages.py +0 -0
  271. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/pipedrive/settings.py +0 -0
  272. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/pipedrive/typing.py +0 -0
  273. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/plusvibeai/__init__.py +0 -0
  274. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/plusvibeai/helpers.py +0 -0
  275. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/plusvibeai/settings.py +0 -0
  276. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/quickbooks/__init__.py +0 -0
  277. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/resource.py +0 -0
  278. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/revenuecat/__init__.py +0 -0
  279. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/revenuecat/helpers.py +0 -0
  280. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/salesforce/__init__.py +0 -0
  281. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/salesforce/helpers.py +0 -0
  282. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/shopify/__init__.py +0 -0
  283. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/shopify/exceptions.py +0 -0
  284. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/shopify/helpers.py +0 -0
  285. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/shopify/settings.py +0 -0
  286. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/slack/__init__.py +0 -0
  287. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/slack/helpers.py +0 -0
  288. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/slack/settings.py +0 -0
  289. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/smartsheets/__init__.py +0 -0
  290. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/solidgate/__init__.py +0 -0
  291. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/solidgate/helpers.py +0 -0
  292. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/sql_database/__init__.py +0 -0
  293. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/sql_database/callbacks.py +0 -0
  294. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/stripe_analytics/__init__.py +0 -0
  295. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/stripe_analytics/helpers.py +0 -0
  296. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/stripe_analytics/settings.py +0 -0
  297. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/table_definition.py +0 -0
  298. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/telemetry/event.py +0 -0
  299. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/testdata/fakebqcredentials.json +0 -0
  300. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/tiktok_ads/__init__.py +0 -0
  301. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
  302. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/time.py +0 -0
  303. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/trustpilot/__init__.py +0 -0
  304. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/trustpilot/client.py +0 -0
  305. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/version.py +0 -0
  306. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/wise/__init__.py +0 -0
  307. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/wise/client.py +0 -0
  308. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/zendesk/__init__.py +0 -0
  309. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/zendesk/helpers/__init__.py +0 -0
  310. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
  311. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/zendesk/helpers/credentials.py +0 -0
  312. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
  313. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/zendesk/settings.py +0 -0
  314. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/zoom/__init__.py +0 -0
  315. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/src/zoom/helpers.py +0 -0
  316. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/testdata/.gitignore +0 -0
  317. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/testdata/create_replace.csv +0 -0
  318. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/testdata/delete_insert_expected.csv +0 -0
  319. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/testdata/delete_insert_part1.csv +0 -0
  320. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/testdata/delete_insert_part2.csv +0 -0
  321. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/testdata/merge_expected.csv +0 -0
  322. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/testdata/merge_part1.csv +0 -0
  323. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/testdata/merge_part2.csv +0 -0
  324. {ingestr-0.14.8 → ingestr-0.14.91}/ingestr/tests/unit/test_smartsheets.py +0 -0
  325. {ingestr-0.14.8 → ingestr-0.14.91}/package-lock.json +0 -0
  326. {ingestr-0.14.8 → ingestr-0.14.91}/package.json +0 -0
  327. {ingestr-0.14.8 → ingestr-0.14.91}/pyproject.toml +0 -0
  328. {ingestr-0.14.8 → ingestr-0.14.91}/requirements-dev.txt +0 -0
  329. {ingestr-0.14.8 → ingestr-0.14.91}/requirements.in +0 -0
  330. {ingestr-0.14.8 → ingestr-0.14.91}/requirements.txt +0 -0
  331. {ingestr-0.14.8 → ingestr-0.14.91}/requirements_arm64.txt +0 -0
  332. {ingestr-0.14.8 → ingestr-0.14.91}/resources/demo.gif +0 -0
  333. {ingestr-0.14.8 → ingestr-0.14.91}/resources/demo.tape +0 -0
  334. {ingestr-0.14.8 → ingestr-0.14.91}/resources/ingestr.svg +0 -0
  335. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/AMPM.yml +0 -0
  336. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Acronyms.yml +0 -0
  337. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Colons.yml +0 -0
  338. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Contractions.yml +0 -0
  339. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/DateFormat.yml +0 -0
  340. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Ellipses.yml +0 -0
  341. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/EmDash.yml +0 -0
  342. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Exclamation.yml +0 -0
  343. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/FirstPerson.yml +0 -0
  344. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Gender.yml +0 -0
  345. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/GenderBias.yml +0 -0
  346. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/HeadingPunctuation.yml +0 -0
  347. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Headings.yml +0 -0
  348. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Latin.yml +0 -0
  349. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/LyHyphens.yml +0 -0
  350. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/OptionalPlurals.yml +0 -0
  351. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Ordinal.yml +0 -0
  352. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/OxfordComma.yml +0 -0
  353. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Parens.yml +0 -0
  354. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Passive.yml +0 -0
  355. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Periods.yml +0 -0
  356. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Quotes.yml +0 -0
  357. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Ranges.yml +0 -0
  358. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Semicolons.yml +0 -0
  359. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Slang.yml +0 -0
  360. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Spacing.yml +0 -0
  361. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Spelling.yml +0 -0
  362. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Units.yml +0 -0
  363. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/We.yml +0 -0
  364. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/Will.yml +0 -0
  365. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/WordList.yml +0 -0
  366. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/meta.json +0 -0
  367. {ingestr-0.14.8 → ingestr-0.14.91}/styles/Google/vocab.txt +0 -0
  368. {ingestr-0.14.8 → ingestr-0.14.91}/styles/bruin/Ingestr.yml +0 -0
  369. {ingestr-0.14.8 → ingestr-0.14.91}/styles/config/vocabularies/bruin/accept.txt +0 -0
  370. {ingestr-0.14.8 → ingestr-0.14.91}/test.env.template +0 -0
@@ -13,7 +13,24 @@ concurrency:
13
13
  cancel-in-progress: true
14
14
 
15
15
  jobs:
16
+ check-changes:
17
+ runs-on: ubuntu-latest
18
+ outputs:
19
+ docs-only: ${{ steps.filter.outputs.docs-only }}
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: dorny/paths-filter@v3
23
+ id: filter
24
+ with:
25
+ filters: |
26
+ docs-only:
27
+ - '!**'
28
+ - '**/*.md'
29
+ - 'docs/**'
30
+
16
31
  tests:
32
+ needs: check-changes
33
+ if: needs.check-changes.outputs.docs-only != 'true'
17
34
  strategy:
18
35
  matrix:
19
36
  # I tried running stuff on macOS but it was too slow and unreliable.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ingestr
3
- Version: 0.14.8
3
+ Version: 0.14.91
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
@@ -155,6 +155,7 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
155
155
  { text: "Klaviyo", link: "/supported-sources/klaviyo.md" },
156
156
  { text: "Linear", link: "/supported-sources/linear.md" },
157
157
  { text: "LinkedIn Ads", link: "/supported-sources/linkedin_ads.md" },
158
+ { text: "Mailchimp", link: "/supported-sources/mailchimp.md" },
158
159
  { text: "Mixpanel", link: "/supported-sources/mixpanel.md" },
159
160
  { text: "Monday", link: "/supported-sources/monday.md" },
160
161
  { text: "Notion", link: "/supported-sources/notion.md" },
@@ -44,6 +44,6 @@ The Freshdesk source allows you to ingest the following tables:
44
44
  | [groups](https://developers.freshdesk.com/api/#groups) | id | updated_at | merge | Retrieves agents organized based on specific criteria. |
45
45
  | [roles](https://developers.freshdesk.com/api/#roles) | id | updated_at | merge | Retrieves predefined sets of permissions that determine what actions an agent can perform.|
46
46
  | [tickets](https://developers.freshdesk.com/api/#tickets) | id | updated_at | merge | Retrieves customer inquiries or issues submitted via various channels like email, chat, phone, etc.
47
- | [tickets:<query>](https://developers.freshdesk.com/api/#filter_tickets) | id | updated_at | merge | Executes the [Freshdesk ticket filter query](https://developers.freshdesk.com/api/#filter_tickets) while preserving incremental sync. |
47
+ | [tickets:<query>](https://developers.freshdesk.com/api/#filter_tickets) | id | updated_at | merge | Executes the [Freshdesk ticket filter query](https://developers.freshdesk.com/api/#filter_tickets) while preserving incremental sync. Maximum results: 300 tickets. |
48
48
 
49
49
  Use these as the `--source-table` parameter in the `ingestr ingest` command.
@@ -0,0 +1,99 @@
1
+ # Mailchimp
2
+
3
+ [Mailchimp](https://mailchimp.com/) is an all-in-one marketing platform that helps businesses manage and talk to their clients, customers, and other interested parties through email marketing campaigns, automated messages, and targeted ads.
4
+
5
+ ingestr supports Mailchimp as a source.
6
+
7
+ ## URI format
8
+
9
+ The URI format for Mailchimp is as follows:
10
+
11
+ ```plaintext
12
+ mailchimp://?api_key=<api-key>&server=<server-prefix>
13
+ ```
14
+
15
+ URI parameters:
16
+
17
+ - `api_key`: The API key used for authentication with the Mailchimp API
18
+ - `server`: The server prefix for your Mailchimp account (e.g., `us10`, `us19`)
19
+
20
+ The URI is used to connect to the Mailchimp API for extracting data.
21
+
22
+ ## Setting up a Mailchimp Integration
23
+
24
+ To get your Mailchimp API credentials:
25
+
26
+ 1. Log in to your Mailchimp account
27
+ 2. Navigate to **Account** → **Extras** → **API keys**
28
+ 3. Create a new API key or use an existing one
29
+ 4. Note your server prefix from your API key (the part after the dash, e.g., `us10` from `xxxxx-us10`)
30
+
31
+ Once you have your credentials, here's a sample command that will copy the data from Mailchimp into a DuckDB database:
32
+
33
+ ```sh
34
+ ingestr ingest --source-uri 'mailchimp://?api_key=your_api_key&server=us10' --source-table 'campaigns' --dest-uri duckdb:///mailchimp.duckdb --dest-table 'mailchimp.campaigns'
35
+ ```
36
+
37
+ The result of this command will be a table in the `mailchimp.duckdb` database.
38
+
39
+ ## Tables
40
+
41
+ Mailchimp source allows ingesting the following sources into separate tables:
42
+
43
+ | Table | PK | Inc Key | Inc Strategy | Details |
44
+ | ----- | -- | ------- | ------------ | ------- |
45
+ | [account](https://mailchimp.com/developer/marketing/api/root/) | - | - | replace | Retrieves account information including company details, account tier, and contact information. |
46
+ | [account_exports](https://mailchimp.com/developer/marketing/api/account-exports/) | - | - | replace | Retrieves account export information. |
47
+ | [audiences](https://mailchimp.com/developer/marketing/api/lists/) | id | date_created | merge | Retrieves audience (list) information including subscriber counts and list settings. |
48
+ | [authorized_apps](https://mailchimp.com/developer/marketing/api/authorized-apps/) | id | - | replace | Retrieves third-party applications authorized to access your account. |
49
+ | [automations](https://mailchimp.com/developer/marketing/api/automations/) | id | create_time | merge | Retrieves automated email workflows and their configurations. |
50
+ | [batches](https://mailchimp.com/developer/marketing/api/batches/) | - | - | replace | Retrieves batch operation status and results. |
51
+ | [campaign_folders](https://mailchimp.com/developer/marketing/api/campaign-folders/) | id | - | replace | Retrieves folders used to organize campaigns. |
52
+ | [campaigns](https://mailchimp.com/developer/marketing/api/campaigns/) | id | create_time | merge | Retrieves email campaigns including their content, settings, and metadata. |
53
+ | [chimp_chatter](https://mailchimp.com/developer/marketing/api/activity-feed/) | - | - | replace | Retrieves recent activity feed from your Mailchimp account. |
54
+ | [connected_sites](https://mailchimp.com/developer/marketing/api/connected-sites/) | id | updated_at | merge | Retrieves websites connected to your Mailchimp account. |
55
+ | [conversations](https://mailchimp.com/developer/marketing/api/conversations/) | id | last_message.timestamp | merge | Retrieves conversation threads from connected channels. |
56
+ | [ecommerce_stores](https://mailchimp.com/developer/marketing/api/ecommerce-stores/) | id | updated_at | merge | Retrieves e-commerce store information including products and orders. |
57
+ | [facebook_ads](https://mailchimp.com/developer/marketing/api/facebook-ads/) | id | updated_at | merge | Retrieves Facebook ad campaigns managed through Mailchimp. |
58
+ | [landing_pages](https://mailchimp.com/developer/marketing/api/landing-pages/) | id | updated_at | merge | Retrieves landing pages created in Mailchimp. |
59
+ | lists_activity | - | - | replace | Retrieves recent activity for list members. Includes `audiences_id` reference. |
60
+ | lists_clients | - | - | replace | Retrieves email clients used by list members. Includes `audiences_id` reference. |
61
+ | lists_growth_history | - | - | replace | Retrieves historical growth data for the list. Includes `audiences_id` reference. |
62
+ | lists_interest_categories | - | - | replace | Retrieves interest categories (groups) for the list. Includes `audiences_id` reference. |
63
+ | lists_locations | - | - | replace | Retrieves geographic locations of list members. Includes `audiences_id` reference. |
64
+ | lists_merge_fields | - | - | replace | Retrieves custom merge fields defined for the list. Includes `audiences_id` reference. |
65
+ | lists_segments | - | - | replace | Retrieves segments (filtered subsets) of the list. Includes `audiences_id` reference. |
66
+ | [reports](https://mailchimp.com/developer/marketing/api/reports/) | id | send_time | merge | Retrieves campaign performance reports and analytics. |
67
+ | reports_advice | - | - | replace | Retrieves feedback and suggestions for improving campaign performance. Includes `reports_id` reference. |
68
+ | reports_domain_performance | - | - | replace | Retrieves email performance broken down by email domain. Includes `reports_id` reference. |
69
+ | reports_locations | - | - | replace | Retrieves geographic location data for campaign opens. Includes `reports_id` reference. |
70
+ | reports_sent_to | - | - | replace | Retrieves list of recipients who were sent the campaign. Includes `reports_id` reference. |
71
+ | reports_sub_reports | - | - | replace | Retrieves sub-reports for A/B test campaigns. Includes `reports_id` reference. |
72
+ | reports_unsubscribed | - | - | replace | Retrieves list of members who unsubscribed from the campaign. Includes `reports_id` reference. |
73
+
74
+ Use these as `--source-table` parameter in the `ingestr ingest` command.
75
+
76
+ ## Examples
77
+
78
+ ### Ingesting Campaign Data
79
+
80
+ ```sh
81
+ ingestr ingest \
82
+ --source-uri 'mailchimp://?api_key=your_api_key&server=us10' \
83
+ --source-table 'campaigns' \
84
+ --dest-uri duckdb:///mailchimp.duckdb \
85
+ --dest-table 'mailchimp.campaigns'
86
+ ```
87
+
88
+
89
+
90
+ The `reports_advice` table will include a `reports_id` column that references the parent campaign report.
91
+
92
+
93
+ The `lists_segments` table will include an `audiences_id` column that references the parent audience/list.
94
+
95
+ ## Notes
96
+
97
+ > [!NOTE]
98
+ > Nested resources (e.g., `reports_advice`, `lists_segments`) automatically include a reference to their parent resource through an ID column (`reports_id` or `audiences_id`).
99
+
@@ -0,0 +1 @@
1
+ version = "v0.14.91"
@@ -64,6 +64,7 @@ from ingestr.src.sources import (
64
64
  LinearSource,
65
65
  LinkedInAdsSource,
66
66
  LocalCsvSource,
67
+ MailchimpSource,
67
68
  MixpanelSource,
68
69
  MondaySource,
69
70
  MongoDbSource,
@@ -219,6 +220,7 @@ class SourceDestinationFactory:
219
220
  "wise": WiseSource,
220
221
  "plusvibeai": PlusVibeAISource,
221
222
  "monday": MondaySource,
223
+ "mailchimp": MailchimpSource,
222
224
  }
223
225
  destinations: Dict[str, Type[DestinationProtocol]] = {
224
226
  "bigquery": BigQueryDestination,
@@ -10,6 +10,8 @@ from dlt.sources.helpers import requests
10
10
 
11
11
  from ingestr.src.errors import HTTPError
12
12
 
13
+ TICKETS_QUERY_MAX_PAGE = 10
14
+
13
15
 
14
16
  class FreshdeskClient:
15
17
  """
@@ -85,6 +87,8 @@ class FreshdeskClient:
85
87
  if query is not None:
86
88
  query = query.replace('"', "").strip()
87
89
 
90
+ is_tickets_query = query and endpoint == "tickets"
91
+
88
92
  while True:
89
93
  # Construct the URL for the specific endpoint
90
94
  url = f"{self.base_url}/{endpoint}"
@@ -99,7 +103,7 @@ class FreshdeskClient:
99
103
 
100
104
  params[param_key] = start_date.to_iso8601_string()
101
105
 
102
- if query and endpoint == "tickets":
106
+ if is_tickets_query:
103
107
  url = f"{self.base_url}/search/tickets"
104
108
  params = {
105
109
  "query": f'"{query}"',
@@ -127,3 +131,7 @@ class FreshdeskClient:
127
131
  break
128
132
  yield filtered_data
129
133
  page += 1
134
+
135
+ # https://developers.freshdesk.com/api/#filter_tickets
136
+ if is_tickets_query and page > TICKETS_QUERY_MAX_PAGE:
137
+ break
@@ -0,0 +1,126 @@
1
+ """
2
+ Mailchimp source for data extraction via REST API.
3
+
4
+ This source provides access to Mailchimp account data.
5
+ """
6
+
7
+ from typing import Any, Iterable, Iterator
8
+
9
+ import dlt
10
+ from dlt.sources import DltResource
11
+
12
+ from ingestr.src.http_client import create_client
13
+ from ingestr.src.mailchimp.helpers import (
14
+ create_merge_resource,
15
+ create_nested_resource,
16
+ create_replace_resource,
17
+ )
18
+ from ingestr.src.mailchimp.settings import (
19
+ MERGE_ENDPOINTS,
20
+ NESTED_ENDPOINTS,
21
+ REPLACE_ENDPOINTS,
22
+ )
23
+
24
+
25
+ @dlt.source(max_table_nesting=0, name="mailchimp_source")
26
+ def mailchimp_source(
27
+ api_key: str,
28
+ server: str,
29
+ ) -> Iterable[DltResource]:
30
+ """
31
+ Mailchimp data source.
32
+
33
+ Args:
34
+ api_key: Mailchimp API key for authentication
35
+ server: Server prefix (e.g., 'us10')
36
+
37
+ Yields:
38
+ DltResource: Data resources for Mailchimp data
39
+ """
40
+ base_url = f"https://{server}.api.mailchimp.com/3.0"
41
+ session = create_client()
42
+ auth = ("anystring", api_key)
43
+
44
+ @dlt.resource(
45
+ name="account",
46
+ write_disposition="replace",
47
+ )
48
+ def fetch_account() -> Iterator[dict[str, Any]]:
49
+ """
50
+ Fetch account information from Mailchimp.
51
+
52
+ Table format: account (no parameters needed)
53
+ """
54
+ response = session.get(f"{base_url}/", auth=auth)
55
+ response.raise_for_status()
56
+ data = response.json()
57
+ yield data
58
+
59
+ # Create resources dynamically
60
+ resources = [fetch_account]
61
+
62
+ # Create merge resources (with incremental loading)
63
+ for (
64
+ resource_name,
65
+ endpoint_path,
66
+ data_key,
67
+ primary_key,
68
+ incremental_key,
69
+ ) in MERGE_ENDPOINTS:
70
+ resources.append(
71
+ create_merge_resource(
72
+ base_url,
73
+ session,
74
+ auth,
75
+ resource_name,
76
+ endpoint_path,
77
+ data_key,
78
+ primary_key,
79
+ incremental_key,
80
+ )
81
+ )
82
+
83
+ # Create replace resources (without incremental loading)
84
+ for replace_endpoint in REPLACE_ENDPOINTS:
85
+ resource_name, endpoint_path, data_key, pk = replace_endpoint
86
+ resources.append(
87
+ create_replace_resource(
88
+ base_url,
89
+ session,
90
+ auth,
91
+ resource_name,
92
+ endpoint_path,
93
+ data_key,
94
+ pk,
95
+ )
96
+ )
97
+
98
+ # Create nested resources (depend on parent resources)
99
+ for nested_endpoint in NESTED_ENDPOINTS:
100
+ (
101
+ parent_name,
102
+ parent_path,
103
+ parent_key,
104
+ parent_id_field,
105
+ nested_name,
106
+ nested_path,
107
+ nested_key,
108
+ pk,
109
+ ) = nested_endpoint
110
+ resources.append(
111
+ create_nested_resource(
112
+ base_url,
113
+ session,
114
+ auth,
115
+ parent_name,
116
+ parent_path,
117
+ parent_key,
118
+ parent_id_field,
119
+ nested_name,
120
+ nested_path,
121
+ nested_key,
122
+ pk,
123
+ )
124
+ )
125
+
126
+ return tuple(resources)
@@ -0,0 +1,226 @@
1
+ """
2
+ Helper functions for Mailchimp source.
3
+ """
4
+
5
+ from typing import Any, Iterator
6
+
7
+ import dlt
8
+
9
+
10
+ def fetch_paginated(
11
+ session,
12
+ url: str,
13
+ auth: tuple,
14
+ data_key: str | None = None,
15
+ ) -> Iterator[dict[str, Any]]:
16
+ """
17
+ Helper function to fetch paginated data from Mailchimp API.
18
+
19
+ Args:
20
+ session: HTTP session
21
+ url: API endpoint URL
22
+ auth: Authentication tuple
23
+ data_key: Key in response containing the data array (if None, return whole response)
24
+
25
+ Yields:
26
+ Individual items from the paginated response
27
+ """
28
+ offset = 0
29
+ count = 1000 # Maximum allowed by Mailchimp
30
+
31
+ while True:
32
+ params = {"count": count, "offset": offset}
33
+ response = session.get(url, auth=auth, params=params)
34
+ response.raise_for_status()
35
+ data = response.json()
36
+
37
+ # Extract items from response
38
+ if data_key and data_key in data:
39
+ items = data[data_key]
40
+ elif isinstance(data, list):
41
+ items = data
42
+ else:
43
+ # If no data_key specified and response is dict, yield the whole response
44
+ yield data
45
+ break
46
+
47
+ if not items:
48
+ break
49
+
50
+ yield from items
51
+
52
+ # Check if we've received fewer items than requested (last page)
53
+ if len(items) < count:
54
+ break
55
+
56
+ offset += count
57
+
58
+
59
+ def create_merge_resource(
60
+ base_url: str,
61
+ session,
62
+ auth: tuple,
63
+ name: str,
64
+ path: str,
65
+ key: str,
66
+ pk: str,
67
+ ik: str,
68
+ ):
69
+ """
70
+ Create a DLT resource with merge disposition for incremental loading.
71
+
72
+ Args:
73
+ base_url: Base API URL
74
+ session: HTTP session
75
+ auth: Authentication tuple
76
+ name: Resource name
77
+ path: API endpoint path
78
+ key: Data key in response
79
+ pk: Primary key field
80
+ ik: Incremental key field
81
+
82
+ Returns:
83
+ DLT resource function
84
+ """
85
+
86
+ @dlt.resource(
87
+ name=name,
88
+ write_disposition="merge",
89
+ primary_key=pk,
90
+ )
91
+ def fetch_data(
92
+ updated_at: dlt.sources.incremental[str] = dlt.sources.incremental(
93
+ ik, initial_value=None
94
+ ),
95
+ ) -> Iterator[dict[str, Any]]:
96
+ url = f"{base_url}/{path}"
97
+ yield from fetch_paginated(session, url, auth, data_key=key)
98
+
99
+ return fetch_data
100
+
101
+
102
+ def create_replace_resource(
103
+ base_url: str,
104
+ session,
105
+ auth: tuple,
106
+ name: str,
107
+ path: str,
108
+ key: str,
109
+ pk: str | None,
110
+ ):
111
+ """
112
+ Create a DLT resource with replace disposition.
113
+
114
+ Args:
115
+ base_url: Base API URL
116
+ session: HTTP session
117
+ auth: Authentication tuple
118
+ name: Resource name
119
+ path: API endpoint path
120
+ key: Data key in response
121
+ pk: Primary key field (optional)
122
+
123
+ Returns:
124
+ DLT resource function
125
+ """
126
+
127
+ def fetch_data() -> Iterator[dict[str, Any]]:
128
+ url = f"{base_url}/{path}"
129
+ yield from fetch_paginated(session, url, auth, data_key=key)
130
+
131
+ # Apply the resource decorator with conditional primary_key
132
+ if pk is not None:
133
+ return dlt.resource(
134
+ fetch_data,
135
+ name=name,
136
+ write_disposition="replace",
137
+ primary_key=pk,
138
+ )
139
+ else:
140
+ return dlt.resource(
141
+ fetch_data,
142
+ name=name,
143
+ write_disposition="replace",
144
+ )
145
+
146
+
147
+ def create_nested_resource(
148
+ base_url: str,
149
+ session,
150
+ auth: tuple,
151
+ parent_resource_name: str,
152
+ parent_path: str,
153
+ parent_key: str,
154
+ parent_id_field: str,
155
+ nested_name: str,
156
+ nested_path: str,
157
+ nested_key: str | None,
158
+ pk: str | None,
159
+ ):
160
+ """
161
+ Create a nested DLT resource that depends on a parent resource.
162
+
163
+ Args:
164
+ base_url: Base API URL
165
+ session: HTTP session
166
+ auth: Authentication tuple
167
+ parent_resource_name: Name of the parent resource
168
+ parent_path: Parent API endpoint path
169
+ parent_key: Data key in parent response
170
+ parent_id_field: Field name for parent ID
171
+ nested_name: Nested resource name
172
+ nested_path: Nested API endpoint path (with {id} placeholder)
173
+ nested_key: Data key in nested response (None to return whole response)
174
+ pk: Primary key field (optional)
175
+
176
+ Returns:
177
+ DLT resource function
178
+ """
179
+
180
+ def fetch_nested_data() -> Iterator[dict[str, Any]]:
181
+ # First, fetch parent items
182
+ parent_url = f"{base_url}/{parent_path}"
183
+ parent_items = fetch_paginated(session, parent_url, auth, data_key=parent_key)
184
+
185
+ # For each parent item, fetch nested data
186
+ for parent_item in parent_items:
187
+ parent_id = parent_item.get(parent_id_field)
188
+ if parent_id:
189
+ # Build nested URL with parent ID
190
+ nested_url = f"{base_url}/{nested_path.format(id=parent_id)}"
191
+
192
+ # Fetch nested data
193
+ response = session.get(nested_url, auth=auth)
194
+ response.raise_for_status()
195
+ data = response.json()
196
+
197
+ # Extract nested items or return whole response
198
+ if nested_key and nested_key in data:
199
+ items = data[nested_key]
200
+ if isinstance(items, list):
201
+ for item in items:
202
+ # Add parent reference
203
+ item[f"{parent_resource_name}_id"] = parent_id
204
+ yield item
205
+ else:
206
+ items[f"{parent_resource_name}_id"] = parent_id
207
+ yield items
208
+ else:
209
+ # Return whole response with parent reference
210
+ data[f"{parent_resource_name}_id"] = parent_id
211
+ yield data
212
+
213
+ # Apply the resource decorator with conditional primary_key
214
+ if pk is not None:
215
+ return dlt.resource(
216
+ fetch_nested_data,
217
+ name=nested_name,
218
+ write_disposition="replace",
219
+ primary_key=pk,
220
+ )
221
+ else:
222
+ return dlt.resource(
223
+ fetch_nested_data,
224
+ name=nested_name,
225
+ write_disposition="replace",
226
+ )