ingestr 0.13.73__tar.gz → 0.13.74__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.
Files changed (321) hide show
  1. {ingestr-0.13.73 → ingestr-0.13.74}/PKG-INFO +3 -1
  2. {ingestr-0.13.73 → ingestr-0.13.74}/docs/.vitepress/config.mjs +1 -0
  3. ingestr-0.13.74/docs/supported-sources/influxdb.md +38 -0
  4. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/main.py +7 -1
  5. ingestr-0.13.74/ingestr/src/buildinfo.py +1 -0
  6. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/facebook_ads/__init__.py +10 -5
  7. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/facebook_ads/helpers.py +1 -3
  8. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/factory.py +2 -0
  9. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/github/__init__.py +36 -3
  10. ingestr-0.13.74/ingestr/src/influxdb/__init__.py +45 -0
  11. ingestr-0.13.74/ingestr/src/influxdb/client.py +34 -0
  12. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/solidgate/helpers.py +2 -3
  13. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/sources.py +67 -1
  14. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/tiktok_ads/__init__.py +6 -2
  15. {ingestr-0.13.73 → ingestr-0.13.74}/pyproject.toml +2 -0
  16. {ingestr-0.13.73 → ingestr-0.13.74}/requirements.in +1 -0
  17. {ingestr-0.13.73 → ingestr-0.13.74}/requirements.txt +9 -0
  18. {ingestr-0.13.73 → ingestr-0.13.74}/requirements_arm64.txt +9 -0
  19. ingestr-0.13.73/ingestr/src/buildinfo.py +0 -1
  20. {ingestr-0.13.73 → ingestr-0.13.74}/.dlt/config.toml +0 -0
  21. {ingestr-0.13.73 → ingestr-0.13.74}/.dockerignore +0 -0
  22. {ingestr-0.13.73 → ingestr-0.13.74}/.githooks/pre-commit-hook.sh +0 -0
  23. {ingestr-0.13.73 → ingestr-0.13.74}/.github/workflows/deploy-docs.yml +0 -0
  24. {ingestr-0.13.73 → ingestr-0.13.74}/.github/workflows/release.yml +0 -0
  25. {ingestr-0.13.73 → ingestr-0.13.74}/.github/workflows/secrets-scan.yml +0 -0
  26. {ingestr-0.13.73 → ingestr-0.13.74}/.github/workflows/tests.yml +0 -0
  27. {ingestr-0.13.73 → ingestr-0.13.74}/.gitignore +0 -0
  28. {ingestr-0.13.73 → ingestr-0.13.74}/.gitleaksignore +0 -0
  29. {ingestr-0.13.73 → ingestr-0.13.74}/.python-version +0 -0
  30. {ingestr-0.13.73 → ingestr-0.13.74}/.vale.ini +0 -0
  31. {ingestr-0.13.73 → ingestr-0.13.74}/Dockerfile +0 -0
  32. {ingestr-0.13.73 → ingestr-0.13.74}/LICENSE.md +0 -0
  33. {ingestr-0.13.73 → ingestr-0.13.74}/Makefile +0 -0
  34. {ingestr-0.13.73 → ingestr-0.13.74}/README.md +0 -0
  35. {ingestr-0.13.73 → ingestr-0.13.74}/docs/.vitepress/theme/custom.css +0 -0
  36. {ingestr-0.13.73 → ingestr-0.13.74}/docs/.vitepress/theme/index.js +0 -0
  37. {ingestr-0.13.73 → ingestr-0.13.74}/docs/commands/example-uris.md +0 -0
  38. {ingestr-0.13.73 → ingestr-0.13.74}/docs/commands/ingest.md +0 -0
  39. {ingestr-0.13.73 → ingestr-0.13.74}/docs/getting-started/core-concepts.md +0 -0
  40. {ingestr-0.13.73 → ingestr-0.13.74}/docs/getting-started/incremental-loading.md +0 -0
  41. {ingestr-0.13.73 → ingestr-0.13.74}/docs/getting-started/quickstart.md +0 -0
  42. {ingestr-0.13.73 → ingestr-0.13.74}/docs/getting-started/telemetry.md +0 -0
  43. {ingestr-0.13.73 → ingestr-0.13.74}/docs/index.md +0 -0
  44. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/applovin_max.png +0 -0
  45. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/athena.png +0 -0
  46. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/clickhouse_img.png +0 -0
  47. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/clickup_ingestion.png +0 -0
  48. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/cratedb-destination.png +0 -0
  49. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/cratedb-source.png +0 -0
  50. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/freshdesk_ingestion.png +0 -0
  51. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/gcp_spanner_ingestion.png +0 -0
  52. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/github.png +0 -0
  53. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/google_analytics_realtime_report.png +0 -0
  54. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/googleanalytics.png +0 -0
  55. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/ingestion_elasticsearch_img.png +0 -0
  56. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/kinesis.bigquery.png +0 -0
  57. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/linear.png +0 -0
  58. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/linkedin_ads.png +0 -0
  59. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/mixpanel_ingestion.png +0 -0
  60. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/personio.png +0 -0
  61. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/personio_duckdb.png +0 -0
  62. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/phantombuster.png +0 -0
  63. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/pipedrive.png +0 -0
  64. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/quickbook_ingestion.png +0 -0
  65. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/sftp.png +0 -0
  66. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/stripe_postgres.png +0 -0
  67. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/tiktok.png +0 -0
  68. {ingestr-0.13.73 → ingestr-0.13.74}/docs/media/zoom_ingestion.png +0 -0
  69. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/adjust.md +0 -0
  70. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/airtable.md +0 -0
  71. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/applovin.md +0 -0
  72. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/applovin_max.md +0 -0
  73. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/appsflyer.md +0 -0
  74. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/appstore.md +0 -0
  75. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/asana.md +0 -0
  76. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/athena.md +0 -0
  77. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/attio.md +0 -0
  78. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/bigquery.md +0 -0
  79. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/chess.md +0 -0
  80. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/clickhouse.md +0 -0
  81. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/clickup.md +0 -0
  82. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/cratedb.md +0 -0
  83. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/csv.md +0 -0
  84. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/custom_queries.md +0 -0
  85. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/databricks.md +0 -0
  86. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/db2.md +0 -0
  87. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/duckdb.md +0 -0
  88. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/dynamodb.md +0 -0
  89. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/elasticsearch.md +0 -0
  90. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/facebook-ads.md +0 -0
  91. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/frankfurter.md +0 -0
  92. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/freshdesk.md +0 -0
  93. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/gcs.md +0 -0
  94. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/github.md +0 -0
  95. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/google-ads.md +0 -0
  96. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/google_analytics.md +0 -0
  97. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/gorgias.md +0 -0
  98. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/gsheets.md +0 -0
  99. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/hubspot.md +0 -0
  100. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/isoc-pulse.md +0 -0
  101. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/kafka.md +0 -0
  102. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/kinesis.md +0 -0
  103. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/klaviyo.md +0 -0
  104. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/linear.md +0 -0
  105. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/linkedin_ads.md +0 -0
  106. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/mixpanel.md +0 -0
  107. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/mongodb.md +0 -0
  108. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/mssql.md +0 -0
  109. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/mysql.md +0 -0
  110. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/notion.md +0 -0
  111. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/oracle.md +0 -0
  112. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/personio.md +0 -0
  113. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/phantombuster.md +0 -0
  114. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/pinterest.md +0 -0
  115. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/pipedrive.md +0 -0
  116. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/postgres.md +0 -0
  117. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/quickbooks.md +0 -0
  118. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/redshift.md +0 -0
  119. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/s3.md +0 -0
  120. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/salesforce.md +0 -0
  121. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/sap-hana.md +0 -0
  122. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/sftp.md +0 -0
  123. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/shopify.md +0 -0
  124. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/slack.md +0 -0
  125. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/smartsheets.md +0 -0
  126. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/snowflake.md +0 -0
  127. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/solidgate.md +0 -0
  128. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/spanner.md +0 -0
  129. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/sqlite.md +0 -0
  130. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/stripe.md +0 -0
  131. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/tiktok-ads.md +0 -0
  132. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/trustpilot.md +0 -0
  133. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/zendesk.md +0 -0
  134. {ingestr-0.13.73 → ingestr-0.13.74}/docs/supported-sources/zoom.md +0 -0
  135. {ingestr-0.13.73 → ingestr-0.13.74}/docs/tutorials/load-kinesis-bigquery.md +0 -0
  136. {ingestr-0.13.73 → ingestr-0.13.74}/docs/tutorials/load-personio-duckdb.md +0 -0
  137. {ingestr-0.13.73 → ingestr-0.13.74}/docs/tutorials/load-stripe-postgres.md +0 -0
  138. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/conftest.py +0 -0
  139. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/.gitignore +0 -0
  140. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/adjust/__init__.py +0 -0
  141. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/adjust/adjust_helpers.py +0 -0
  142. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/airtable/__init__.py +0 -0
  143. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/applovin/__init__.py +0 -0
  144. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/applovin_max/__init__.py +0 -0
  145. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/appsflyer/__init__.py +0 -0
  146. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/appsflyer/client.py +0 -0
  147. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/appstore/__init__.py +0 -0
  148. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/appstore/client.py +0 -0
  149. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/appstore/errors.py +0 -0
  150. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/appstore/models.py +0 -0
  151. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/appstore/resources.py +0 -0
  152. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/arrow/__init__.py +0 -0
  153. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/asana_source/__init__.py +0 -0
  154. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/asana_source/helpers.py +0 -0
  155. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/asana_source/settings.py +0 -0
  156. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/attio/__init__.py +0 -0
  157. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/attio/helpers.py +0 -0
  158. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/blob.py +0 -0
  159. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/chess/__init__.py +0 -0
  160. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/chess/helpers.py +0 -0
  161. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/chess/settings.py +0 -0
  162. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/clickup/__init__.py +0 -0
  163. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/clickup/helpers.py +0 -0
  164. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/collector/spinner.py +0 -0
  165. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/destinations.py +0 -0
  166. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/dynamodb/__init__.py +0 -0
  167. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/elasticsearch/__init__.py +0 -0
  168. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/errors.py +0 -0
  169. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/facebook_ads/exceptions.py +0 -0
  170. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/facebook_ads/settings.py +0 -0
  171. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/facebook_ads/utils.py +0 -0
  172. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/filesystem/__init__.py +0 -0
  173. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/filesystem/helpers.py +0 -0
  174. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/filesystem/readers.py +0 -0
  175. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/filters.py +0 -0
  176. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/frankfurter/__init__.py +0 -0
  177. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/frankfurter/helpers.py +0 -0
  178. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/freshdesk/__init__.py +0 -0
  179. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/freshdesk/freshdesk_client.py +0 -0
  180. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/freshdesk/settings.py +0 -0
  181. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/github/helpers.py +0 -0
  182. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/github/queries.py +0 -0
  183. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/github/settings.py +0 -0
  184. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_ads/__init__.py +0 -0
  185. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_ads/field.py +0 -0
  186. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_ads/metrics.py +0 -0
  187. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_ads/predicates.py +0 -0
  188. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_ads/reports.py +0 -0
  189. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_analytics/__init__.py +0 -0
  190. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_analytics/helpers.py +0 -0
  191. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_sheets/README.md +0 -0
  192. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_sheets/__init__.py +0 -0
  193. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
  194. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
  195. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
  196. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/gorgias/__init__.py +0 -0
  197. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/gorgias/helpers.py +0 -0
  198. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/http_client.py +0 -0
  199. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/hubspot/__init__.py +0 -0
  200. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/hubspot/helpers.py +0 -0
  201. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/hubspot/settings.py +0 -0
  202. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/isoc_pulse/__init__.py +0 -0
  203. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/kafka/__init__.py +0 -0
  204. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/kafka/helpers.py +0 -0
  205. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/kinesis/__init__.py +0 -0
  206. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/kinesis/helpers.py +0 -0
  207. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/klaviyo/__init__.py +0 -0
  208. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/klaviyo/client.py +0 -0
  209. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/klaviyo/helpers.py +0 -0
  210. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/linear/__init__.py +0 -0
  211. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/linear/helpers.py +0 -0
  212. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/linkedin_ads/__init__.py +0 -0
  213. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
  214. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/linkedin_ads/helpers.py +0 -0
  215. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/loader.py +0 -0
  216. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/mixpanel/__init__.py +0 -0
  217. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/mixpanel/client.py +0 -0
  218. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/mongodb/__init__.py +0 -0
  219. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/mongodb/helpers.py +0 -0
  220. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/notion/__init__.py +0 -0
  221. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/notion/helpers/__init__.py +0 -0
  222. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/notion/helpers/client.py +0 -0
  223. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/notion/helpers/database.py +0 -0
  224. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/notion/settings.py +0 -0
  225. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/partition.py +0 -0
  226. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/personio/__init__.py +0 -0
  227. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/personio/helpers.py +0 -0
  228. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/phantombuster/__init__.py +0 -0
  229. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/phantombuster/client.py +0 -0
  230. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/pinterest/__init__.py +0 -0
  231. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/pipedrive/__init__.py +0 -0
  232. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/pipedrive/helpers/__init__.py +0 -0
  233. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/pipedrive/helpers/custom_fields_munger.py +0 -0
  234. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/pipedrive/helpers/pages.py +0 -0
  235. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/pipedrive/settings.py +0 -0
  236. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/pipedrive/typing.py +0 -0
  237. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/quickbooks/__init__.py +0 -0
  238. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/resource.py +0 -0
  239. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/salesforce/__init__.py +0 -0
  240. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/salesforce/helpers.py +0 -0
  241. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/shopify/__init__.py +0 -0
  242. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/shopify/exceptions.py +0 -0
  243. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/shopify/helpers.py +0 -0
  244. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/shopify/settings.py +0 -0
  245. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/slack/__init__.py +0 -0
  246. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/slack/helpers.py +0 -0
  247. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/slack/settings.py +0 -0
  248. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/smartsheets/__init__.py +0 -0
  249. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/solidgate/__init__.py +0 -0
  250. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/sql_database/__init__.py +0 -0
  251. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/sql_database/callbacks.py +0 -0
  252. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/stripe_analytics/__init__.py +0 -0
  253. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/stripe_analytics/helpers.py +0 -0
  254. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/stripe_analytics/settings.py +0 -0
  255. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/table_definition.py +0 -0
  256. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/telemetry/event.py +0 -0
  257. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/testdata/fakebqcredentials.json +0 -0
  258. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
  259. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/time.py +0 -0
  260. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/trustpilot/__init__.py +0 -0
  261. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/trustpilot/client.py +0 -0
  262. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/version.py +0 -0
  263. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/zendesk/__init__.py +0 -0
  264. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/zendesk/helpers/__init__.py +0 -0
  265. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
  266. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/zendesk/helpers/credentials.py +0 -0
  267. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
  268. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/zendesk/settings.py +0 -0
  269. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/zoom/__init__.py +0 -0
  270. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/src/zoom/helpers.py +0 -0
  271. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/testdata/.gitignore +0 -0
  272. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/testdata/create_replace.csv +0 -0
  273. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/testdata/delete_insert_expected.csv +0 -0
  274. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/testdata/delete_insert_part1.csv +0 -0
  275. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/testdata/delete_insert_part2.csv +0 -0
  276. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/testdata/merge_expected.csv +0 -0
  277. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/testdata/merge_part1.csv +0 -0
  278. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/testdata/merge_part2.csv +0 -0
  279. {ingestr-0.13.73 → ingestr-0.13.74}/ingestr/tests/unit/test_smartsheets.py +0 -0
  280. {ingestr-0.13.73 → ingestr-0.13.74}/package-lock.json +0 -0
  281. {ingestr-0.13.73 → ingestr-0.13.74}/package.json +0 -0
  282. {ingestr-0.13.73 → ingestr-0.13.74}/requirements-dev.txt +0 -0
  283. {ingestr-0.13.73 → ingestr-0.13.74}/resources/demo.gif +0 -0
  284. {ingestr-0.13.73 → ingestr-0.13.74}/resources/demo.tape +0 -0
  285. {ingestr-0.13.73 → ingestr-0.13.74}/resources/ingestr.svg +0 -0
  286. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/AMPM.yml +0 -0
  287. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Acronyms.yml +0 -0
  288. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Colons.yml +0 -0
  289. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Contractions.yml +0 -0
  290. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/DateFormat.yml +0 -0
  291. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Ellipses.yml +0 -0
  292. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/EmDash.yml +0 -0
  293. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Exclamation.yml +0 -0
  294. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/FirstPerson.yml +0 -0
  295. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Gender.yml +0 -0
  296. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/GenderBias.yml +0 -0
  297. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/HeadingPunctuation.yml +0 -0
  298. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Headings.yml +0 -0
  299. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Latin.yml +0 -0
  300. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/LyHyphens.yml +0 -0
  301. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/OptionalPlurals.yml +0 -0
  302. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Ordinal.yml +0 -0
  303. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/OxfordComma.yml +0 -0
  304. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Parens.yml +0 -0
  305. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Passive.yml +0 -0
  306. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Periods.yml +0 -0
  307. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Quotes.yml +0 -0
  308. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Ranges.yml +0 -0
  309. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Semicolons.yml +0 -0
  310. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Slang.yml +0 -0
  311. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Spacing.yml +0 -0
  312. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Spelling.yml +0 -0
  313. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Units.yml +0 -0
  314. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/We.yml +0 -0
  315. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/Will.yml +0 -0
  316. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/WordList.yml +0 -0
  317. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/meta.json +0 -0
  318. {ingestr-0.13.73 → ingestr-0.13.74}/styles/Google/vocab.txt +0 -0
  319. {ingestr-0.13.73 → ingestr-0.13.74}/styles/bruin/Ingestr.yml +0 -0
  320. {ingestr-0.13.73 → ingestr-0.13.74}/styles/config/vocabularies/bruin/accept.txt +0 -0
  321. {ingestr-0.13.73 → ingestr-0.13.74}/test.env.template +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ingestr
3
- Version: 0.13.73
3
+ Version: 0.13.74
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
@@ -96,6 +96,7 @@ Requires-Dist: ibm-db-sa==0.4.1
96
96
  Requires-Dist: ibm-db==3.2.6
97
97
  Requires-Dist: idna==3.10
98
98
  Requires-Dist: inflection==0.5.1
99
+ Requires-Dist: influxdb-client==1.41.0
99
100
  Requires-Dist: intuit-oauth==1.2.4
100
101
  Requires-Dist: isodate==0.7.2
101
102
  Requires-Dist: jmespath==1.0.1
@@ -156,6 +157,7 @@ Requires-Dist: python-quickbooks==0.9.2
156
157
  Requires-Dist: pytz==2025.1
157
158
  Requires-Dist: pyyaml==6.0.2
158
159
  Requires-Dist: rauth==0.7.3
160
+ Requires-Dist: reactivex==4.0.4
159
161
  Requires-Dist: requests-file==2.1.0
160
162
  Requires-Dist: requests-oauthlib==1.3.1
161
163
  Requires-Dist: requests-toolbelt==1.0.0
@@ -82,6 +82,7 @@ export default defineConfig({
82
82
  },
83
83
  { text: "GCP Spanner", link: "/supported-sources/spanner.md" },
84
84
  { text: "IBM Db2", link: "/supported-sources/db2.md" },
85
+ { text: "InfluxDB", link: "/supported-sources/influxdb.md" },
85
86
  { text: "Kafka", link: "/supported-sources/kafka.md" },
86
87
  { text: "Local CSV Files", link: "/supported-sources/csv.md" },
87
88
  {
@@ -0,0 +1,38 @@
1
+ # InfluxDB
2
+ [InfluxDB](https://www.influxdata.com/) is a time series database optimized for storing high throughput metrics.
3
+
4
+ ingestr supports InfluxDB as a source.
5
+
6
+ ## URI format
7
+
8
+ ```plaintext
9
+ influxdb://<host>:<port>?token=<token>&org=<org>&bucket=<bucket>&secure=<secure>
10
+ ```
11
+
12
+ URI parameters:
13
+ - `host`: Hostname and optional port of your InfluxDB instance.
14
+ - `token`: Authentication token.
15
+ - `org`: Name of the organization.
16
+ - `bucket`: Bucket that stores the measurements.
17
+ - `secure`: Optional. Use HTTPS when `true` (default) or HTTP when `false`.
18
+
19
+ The `<measurement>` name should be provided as the value for `--source-table`.
20
+
21
+ ## Example
22
+
23
+ Copy cpu metrics from InfluxDB into DuckDB:
24
+
25
+ ```sh
26
+ ingestr ingest \
27
+ --source-uri 'influxdb://eu-central-1-0.aws.cloud3.influxdata.com?token=my-token&org=my-org&bucket=metrics&secure=false' \
28
+ --source-table 'cpu' \
29
+ --dest-uri duckdb:///metrics.duckdb \
30
+ --dest-table 'dest.cpu'
31
+ ```
32
+
33
+ ## Tables
34
+
35
+ The InfluxDB source accepts any measurement name. Specify the measurement as the `--source-table` option when running `ingestr`.
36
+
37
+ > [!NOTE]
38
+ > Primary Key Required for Merge: When using `--incremental-strategy merge`, you must also specify `--primary-key` Otherwise, the strategy defaults to append.
@@ -506,6 +506,7 @@ def ingest(
506
506
 
507
507
  if factory.source_scheme == "sqlite":
508
508
  source_table = "main." + source_table.split(".")[-1]
509
+
509
510
 
510
511
  if (
511
512
  incremental_key
@@ -596,8 +597,13 @@ def ingest(
596
597
  if incremental_strategy != IncrementalStrategy.none:
597
598
  write_disposition = incremental_strategy.value
598
599
 
599
- start_time = datetime.now()
600
+ if factory.source_scheme == "influxdb":
601
+ if primary_key:
602
+ write_disposition = "merge"
603
+
600
604
 
605
+ start_time = datetime.now()
606
+
601
607
  run_info: LoadInfo = pipeline.run(
602
608
  dlt_source,
603
609
  **destination.dlt_run_params(
@@ -0,0 +1 @@
1
+ version = "v0.13.74"
@@ -1,14 +1,13 @@
1
1
  """Loads campaigns, ads sets, ads, leads and insight data from Facebook Marketing API"""
2
2
 
3
- from datetime import datetime
4
3
  from typing import Iterator, Sequence
5
4
 
6
5
  import dlt
7
6
  from dlt.common import pendulum
7
+ from dlt.common.time import ensure_pendulum_datetime
8
8
  from dlt.common.typing import TDataItems
9
9
  from dlt.sources import DltResource
10
10
  from facebook_business.adobjects.ad import Ad
11
- from dlt.common.time import ensure_pendulum_datetime
12
11
 
13
12
  from .helpers import (
14
13
  execute_job,
@@ -167,14 +166,20 @@ def facebook_insights_source(
167
166
  def facebook_insights(
168
167
  date_start: dlt.sources.incremental[str] = dlt.sources.incremental(
169
168
  "date_start",
170
- initial_value=ensure_pendulum_datetime(start_date).start_of('day').date(),
171
- end_value=ensure_pendulum_datetime(end_date).end_of('day').date() if end_date else None,
169
+ initial_value=ensure_pendulum_datetime(start_date).start_of("day").date(),
170
+ end_value=ensure_pendulum_datetime(end_date).end_of("day").date()
171
+ if end_date
172
+ else None,
172
173
  range_end="closed",
173
174
  range_start="closed",
174
175
  ),
175
176
  ) -> Iterator[TDataItems]:
176
177
  start_date = date_start.last_value
177
- end_date = pendulum.instance(date_start.end_value) if date_start.end_value else pendulum.now()
178
+ end_date = (
179
+ pendulum.instance(date_start.end_value)
180
+ if date_start.end_value
181
+ else pendulum.now()
182
+ )
178
183
 
179
184
  while start_date <= end_date:
180
185
  query = {
@@ -6,12 +6,10 @@ import time
6
6
  from datetime import datetime
7
7
  from typing import Any, Iterator, Sequence
8
8
 
9
- import dlt
10
9
  import humanize
11
10
  import pendulum
12
11
  from dlt.common import logger
13
12
  from dlt.common.configuration.inject import with_config
14
- from dlt.common.time import ensure_pendulum_datetime
15
13
  from dlt.common.typing import DictStrAny, TDataItem, TDataItems
16
14
  from dlt.sources.helpers import requests
17
15
  from dlt.sources.helpers.requests import Client
@@ -34,7 +32,7 @@ def process_report_item(item: AbstractObject) -> DictStrAny:
34
32
  item["date_start"] = datetime.strptime(item["date_start"], "%Y-%m-%d").date()
35
33
  if "date_stop" in item:
36
34
  item["date_stop"] = datetime.strptime(item["date_stop"], "%Y-%m-%d").date()
37
-
35
+
38
36
  d: DictStrAny = item.export_all_data()
39
37
  for pki in INSIGHTS_PRIMARY_KEY:
40
38
  if pki not in d:
@@ -45,6 +45,7 @@ from ingestr.src.sources import (
45
45
  GoogleSheetsSource,
46
46
  GorgiasSource,
47
47
  HubspotSource,
48
+ InfluxDBSource,
48
49
  IsocPulseSource,
49
50
  KafkaSource,
50
51
  KinesisSource,
@@ -187,6 +188,7 @@ class SourceDestinationFactory:
187
188
  "pinterest": PinterestSource,
188
189
  "zoom": ZoomSource,
189
190
  "clickup": ClickupSource,
191
+ "influxdb": InfluxDBSource,
190
192
  }
191
193
  destinations: Dict[str, Type[DestinationProtocol]] = {
192
194
  "bigquery": BigQueryDestination,
@@ -4,6 +4,7 @@ import urllib.parse
4
4
  from typing import Iterator, Optional, Sequence
5
5
 
6
6
  import dlt
7
+ import pendulum
7
8
  from dlt.common.typing import TDataItems
8
9
  from dlt.sources import DltResource
9
10
 
@@ -67,7 +68,11 @@ def github_reactions(
67
68
 
68
69
  @dlt.source(max_table_nesting=0)
69
70
  def github_repo_events(
70
- owner: str, name: str, access_token: Optional[str] = None
71
+ owner: str,
72
+ name: str,
73
+ access_token: str,
74
+ start_date: pendulum.DateTime,
75
+ end_date: pendulum.DateTime,
71
76
  ) -> DltResource:
72
77
  """Gets events for repository `name` with owner `owner` incrementally.
73
78
 
@@ -90,7 +95,8 @@ def github_repo_events(
90
95
  def repo_events(
91
96
  last_created_at: dlt.sources.incremental[str] = dlt.sources.incremental(
92
97
  "created_at",
93
- initial_value="1970-01-01T00:00:00Z",
98
+ initial_value=start_date.isoformat(),
99
+ end_value=end_date.isoformat(),
94
100
  last_value_func=max,
95
101
  range_end="closed",
96
102
  range_start="closed",
@@ -100,8 +106,35 @@ def github_repo_events(
100
106
  f"/repos/{urllib.parse.quote(owner)}/{urllib.parse.quote(name)}/events"
101
107
  )
102
108
 
109
+ # Get the date range from the incremental state
110
+ start_filter = pendulum.parse(
111
+ last_created_at.last_value or last_created_at.initial_value
112
+ )
113
+ end_filter = (
114
+ pendulum.parse(last_created_at.end_value)
115
+ if last_created_at.end_value
116
+ else None
117
+ )
118
+
103
119
  for page in get_rest_pages(access_token, repos_path + "?per_page=100"):
104
- yield page
120
+ # Filter events by date range
121
+ filtered_events = []
122
+ for event in page:
123
+ event_date = pendulum.parse(event["created_at"])
124
+
125
+ # Check if event is within the date range
126
+ if event_date >= start_filter:
127
+ if end_filter is None or event_date <= end_filter:
128
+ filtered_events.append(event)
129
+ elif event_date > end_filter:
130
+ # Skip events that are newer than our end date
131
+ continue
132
+ else:
133
+ # Events are ordered by date desc, so if we hit an older event, we can stop
134
+ break
135
+
136
+ if filtered_events:
137
+ yield filtered_events
105
138
 
106
139
  # stop requesting pages if the last element was already older than initial value
107
140
  # note: incremental will skip those items anyway, we just do not want to use the api limits
@@ -0,0 +1,45 @@
1
+ from typing import Iterable
2
+
3
+ import dlt
4
+ import pendulum
5
+ from dlt.common.typing import TDataItem
6
+ from dlt.sources import DltResource
7
+
8
+ from .client import InfluxClient
9
+
10
+ @dlt.source(max_table_nesting=0)
11
+ def influxdb_source(
12
+ measurement: str,
13
+ host: str,
14
+ org: str,
15
+ bucket: str,
16
+ token: str = dlt.secrets.value,
17
+ secure: bool = True,
18
+ start_date: pendulum.DateTime = pendulum.datetime(2024, 1, 1),
19
+ end_date: pendulum.DateTime | None = None,
20
+ ) -> Iterable[DltResource]:
21
+ client = InfluxClient(
22
+ url=host, token=token, org=org, bucket=bucket, verify_ssl=secure
23
+ )
24
+
25
+ @dlt.resource(name=measurement)
26
+ def fetch_table(
27
+ timestamp=dlt.sources.incremental(
28
+ "time",
29
+ initial_value=start_date,
30
+ end_value=end_date,
31
+ range_start="closed",
32
+ range_end="closed",
33
+ ),
34
+ ) -> Iterable[TDataItem]:
35
+ if timestamp.last_value is None:
36
+ start = start_date.isoformat()
37
+ else:
38
+ start = timestamp.last_value.isoformat()
39
+ if timestamp.end_value is None:
40
+ end = pendulum.now().isoformat()
41
+ else:
42
+ end = timestamp.end_value.isoformat()
43
+ yield from client.fetch_measurement(measurement, start, end)
44
+
45
+ return fetch_table
@@ -0,0 +1,34 @@
1
+ from typing import Any, Dict, Iterable
2
+
3
+ from influxdb_client import InfluxDBClient # type: ignore
4
+
5
+
6
+ class InfluxClient:
7
+ def __init__(
8
+ self, url: str, token: str, org: str, bucket: str, verify_ssl: bool = True
9
+ ) -> None:
10
+ self.client = InfluxDBClient(
11
+ url=url, token=token, org=org, verify_ssl=verify_ssl
12
+ )
13
+ self.bucket = bucket
14
+
15
+ def fetch_measurement(
16
+ self, measurement: str, start: str, end: str | None = None
17
+ ) -> Iterable[Dict[str, Any]]:
18
+ query = f'from(bucket: "{self.bucket}") |> range(start: {start}'
19
+ if end:
20
+ query += f", stop: {end}"
21
+ query += f') |> filter(fn: (r) => r["_measurement"] == "{measurement}")'
22
+ query_api = self.client.query_api()
23
+
24
+ for record in query_api.query_stream(query):
25
+ cleaned_record = {}
26
+ exclude_keys = {"result", "table", "_start", "_stop"}
27
+ for key, value in record.values.items():
28
+ if key in exclude_keys:
29
+ continue
30
+ if key.startswith("_"):
31
+ cleaned_record[key[1:]] = value
32
+ else:
33
+ cleaned_record[key] = value
34
+ yield cleaned_record
@@ -6,7 +6,6 @@ import json
6
6
  import time
7
7
  from io import StringIO
8
8
 
9
- import pandas as pd # type: ignore
10
9
  import pendulum
11
10
 
12
11
  from ingestr.src.http_client import create_client
@@ -132,9 +131,9 @@ class SolidgateClient:
132
131
  else:
133
132
  row["created_at"] = None
134
133
 
135
- row2 = {k: v for k, v in row.items() if v != ''}
134
+ row2 = {k: v for k, v in row.items() if v != ""}
136
135
  rows.append(row2)
137
-
136
+
138
137
  return rows
139
138
  except Exception as e:
140
139
  raise Exception(f"Error reading CSV: {e}")
@@ -1814,7 +1814,23 @@ class GitHubSource:
1814
1814
  owner=owner, name=repo, access_token=access_token
1815
1815
  ).with_resources(table)
1816
1816
  elif table == "repo_events":
1817
- return github_repo_events(owner=owner, name=repo, access_token=access_token)
1817
+ start_date = kwargs.get("interval_start") or pendulum.now().subtract(
1818
+ days=30
1819
+ )
1820
+ end_date = kwargs.get("interval_end") or pendulum.now()
1821
+
1822
+ if isinstance(start_date, str):
1823
+ start_date = pendulum.parse(start_date)
1824
+ if isinstance(end_date, str):
1825
+ end_date = pendulum.parse(end_date)
1826
+
1827
+ return github_repo_events(
1828
+ owner=owner,
1829
+ name=repo,
1830
+ access_token=access_token,
1831
+ start_date=start_date,
1832
+ end_date=end_date,
1833
+ )
1818
1834
  elif table == "stargazers":
1819
1835
  return github_stargazers(owner=owner, name=repo, access_token=access_token)
1820
1836
  else:
@@ -3026,3 +3042,53 @@ class ZoomSource:
3026
3042
  start_date=start_date,
3027
3043
  end_date=end_date,
3028
3044
  ).with_resources(table)
3045
+
3046
+
3047
+ class InfluxDBSource:
3048
+ def handles_incrementality(self) -> bool:
3049
+ return True
3050
+
3051
+ def dlt_source(self, uri: str, table: str, **kwargs):
3052
+ parsed_uri = urlparse(uri)
3053
+ params = parse_qs(parsed_uri.query)
3054
+ host = parsed_uri.netloc
3055
+
3056
+ secure = params.get("secure", ["true"])[0].lower() != "false"
3057
+ scheme = "https" if secure else "http"
3058
+ host_url = f"{scheme}://{host}"
3059
+
3060
+ token = params.get("token")
3061
+ org = params.get("org")
3062
+ bucket = params.get("bucket")
3063
+
3064
+ if not host:
3065
+ raise MissingValueError("host", "InfluxDB")
3066
+ if not token:
3067
+ raise MissingValueError("token", "InfluxDB")
3068
+ if not org:
3069
+ raise MissingValueError("org", "InfluxDB")
3070
+ if not bucket:
3071
+ raise MissingValueError("bucket", "InfluxDB")
3072
+
3073
+ start_date = kwargs.get("interval_start")
3074
+ if start_date is not None:
3075
+ start_date = ensure_pendulum_datetime(start_date)
3076
+ else:
3077
+ start_date = pendulum.datetime(2024, 1, 1).in_tz("UTC")
3078
+
3079
+ end_date = kwargs.get("interval_end")
3080
+ if end_date is not None:
3081
+ end_date = ensure_pendulum_datetime(end_date)
3082
+
3083
+ from ingestr.src.influxdb import influxdb_source
3084
+
3085
+ return influxdb_source(
3086
+ measurement=table,
3087
+ host=host_url,
3088
+ org=org[0],
3089
+ bucket=bucket[0],
3090
+ token=token[0],
3091
+ secure=secure,
3092
+ start_date=start_date,
3093
+ end_date=end_date,
3094
+ ).with_resources(table)
@@ -125,8 +125,12 @@ def tiktok_source(
125
125
  end_date_tz_adjusted = end_date.in_tz(timezone)
126
126
 
127
127
  if datetime is not None:
128
- start_date_tz_adjusted = ensure_pendulum_datetime(datetime.last_value).in_tz(timezone)
129
- end_date_tz_adjusted = ensure_pendulum_datetime(datetime.end_value).in_tz(timezone)
128
+ start_date_tz_adjusted = ensure_pendulum_datetime(
129
+ datetime.last_value
130
+ ).in_tz(timezone)
131
+ end_date_tz_adjusted = ensure_pendulum_datetime(datetime.end_value).in_tz(
132
+ timezone
133
+ )
130
134
 
131
135
  list_of_interval = find_intervals(
132
136
  current_date=start_date_tz_adjusted,
@@ -92,6 +92,7 @@ exclude = [
92
92
  'src/linear/.*',
93
93
  'src/zoom/.*',
94
94
  'src/clickup/.*',
95
+ 'src/influxdb/.*'
95
96
  ]
96
97
 
97
98
  [[tool.mypy.overrides]]
@@ -122,6 +123,7 @@ module = [
122
123
  "ingestr.src.linear.*",
123
124
  "ingestr.src.zoom.*",
124
125
  "ingestr.src.clickup.*",
126
+ "ingestr.src.influxdb",
125
127
  ]
126
128
  follow_imports = "skip"
127
129
 
@@ -56,3 +56,4 @@ google-cloud-spanner==3.54.0
56
56
  smartsheet-python-sdk==3.0.5
57
57
  paramiko==3.5.1
58
58
  python-quickbooks==0.9.2
59
+ influxdb-client==1.41.0
@@ -49,6 +49,7 @@ certifi==2025.1.31
49
49
  # via
50
50
  # clickhouse-connect
51
51
  # elastic-transport
52
+ # influxdb-client
52
53
  # requests
53
54
  # smartsheet-python-sdk
54
55
  # snowflake-connector-python
@@ -254,6 +255,8 @@ idna==3.10
254
255
  # yarl
255
256
  inflection==0.5.1
256
257
  # via pyairtable
258
+ influxdb-client==1.41.0
259
+ # via -r requirements.in
257
260
  intuit-oauth==1.2.4
258
261
  # via python-quickbooks
259
262
  isodate==0.7.2
@@ -418,6 +421,7 @@ python-dateutil==2.9.0.post0
418
421
  # aiobotocore
419
422
  # botocore
420
423
  # google-cloud-bigquery
424
+ # influxdb-client
421
425
  # pandas
422
426
  # pendulum
423
427
  # pyathena
@@ -446,6 +450,8 @@ pyyaml==6.0.2
446
450
  # google-ads
447
451
  rauth==0.7.3
448
452
  # via python-quickbooks
453
+ reactivex==4.0.4
454
+ # via influxdb-client
449
455
  requests==2.32.3
450
456
  # via
451
457
  # asana
@@ -506,6 +512,7 @@ semver==3.0.4
506
512
  setuptools==75.8.2
507
513
  # via
508
514
  # dlt
515
+ # influxdb-client
509
516
  # python-quickbooks
510
517
  # types-setuptools
511
518
  shellingham==1.5.4
@@ -597,6 +604,7 @@ typing-extensions==4.12.2
597
604
  # pydantic
598
605
  # pydantic-core
599
606
  # pyopenssl
607
+ # reactivex
600
608
  # simple-salesforce
601
609
  # snowflake-connector-python
602
610
  # sqlalchemy2-stubs
@@ -623,6 +631,7 @@ urllib3==2.3.0
623
631
  # crate
624
632
  # databricks-sql-connector
625
633
  # elastic-transport
634
+ # influxdb-client
626
635
  # pyairtable
627
636
  # requests
628
637
  # types-requests
@@ -49,6 +49,7 @@ certifi==2025.1.31
49
49
  # via
50
50
  # clickhouse-connect
51
51
  # elastic-transport
52
+ # influxdb-client
52
53
  # requests
53
54
  # smartsheet-python-sdk
54
55
  # snowflake-connector-python
@@ -248,6 +249,8 @@ idna==3.10
248
249
  # yarl
249
250
  inflection==0.5.1
250
251
  # via pyairtable
252
+ influxdb-client==1.41.0
253
+ # via -r requirements.in
251
254
  intuit-oauth==1.2.4
252
255
  # via python-quickbooks
253
256
  isodate==0.7.2
@@ -412,6 +415,7 @@ python-dateutil==2.9.0.post0
412
415
  # aiobotocore
413
416
  # botocore
414
417
  # google-cloud-bigquery
418
+ # influxdb-client
415
419
  # pandas
416
420
  # pendulum
417
421
  # pyathena
@@ -440,6 +444,8 @@ pyyaml==6.0.2
440
444
  # google-ads
441
445
  rauth==0.7.3
442
446
  # via python-quickbooks
447
+ reactivex==4.0.4
448
+ # via influxdb-client
443
449
  requests==2.32.4
444
450
  # via
445
451
  # asana
@@ -500,6 +506,7 @@ semver==3.0.4
500
506
  setuptools==78.1.1
501
507
  # via
502
508
  # dlt
509
+ # influxdb-client
503
510
  # python-quickbooks
504
511
  # types-setuptools
505
512
  shellingham==1.5.4
@@ -590,6 +597,7 @@ typing-extensions==4.13.0
590
597
  # pydantic
591
598
  # pydantic-core
592
599
  # pyopenssl
600
+ # reactivex
593
601
  # simple-salesforce
594
602
  # snowflake-connector-python
595
603
  # sqlalchemy2-stubs
@@ -619,6 +627,7 @@ urllib3==2.5.0
619
627
  # crate
620
628
  # databricks-sql-connector
621
629
  # elastic-transport
630
+ # influxdb-client
622
631
  # pyairtable
623
632
  # requests
624
633
  # types-requests
@@ -1 +0,0 @@
1
- version = "v0.13.73"
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