ingestr 0.13.80__tar.gz → 0.13.82__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 (325) hide show
  1. {ingestr-0.13.80 → ingestr-0.13.82}/PKG-INFO +1 -1
  2. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/facebook-ads.md +63 -5
  3. ingestr-0.13.82/docs/supported-sources/linear.md +60 -0
  4. ingestr-0.13.82/ingestr/src/buildinfo.py +1 -0
  5. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/facebook_ads/__init__.py +9 -15
  6. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/facebook_ads/helpers.py +46 -0
  7. ingestr-0.13.82/ingestr/src/linear/__init__.py +557 -0
  8. ingestr-0.13.82/ingestr/src/linear/helpers.py +101 -0
  9. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/sources.py +23 -20
  10. ingestr-0.13.80/docs/supported-sources/linear.md +0 -41
  11. ingestr-0.13.80/ingestr/src/buildinfo.py +0 -1
  12. ingestr-0.13.80/ingestr/src/linear/__init__.py +0 -215
  13. ingestr-0.13.80/ingestr/src/linear/helpers.py +0 -55
  14. {ingestr-0.13.80 → ingestr-0.13.82}/.dlt/config.toml +0 -0
  15. {ingestr-0.13.80 → ingestr-0.13.82}/.dockerignore +0 -0
  16. {ingestr-0.13.80 → ingestr-0.13.82}/.githooks/pre-commit-hook.sh +0 -0
  17. {ingestr-0.13.80 → ingestr-0.13.82}/.github/workflows/deploy-docs.yml +0 -0
  18. {ingestr-0.13.80 → ingestr-0.13.82}/.github/workflows/release.yml +0 -0
  19. {ingestr-0.13.80 → ingestr-0.13.82}/.github/workflows/secrets-scan.yml +0 -0
  20. {ingestr-0.13.80 → ingestr-0.13.82}/.github/workflows/tests.yml +0 -0
  21. {ingestr-0.13.80 → ingestr-0.13.82}/.gitignore +0 -0
  22. {ingestr-0.13.80 → ingestr-0.13.82}/.gitleaksignore +0 -0
  23. {ingestr-0.13.80 → ingestr-0.13.82}/.python-version +0 -0
  24. {ingestr-0.13.80 → ingestr-0.13.82}/.vale.ini +0 -0
  25. {ingestr-0.13.80 → ingestr-0.13.82}/Dockerfile +0 -0
  26. {ingestr-0.13.80 → ingestr-0.13.82}/LICENSE.md +0 -0
  27. {ingestr-0.13.80 → ingestr-0.13.82}/Makefile +0 -0
  28. {ingestr-0.13.80 → ingestr-0.13.82}/README.md +0 -0
  29. {ingestr-0.13.80 → ingestr-0.13.82}/docs/.vitepress/config.mjs +0 -0
  30. {ingestr-0.13.80 → ingestr-0.13.82}/docs/.vitepress/theme/custom.css +0 -0
  31. {ingestr-0.13.80 → ingestr-0.13.82}/docs/.vitepress/theme/index.js +0 -0
  32. {ingestr-0.13.80 → ingestr-0.13.82}/docs/commands/example-uris.md +0 -0
  33. {ingestr-0.13.80 → ingestr-0.13.82}/docs/commands/ingest.md +0 -0
  34. {ingestr-0.13.80 → ingestr-0.13.82}/docs/getting-started/core-concepts.md +0 -0
  35. {ingestr-0.13.80 → ingestr-0.13.82}/docs/getting-started/incremental-loading.md +0 -0
  36. {ingestr-0.13.80 → ingestr-0.13.82}/docs/getting-started/quickstart.md +0 -0
  37. {ingestr-0.13.80 → ingestr-0.13.82}/docs/getting-started/telemetry.md +0 -0
  38. {ingestr-0.13.80 → ingestr-0.13.82}/docs/index.md +0 -0
  39. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/applovin_max.png +0 -0
  40. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/athena.png +0 -0
  41. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/clickhouse_img.png +0 -0
  42. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/clickup_ingestion.png +0 -0
  43. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/cratedb-destination.png +0 -0
  44. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/cratedb-source.png +0 -0
  45. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/freshdesk_ingestion.png +0 -0
  46. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/gcp_spanner_ingestion.png +0 -0
  47. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/github.png +0 -0
  48. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/google_analytics_realtime_report.png +0 -0
  49. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/googleanalytics.png +0 -0
  50. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/ingestion_elasticsearch_img.png +0 -0
  51. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/kinesis.bigquery.png +0 -0
  52. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/linear.png +0 -0
  53. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/linkedin_ads.png +0 -0
  54. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/mixpanel_ingestion.png +0 -0
  55. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/personio.png +0 -0
  56. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/personio_duckdb.png +0 -0
  57. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/phantombuster.png +0 -0
  58. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/pipedrive.png +0 -0
  59. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/quickbook_ingestion.png +0 -0
  60. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/sftp.png +0 -0
  61. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/stripe_postgres.png +0 -0
  62. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/tiktok.png +0 -0
  63. {ingestr-0.13.80 → ingestr-0.13.82}/docs/media/zoom_ingestion.png +0 -0
  64. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/adjust.md +0 -0
  65. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/airtable.md +0 -0
  66. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/applovin.md +0 -0
  67. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/applovin_max.md +0 -0
  68. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/appsflyer.md +0 -0
  69. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/appstore.md +0 -0
  70. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/asana.md +0 -0
  71. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/athena.md +0 -0
  72. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/attio.md +0 -0
  73. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/bigquery.md +0 -0
  74. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/chess.md +0 -0
  75. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/clickhouse.md +0 -0
  76. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/clickup.md +0 -0
  77. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/cratedb.md +0 -0
  78. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/csv.md +0 -0
  79. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/custom_queries.md +0 -0
  80. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/databricks.md +0 -0
  81. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/db2.md +0 -0
  82. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/duckdb.md +0 -0
  83. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/dynamodb.md +0 -0
  84. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/elasticsearch.md +0 -0
  85. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/frankfurter.md +0 -0
  86. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/freshdesk.md +0 -0
  87. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/gcs.md +0 -0
  88. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/github.md +0 -0
  89. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/google-ads.md +0 -0
  90. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/google_analytics.md +0 -0
  91. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/gorgias.md +0 -0
  92. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/gsheets.md +0 -0
  93. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/hubspot.md +0 -0
  94. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/influxdb.md +0 -0
  95. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/isoc-pulse.md +0 -0
  96. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/kafka.md +0 -0
  97. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/kinesis.md +0 -0
  98. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/klaviyo.md +0 -0
  99. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/linkedin_ads.md +0 -0
  100. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/mixpanel.md +0 -0
  101. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/mongodb.md +0 -0
  102. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/motherduck.md +0 -0
  103. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/mssql.md +0 -0
  104. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/mysql.md +0 -0
  105. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/notion.md +0 -0
  106. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/oracle.md +0 -0
  107. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/personio.md +0 -0
  108. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/phantombuster.md +0 -0
  109. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/pinterest.md +0 -0
  110. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/pipedrive.md +0 -0
  111. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/postgres.md +0 -0
  112. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/quickbooks.md +0 -0
  113. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/redshift.md +0 -0
  114. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/s3.md +0 -0
  115. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/salesforce.md +0 -0
  116. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/sap-hana.md +0 -0
  117. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/sftp.md +0 -0
  118. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/shopify.md +0 -0
  119. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/slack.md +0 -0
  120. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/smartsheets.md +0 -0
  121. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/snowflake.md +0 -0
  122. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/solidgate.md +0 -0
  123. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/spanner.md +0 -0
  124. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/sqlite.md +0 -0
  125. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/stripe.md +0 -0
  126. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/tiktok-ads.md +0 -0
  127. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/trustpilot.md +0 -0
  128. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/zendesk.md +0 -0
  129. {ingestr-0.13.80 → ingestr-0.13.82}/docs/supported-sources/zoom.md +0 -0
  130. {ingestr-0.13.80 → ingestr-0.13.82}/docs/tutorials/load-kinesis-bigquery.md +0 -0
  131. {ingestr-0.13.80 → ingestr-0.13.82}/docs/tutorials/load-personio-duckdb.md +0 -0
  132. {ingestr-0.13.80 → ingestr-0.13.82}/docs/tutorials/load-stripe-postgres.md +0 -0
  133. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/conftest.py +0 -0
  134. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/main.py +0 -0
  135. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/.gitignore +0 -0
  136. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/adjust/__init__.py +0 -0
  137. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/adjust/adjust_helpers.py +0 -0
  138. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/airtable/__init__.py +0 -0
  139. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/applovin/__init__.py +0 -0
  140. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/applovin_max/__init__.py +0 -0
  141. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/appsflyer/__init__.py +0 -0
  142. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/appsflyer/client.py +0 -0
  143. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/appstore/__init__.py +0 -0
  144. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/appstore/client.py +0 -0
  145. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/appstore/errors.py +0 -0
  146. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/appstore/models.py +0 -0
  147. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/appstore/resources.py +0 -0
  148. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/arrow/__init__.py +0 -0
  149. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/asana_source/__init__.py +0 -0
  150. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/asana_source/helpers.py +0 -0
  151. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/asana_source/settings.py +0 -0
  152. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/attio/__init__.py +0 -0
  153. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/attio/helpers.py +0 -0
  154. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/blob.py +0 -0
  155. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/chess/__init__.py +0 -0
  156. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/chess/helpers.py +0 -0
  157. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/chess/settings.py +0 -0
  158. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/clickup/__init__.py +0 -0
  159. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/clickup/helpers.py +0 -0
  160. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/collector/spinner.py +0 -0
  161. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/destinations.py +0 -0
  162. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/dynamodb/__init__.py +0 -0
  163. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/elasticsearch/__init__.py +0 -0
  164. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/errors.py +0 -0
  165. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/facebook_ads/exceptions.py +0 -0
  166. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/facebook_ads/settings.py +0 -0
  167. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/facebook_ads/utils.py +0 -0
  168. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/factory.py +0 -0
  169. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/filesystem/__init__.py +0 -0
  170. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/filesystem/helpers.py +0 -0
  171. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/filesystem/readers.py +0 -0
  172. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/filters.py +0 -0
  173. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/frankfurter/__init__.py +0 -0
  174. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/frankfurter/helpers.py +0 -0
  175. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/freshdesk/__init__.py +0 -0
  176. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/freshdesk/freshdesk_client.py +0 -0
  177. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/freshdesk/settings.py +0 -0
  178. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/github/__init__.py +0 -0
  179. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/github/helpers.py +0 -0
  180. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/github/queries.py +0 -0
  181. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/github/settings.py +0 -0
  182. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_ads/__init__.py +0 -0
  183. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_ads/field.py +0 -0
  184. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_ads/metrics.py +0 -0
  185. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_ads/predicates.py +0 -0
  186. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_ads/reports.py +0 -0
  187. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_analytics/__init__.py +0 -0
  188. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_analytics/helpers.py +0 -0
  189. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_sheets/README.md +0 -0
  190. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_sheets/__init__.py +0 -0
  191. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
  192. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
  193. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
  194. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/gorgias/__init__.py +0 -0
  195. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/gorgias/helpers.py +0 -0
  196. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/http_client.py +0 -0
  197. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/hubspot/__init__.py +0 -0
  198. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/hubspot/helpers.py +0 -0
  199. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/hubspot/settings.py +0 -0
  200. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/influxdb/__init__.py +0 -0
  201. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/influxdb/client.py +0 -0
  202. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/isoc_pulse/__init__.py +0 -0
  203. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/kafka/__init__.py +0 -0
  204. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/kafka/helpers.py +0 -0
  205. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/kinesis/__init__.py +0 -0
  206. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/kinesis/helpers.py +0 -0
  207. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/klaviyo/__init__.py +0 -0
  208. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/klaviyo/client.py +0 -0
  209. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/klaviyo/helpers.py +0 -0
  210. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/linkedin_ads/__init__.py +0 -0
  211. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
  212. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/linkedin_ads/helpers.py +0 -0
  213. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/loader.py +0 -0
  214. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/mixpanel/__init__.py +0 -0
  215. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/mixpanel/client.py +0 -0
  216. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/mongodb/__init__.py +0 -0
  217. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/mongodb/helpers.py +0 -0
  218. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/notion/__init__.py +0 -0
  219. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/notion/helpers/__init__.py +0 -0
  220. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/notion/helpers/client.py +0 -0
  221. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/notion/helpers/database.py +0 -0
  222. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/notion/settings.py +0 -0
  223. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/partition.py +0 -0
  224. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/personio/__init__.py +0 -0
  225. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/personio/helpers.py +0 -0
  226. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/phantombuster/__init__.py +0 -0
  227. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/phantombuster/client.py +0 -0
  228. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/pinterest/__init__.py +0 -0
  229. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/pipedrive/__init__.py +0 -0
  230. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/pipedrive/helpers/__init__.py +0 -0
  231. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/pipedrive/helpers/custom_fields_munger.py +0 -0
  232. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/pipedrive/helpers/pages.py +0 -0
  233. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/pipedrive/settings.py +0 -0
  234. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/pipedrive/typing.py +0 -0
  235. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/quickbooks/__init__.py +0 -0
  236. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/resource.py +0 -0
  237. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/salesforce/__init__.py +0 -0
  238. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/salesforce/helpers.py +0 -0
  239. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/shopify/__init__.py +0 -0
  240. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/shopify/exceptions.py +0 -0
  241. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/shopify/helpers.py +0 -0
  242. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/shopify/settings.py +0 -0
  243. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/slack/__init__.py +0 -0
  244. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/slack/helpers.py +0 -0
  245. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/slack/settings.py +0 -0
  246. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/smartsheets/__init__.py +0 -0
  247. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/solidgate/__init__.py +0 -0
  248. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/solidgate/helpers.py +0 -0
  249. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/sql_database/__init__.py +0 -0
  250. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/sql_database/callbacks.py +0 -0
  251. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/stripe_analytics/__init__.py +0 -0
  252. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/stripe_analytics/helpers.py +0 -0
  253. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/stripe_analytics/settings.py +0 -0
  254. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/table_definition.py +0 -0
  255. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/telemetry/event.py +0 -0
  256. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/testdata/fakebqcredentials.json +0 -0
  257. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/tiktok_ads/__init__.py +0 -0
  258. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
  259. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/time.py +0 -0
  260. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/trustpilot/__init__.py +0 -0
  261. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/trustpilot/client.py +0 -0
  262. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/version.py +0 -0
  263. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/zendesk/__init__.py +0 -0
  264. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/zendesk/helpers/__init__.py +0 -0
  265. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
  266. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/zendesk/helpers/credentials.py +0 -0
  267. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
  268. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/zendesk/settings.py +0 -0
  269. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/zoom/__init__.py +0 -0
  270. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/src/zoom/helpers.py +0 -0
  271. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/testdata/.gitignore +0 -0
  272. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/testdata/create_replace.csv +0 -0
  273. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/testdata/delete_insert_expected.csv +0 -0
  274. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/testdata/delete_insert_part1.csv +0 -0
  275. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/testdata/delete_insert_part2.csv +0 -0
  276. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/testdata/merge_expected.csv +0 -0
  277. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/testdata/merge_part1.csv +0 -0
  278. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/testdata/merge_part2.csv +0 -0
  279. {ingestr-0.13.80 → ingestr-0.13.82}/ingestr/tests/unit/test_smartsheets.py +0 -0
  280. {ingestr-0.13.80 → ingestr-0.13.82}/package-lock.json +0 -0
  281. {ingestr-0.13.80 → ingestr-0.13.82}/package.json +0 -0
  282. {ingestr-0.13.80 → ingestr-0.13.82}/pyproject.toml +0 -0
  283. {ingestr-0.13.80 → ingestr-0.13.82}/requirements-dev.txt +0 -0
  284. {ingestr-0.13.80 → ingestr-0.13.82}/requirements.in +0 -0
  285. {ingestr-0.13.80 → ingestr-0.13.82}/requirements.txt +0 -0
  286. {ingestr-0.13.80 → ingestr-0.13.82}/requirements_arm64.txt +0 -0
  287. {ingestr-0.13.80 → ingestr-0.13.82}/resources/demo.gif +0 -0
  288. {ingestr-0.13.80 → ingestr-0.13.82}/resources/demo.tape +0 -0
  289. {ingestr-0.13.80 → ingestr-0.13.82}/resources/ingestr.svg +0 -0
  290. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/AMPM.yml +0 -0
  291. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Acronyms.yml +0 -0
  292. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Colons.yml +0 -0
  293. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Contractions.yml +0 -0
  294. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/DateFormat.yml +0 -0
  295. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Ellipses.yml +0 -0
  296. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/EmDash.yml +0 -0
  297. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Exclamation.yml +0 -0
  298. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/FirstPerson.yml +0 -0
  299. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Gender.yml +0 -0
  300. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/GenderBias.yml +0 -0
  301. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/HeadingPunctuation.yml +0 -0
  302. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Headings.yml +0 -0
  303. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Latin.yml +0 -0
  304. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/LyHyphens.yml +0 -0
  305. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/OptionalPlurals.yml +0 -0
  306. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Ordinal.yml +0 -0
  307. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/OxfordComma.yml +0 -0
  308. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Parens.yml +0 -0
  309. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Passive.yml +0 -0
  310. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Periods.yml +0 -0
  311. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Quotes.yml +0 -0
  312. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Ranges.yml +0 -0
  313. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Semicolons.yml +0 -0
  314. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Slang.yml +0 -0
  315. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Spacing.yml +0 -0
  316. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Spelling.yml +0 -0
  317. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Units.yml +0 -0
  318. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/We.yml +0 -0
  319. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/Will.yml +0 -0
  320. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/WordList.yml +0 -0
  321. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/meta.json +0 -0
  322. {ingestr-0.13.80 → ingestr-0.13.82}/styles/Google/vocab.txt +0 -0
  323. {ingestr-0.13.80 → ingestr-0.13.82}/styles/bruin/Ingestr.yml +0 -0
  324. {ingestr-0.13.80 → ingestr-0.13.82}/styles/config/vocabularies/bruin/accept.txt +0 -0
  325. {ingestr-0.13.80 → ingestr-0.13.82}/test.env.template +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ingestr
3
- Version: 0.13.80
3
+ Version: 0.13.82
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
@@ -160,13 +160,19 @@ The `facebook_insights` table supports advanced configuration for breakdowns and
160
160
  1. **Default usage**: `facebook_insights`
161
161
  - Uses default breakdown and default fields
162
162
 
163
- 2. **Custom breakdown**: `facebook_insights:breakdown_type`
164
- - Uses specified breakdown with default fields
163
+ 2. **Predefined breakdown**: `facebook_insights:breakdown_type`
164
+ - Uses specified predefined breakdown with default fields
165
165
 
166
- 3. **Custom breakdown + metrics**: `facebook_insights:breakdown_type:metric1,metric2,metric3`
167
- - Uses specified breakdown with custom metrics
166
+ 3. **Predefined breakdown + custom metrics**: `facebook_insights:breakdown_type:metric1,metric2,metric3`
167
+ - Uses specified predefined breakdown with custom metrics
168
168
 
169
- #### Available Breakdown Types
169
+ 4. **Custom dimensions + metrics**: `facebook_insights:dimension1,dimension2:metric1,metric2,metric3`
170
+ - Uses custom dimensions with custom metrics
171
+
172
+ 5. **Level + dimensions + metrics**: `facebook_insights:level,dimension1,dimension2:metric1,metric2,metric3`
173
+ - Uses specified level with custom dimensions and metrics
174
+
175
+ #### Available Predefined Breakdown Types
170
176
 
171
177
  - `ads_insights` (default)
172
178
  - `ads_insights_age_and_gender`
@@ -176,6 +182,30 @@ The `facebook_insights` table supports advanced configuration for breakdowns and
176
182
  - `ads_insights_dma`
177
183
  - `ads_insights_hourly_advertiser`
178
184
 
185
+ #### Available Levels
186
+
187
+ When using custom dimensions, you can specify one of these levels:
188
+ - `account` - Account level insights
189
+ - `campaign` - Campaign level insights
190
+ - `adset` - Ad set level insights
191
+ - `ad` - Ad level insights
192
+
193
+ Note: If multiple levels are specified in the dimensions list, the last valid level will be used and removed from the dimensions list.
194
+
195
+ #### Common Dimensions
196
+
197
+ You can use any valid Facebook Ads dimension in your custom configurations. Some commonly used dimensions include:
198
+ - `age` - Age ranges
199
+ - `gender` - Gender breakdown
200
+ - `country` - Country breakdown
201
+ - `region` - Region breakdown
202
+ - `platform_position` - Platform position
203
+ - `publisher_platform` - Publisher platform
204
+ - `impression_device` - Device type
205
+ - `placement` - Ad placement
206
+
207
+ Note: Not all dimension combinations are valid according to Facebook's API. Refer to [Facebook's Marketing API](https://developers.facebook.com/docs/marketing-api/insights/breakdowns/) documentation for valid dimension combinations.
208
+
179
209
  #### Examples
180
210
 
181
211
  ```sh
@@ -199,4 +229,32 @@ ingestr ingest \
199
229
  --source-table 'facebook_insights:ads_insights_country:impressions,clicks,spend,reach,cpm,ctr' \
200
230
  --dest-uri 'duckdb:///facebook.duckdb' \
201
231
  --dest-table 'dest.insights_by_country'
232
+
233
+ # Custom dimensions (age and gender) with custom metrics
234
+ ingestr ingest \
235
+ --source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
236
+ --source-table 'facebook_insights:age,gender:impressions,clicks,spend' \
237
+ --dest-uri 'duckdb:///facebook.duckdb' \
238
+ --dest-table 'dest.insights_custom_dimensions'
239
+
240
+ # Campaign level with custom dimensions and metrics
241
+ ingestr ingest \
242
+ --source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
243
+ --source-table 'facebook_insights:campaign,age,gender:impressions,clicks,spend,reach' \
244
+ --dest-uri 'duckdb:///facebook.duckdb' \
245
+ --dest-table 'dest.campaign_insights_demographics'
246
+
247
+ # Ad level with geographic dimensions
248
+ ingestr ingest \
249
+ --source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
250
+ --source-table 'facebook_insights:ad,country,region:clicks,impressions,spend' \
251
+ --dest-uri 'duckdb:///facebook.duckdb' \
252
+ --dest-table 'dest.ad_insights_geographic'
253
+
254
+ # Account level insights only (no additional dimensions)
255
+ ingestr ingest \
256
+ --source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
257
+ --source-table 'facebook_insights:account:impressions,clicks,spend,reach' \
258
+ --dest-uri 'duckdb:///facebook.duckdb' \
259
+ --dest-table 'dest.account_level_insights'
202
260
  ```
@@ -0,0 +1,60 @@
1
+ # Linear
2
+
3
+ [Linear](https://linear.app/) is a purpose-built tool for planning and building products that provides issue tracking and project management for teams.
4
+
5
+ ingestr supports Linear as a source.
6
+
7
+ ## URI format
8
+
9
+ The URI format for Linear is:
10
+
11
+ ```plaintext
12
+ linear://?api_key=<api_key>
13
+ ```
14
+
15
+ URI parameters:
16
+
17
+ - `api_key`: The API key used for authentication with the Linear API.
18
+
19
+ ## Example usage
20
+
21
+ Assuming your API key is `lin_api_123`, you can ingest teams into DuckDB using:
22
+
23
+ ```bash
24
+ ingestr ingest
25
+ --source-uri 'linear://?api_key=lin_api_123' \
26
+ --source-table 'teams' \
27
+ --dest-uri duckdb:///linear.duckdb \
28
+ --dest-table 'dest.teams'
29
+ ```
30
+ <img alt="linear" src="../media/linear.png"/>
31
+
32
+ ## Tables
33
+ Linear source allows ingesting the following tables:
34
+
35
+ - `issues`: Fetches all issues from your Linear workspace.
36
+ - `projects`: Fetches project-level data.
37
+ - `teams`: Fetches information about the teams configured in Linear.
38
+ - `users`: Fetches users from your workspace.
39
+ - `workflow_states`: Fetches workflow states used in your Linear workspace.
40
+ - `cycles`: Fetches cycle information and planning data.
41
+ - `attachments`: Fetches file attachments associated with issues.
42
+ - `comments`: Fetches comments on issues and other entities.
43
+ - `documents`: Fetches documents created in Linear.
44
+ - `external_users`: Fetches information about external users.
45
+ - `initiative`: Fetches initiative data for high-level planning.
46
+ - `integrations`: Fetches integration configurations.
47
+ - `labels`: Fetches labels used for categorizing issues.
48
+ - `organization`: Fetches organization-level information.
49
+ - `project_updates`: Fetches updates posted to projects.
50
+ - `roadmaps`: Fetches roadmap data for strategic planning.
51
+ - `roadmap_to_projects`: Fetches relationships between roadmaps and projects.
52
+ - `team_memberships`: Fetches team membership information.
53
+ - `initiative_to_project`: Fetches relationships between initiatives and projects.
54
+ - `project_milestone`: Fetches project milestone data.
55
+ - `project_status`: Fetches project status information.
56
+ - `team`: Fetches team-level data.
57
+ - `project`: Fetches individual project information.
58
+
59
+
60
+ Use these as the `--source-table` parameter in the `ingestr ingest` command.
@@ -0,0 +1 @@
1
+ version = "v0.13.82"
@@ -22,12 +22,8 @@ from .settings import (
22
22
  DEFAULT_ADCREATIVE_FIELDS,
23
23
  DEFAULT_ADSET_FIELDS,
24
24
  DEFAULT_CAMPAIGN_FIELDS,
25
- DEFAULT_INSIGHT_FIELDS,
26
25
  DEFAULT_LEAD_FIELDS,
27
26
  INSIGHT_FIELDS_TYPES,
28
- INSIGHTS_BREAKDOWNS_OPTIONS,
29
- INVALID_INSIGHTS_FIELDS,
30
- TInsightsBreakdownOptions,
31
27
  TInsightsLevels,
32
28
  )
33
29
 
@@ -105,10 +101,9 @@ def facebook_insights_source(
105
101
  account_id: str = dlt.config.value,
106
102
  access_token: str = dlt.secrets.value,
107
103
  initial_load_past_days: int = 1,
108
- fields: Sequence[str] = DEFAULT_INSIGHT_FIELDS,
109
- attribution_window_days_lag: int = 7,
104
+ dimensions: Sequence[str] = None,
105
+ fields: Sequence[str] = None,
110
106
  time_increment_days: int = 1,
111
- breakdowns: TInsightsBreakdownOptions = "ads_insights",
112
107
  action_breakdowns: Sequence[str] = ALL_ACTION_BREAKDOWNS,
113
108
  level: TInsightsLevels = "ad",
114
109
  action_attribution_windows: Sequence[str] = ALL_ACTION_ATTRIBUTION_WINDOWS,
@@ -155,6 +150,11 @@ def facebook_insights_source(
155
150
  if start_date is None:
156
151
  start_date = pendulum.today().subtract(days=initial_load_past_days)
157
152
 
153
+ if dimensions is None:
154
+ dimensions = []
155
+ if fields is None:
156
+ fields = []
157
+
158
158
  columns = {}
159
159
  for field in fields:
160
160
  if field in INSIGHT_FIELDS_TYPES:
@@ -187,15 +187,9 @@ def facebook_insights_source(
187
187
  query = {
188
188
  "level": level,
189
189
  "action_breakdowns": list(action_breakdowns),
190
- "breakdowns": list(
191
- INSIGHTS_BREAKDOWNS_OPTIONS[breakdowns]["breakdowns"]
192
- ),
190
+ "breakdowns": dimensions,
193
191
  "limit": batch_size,
194
- "fields": list(
195
- set(fields)
196
- .union(INSIGHTS_BREAKDOWNS_OPTIONS[breakdowns]["fields"])
197
- .difference(INVALID_INSIGHTS_FIELDS)
198
- ),
192
+ "fields": fields,
199
193
  "time_increment": time_increment_days,
200
194
  "action_attribution_windows": list(action_attribution_windows),
201
195
  "time_ranges": [
@@ -229,3 +229,49 @@ def notify_on_token_expiration(access_token_expires_at: int = None) -> None:
229
229
  logger.error(
230
230
  f"Access Token expires in {humanize.precisedelta(pendulum.now() - expires_at)}. Replace the token now!"
231
231
  )
232
+
233
+
234
+ def parse_insights_table_to_source_kwargs(table: str) -> DictStrAny:
235
+ import typing
236
+
237
+ from ingestr.src.facebook_ads.settings import (
238
+ INSIGHTS_BREAKDOWNS_OPTIONS,
239
+ TInsightsBreakdownOptions,
240
+ TInsightsLevels,
241
+ )
242
+
243
+ parts = table.split(":")
244
+
245
+ source_kwargs = {}
246
+
247
+ breakdown_type = parts[1]
248
+
249
+ valid_breakdowns = list(typing.get_args(TInsightsBreakdownOptions))
250
+ if breakdown_type in valid_breakdowns:
251
+ dimensions = INSIGHTS_BREAKDOWNS_OPTIONS[breakdown_type]["breakdowns"]
252
+ fields = INSIGHTS_BREAKDOWNS_OPTIONS[breakdown_type]["fields"]
253
+ source_kwargs["dimensions"] = dimensions
254
+ source_kwargs["fields"] = fields
255
+ else:
256
+ dimensions = breakdown_type.split(",")
257
+ valid_levels = list(typing.get_args(TInsightsLevels))
258
+ level = None
259
+ for valid_level in reversed(valid_levels):
260
+ if valid_level in dimensions:
261
+ level = valid_level
262
+ dimensions.remove(valid_level)
263
+ break
264
+
265
+ source_kwargs["level"] = level
266
+ source_kwargs["dimensions"] = dimensions
267
+
268
+ # If custom metrics are provided, parse them
269
+ if len(parts) == 3:
270
+ fields = [f.strip() for f in parts[2].split(",") if f.strip()]
271
+ if not fields:
272
+ raise ValueError(
273
+ "Custom metrics must be provided after the second colon in format: facebook_insights:breakdown_type:metric1,metric2..."
274
+ )
275
+ source_kwargs["fields"] = fields
276
+
277
+ return source_kwargs