ingestr 0.13.12__tar.gz → 0.13.13__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 (234) hide show
  1. {ingestr-0.13.12 → ingestr-0.13.13}/PKG-INFO +3 -2
  2. {ingestr-0.13.12 → ingestr-0.13.13}/README.md +1 -1
  3. ingestr-0.13.13/docs/media/applovin_max.png +0 -0
  4. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/applovin_max.md +18 -6
  5. ingestr-0.13.13/ingestr/src/applovin_max/__init__.py +115 -0
  6. ingestr-0.13.13/ingestr/src/buildinfo.py +1 -0
  7. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/sources.py +36 -17
  8. {ingestr-0.13.12 → ingestr-0.13.13}/requirements.txt +1 -0
  9. ingestr-0.13.12/docs/media/applovin_max.png +0 -0
  10. ingestr-0.13.12/ingestr/src/applovin_max/__init__.py +0 -99
  11. ingestr-0.13.12/ingestr/src/buildinfo.py +0 -1
  12. {ingestr-0.13.12 → ingestr-0.13.13}/.dockerignore +0 -0
  13. {ingestr-0.13.12 → ingestr-0.13.13}/.githooks/pre-commit-hook.sh +0 -0
  14. {ingestr-0.13.12 → ingestr-0.13.13}/.github/workflows/deploy-docs.yml +0 -0
  15. {ingestr-0.13.12 → ingestr-0.13.13}/.github/workflows/release.yml +0 -0
  16. {ingestr-0.13.12 → ingestr-0.13.13}/.github/workflows/secrets-scan.yml +0 -0
  17. {ingestr-0.13.12 → ingestr-0.13.13}/.github/workflows/tests.yml +0 -0
  18. {ingestr-0.13.12 → ingestr-0.13.13}/.gitignore +0 -0
  19. {ingestr-0.13.12 → ingestr-0.13.13}/.gitleaksignore +0 -0
  20. {ingestr-0.13.12 → ingestr-0.13.13}/.python-version +0 -0
  21. {ingestr-0.13.12 → ingestr-0.13.13}/.vale.ini +0 -0
  22. {ingestr-0.13.12 → ingestr-0.13.13}/Dockerfile +0 -0
  23. {ingestr-0.13.12 → ingestr-0.13.13}/LICENSE.md +0 -0
  24. {ingestr-0.13.12 → ingestr-0.13.13}/Makefile +0 -0
  25. {ingestr-0.13.12 → ingestr-0.13.13}/docs/.vitepress/config.mjs +0 -0
  26. {ingestr-0.13.12 → ingestr-0.13.13}/docs/.vitepress/theme/custom.css +0 -0
  27. {ingestr-0.13.12 → ingestr-0.13.13}/docs/.vitepress/theme/index.js +0 -0
  28. {ingestr-0.13.12 → ingestr-0.13.13}/docs/commands/example-uris.md +0 -0
  29. {ingestr-0.13.12 → ingestr-0.13.13}/docs/commands/ingest.md +0 -0
  30. {ingestr-0.13.12 → ingestr-0.13.13}/docs/getting-started/core-concepts.md +0 -0
  31. {ingestr-0.13.12 → ingestr-0.13.13}/docs/getting-started/incremental-loading.md +0 -0
  32. {ingestr-0.13.12 → ingestr-0.13.13}/docs/getting-started/quickstart.md +0 -0
  33. {ingestr-0.13.12 → ingestr-0.13.13}/docs/getting-started/telemetry.md +0 -0
  34. {ingestr-0.13.12 → ingestr-0.13.13}/docs/index.md +0 -0
  35. {ingestr-0.13.12 → ingestr-0.13.13}/docs/media/athena.png +0 -0
  36. {ingestr-0.13.12 → ingestr-0.13.13}/docs/media/clickhouse_img.png +0 -0
  37. {ingestr-0.13.12 → ingestr-0.13.13}/docs/media/github.png +0 -0
  38. {ingestr-0.13.12 → ingestr-0.13.13}/docs/media/googleanalytics.png +0 -0
  39. {ingestr-0.13.12 → ingestr-0.13.13}/docs/media/linkedin_ads.png +0 -0
  40. {ingestr-0.13.12 → ingestr-0.13.13}/docs/media/personio.png +0 -0
  41. {ingestr-0.13.12 → ingestr-0.13.13}/docs/media/tiktok.png +0 -0
  42. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/adjust.md +0 -0
  43. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/airtable.md +0 -0
  44. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/applovin.md +0 -0
  45. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/appsflyer.md +0 -0
  46. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/appstore.md +0 -0
  47. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/asana.md +0 -0
  48. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/athena.md +0 -0
  49. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/bigquery.md +0 -0
  50. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/chess.md +0 -0
  51. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/clickhouse.md +0 -0
  52. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/csv.md +0 -0
  53. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/custom_queries.md +0 -0
  54. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/databricks.md +0 -0
  55. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/duckdb.md +0 -0
  56. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/dynamodb.md +0 -0
  57. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/facebook-ads.md +0 -0
  58. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/gcs.md +0 -0
  59. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/github.md +0 -0
  60. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/google-ads.md +0 -0
  61. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/google_analytics.md +0 -0
  62. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/gorgias.md +0 -0
  63. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/gsheets.md +0 -0
  64. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/hubspot.md +0 -0
  65. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/kafka.md +0 -0
  66. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/klaviyo.md +0 -0
  67. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/linkedin_ads.md +0 -0
  68. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/mongodb.md +0 -0
  69. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/mssql.md +0 -0
  70. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/mysql.md +0 -0
  71. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/notion.md +0 -0
  72. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/oracle.md +0 -0
  73. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/personio.md +0 -0
  74. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/postgres.md +0 -0
  75. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/redshift.md +0 -0
  76. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/s3.md +0 -0
  77. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/salesforce.md +0 -0
  78. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/sap-hana.md +0 -0
  79. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/shopify.md +0 -0
  80. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/slack.md +0 -0
  81. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/snowflake.md +0 -0
  82. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/sqlite.md +0 -0
  83. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/stripe.md +0 -0
  84. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/tiktok-ads.md +0 -0
  85. {ingestr-0.13.12 → ingestr-0.13.13}/docs/supported-sources/zendesk.md +0 -0
  86. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/main.py +0 -0
  87. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/.gitignore +0 -0
  88. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/adjust/__init__.py +0 -0
  89. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/adjust/adjust_helpers.py +0 -0
  90. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/airtable/__init__.py +0 -0
  91. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/applovin/__init__.py +0 -0
  92. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/appsflyer/_init_.py +0 -0
  93. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/appsflyer/client.py +0 -0
  94. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/appstore/__init__.py +0 -0
  95. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/appstore/client.py +0 -0
  96. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/appstore/errors.py +0 -0
  97. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/appstore/models.py +0 -0
  98. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/appstore/resources.py +0 -0
  99. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/arrow/__init__.py +0 -0
  100. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/asana_source/__init__.py +0 -0
  101. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/asana_source/helpers.py +0 -0
  102. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/asana_source/settings.py +0 -0
  103. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/blob.py +0 -0
  104. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/chess/__init__.py +0 -0
  105. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/chess/helpers.py +0 -0
  106. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/chess/settings.py +0 -0
  107. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/destinations.py +0 -0
  108. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/dynamodb/__init__.py +0 -0
  109. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/errors.py +0 -0
  110. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/facebook_ads/__init__.py +0 -0
  111. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/facebook_ads/exceptions.py +0 -0
  112. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/facebook_ads/helpers.py +0 -0
  113. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/facebook_ads/settings.py +0 -0
  114. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/factory.py +0 -0
  115. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/filesystem/__init__.py +0 -0
  116. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/filesystem/helpers.py +0 -0
  117. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/filesystem/readers.py +0 -0
  118. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/filters.py +0 -0
  119. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/github/__init__.py +0 -0
  120. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/github/helpers.py +0 -0
  121. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/github/queries.py +0 -0
  122. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/github/settings.py +0 -0
  123. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_ads/__init__.py +0 -0
  124. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_ads/field.py +0 -0
  125. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_ads/metrics.py +0 -0
  126. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_ads/predicates.py +0 -0
  127. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_ads/reports.py +0 -0
  128. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_analytics/__init__.py +0 -0
  129. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_analytics/helpers.py +0 -0
  130. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_sheets/README.md +0 -0
  131. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_sheets/__init__.py +0 -0
  132. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
  133. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
  134. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
  135. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/gorgias/__init__.py +0 -0
  136. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/gorgias/helpers.py +0 -0
  137. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/hubspot/__init__.py +0 -0
  138. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/hubspot/helpers.py +0 -0
  139. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/hubspot/settings.py +0 -0
  140. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/kafka/__init__.py +0 -0
  141. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/kafka/helpers.py +0 -0
  142. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/klaviyo/_init_.py +0 -0
  143. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/klaviyo/client.py +0 -0
  144. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/klaviyo/helpers.py +0 -0
  145. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/linkedin_ads/__init__.py +0 -0
  146. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
  147. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/linkedin_ads/helpers.py +0 -0
  148. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/loader.py +0 -0
  149. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/mongodb/__init__.py +0 -0
  150. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/mongodb/helpers.py +0 -0
  151. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/notion/__init__.py +0 -0
  152. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/notion/helpers/__init__.py +0 -0
  153. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/notion/helpers/client.py +0 -0
  154. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/notion/helpers/database.py +0 -0
  155. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/notion/settings.py +0 -0
  156. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/personio/__init__.py +0 -0
  157. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/personio/helpers.py +0 -0
  158. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/salesforce/__init__.py +0 -0
  159. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/salesforce/helpers.py +0 -0
  160. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/shopify/__init__.py +0 -0
  161. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/shopify/exceptions.py +0 -0
  162. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/shopify/helpers.py +0 -0
  163. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/shopify/settings.py +0 -0
  164. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/slack/__init__.py +0 -0
  165. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/slack/helpers.py +0 -0
  166. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/slack/settings.py +0 -0
  167. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/sql_database/__init__.py +0 -0
  168. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/sql_database/callbacks.py +0 -0
  169. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/stripe_analytics/__init__.py +0 -0
  170. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/stripe_analytics/helpers.py +0 -0
  171. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/stripe_analytics/settings.py +0 -0
  172. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/table_definition.py +0 -0
  173. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/telemetry/event.py +0 -0
  174. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/testdata/fakebqcredentials.json +0 -0
  175. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/tiktok_ads/__init__.py +0 -0
  176. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
  177. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/time.py +0 -0
  178. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/version.py +0 -0
  179. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/zendesk/__init__.py +0 -0
  180. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/zendesk/helpers/__init__.py +0 -0
  181. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
  182. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/zendesk/helpers/credentials.py +0 -0
  183. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
  184. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/src/zendesk/settings.py +0 -0
  185. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/testdata/.gitignore +0 -0
  186. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/testdata/create_replace.csv +0 -0
  187. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/testdata/delete_insert_expected.csv +0 -0
  188. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/testdata/delete_insert_part1.csv +0 -0
  189. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/testdata/delete_insert_part2.csv +0 -0
  190. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/testdata/merge_expected.csv +0 -0
  191. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/testdata/merge_part1.csv +0 -0
  192. {ingestr-0.13.12 → ingestr-0.13.13}/ingestr/testdata/merge_part2.csv +0 -0
  193. {ingestr-0.13.12 → ingestr-0.13.13}/package-lock.json +0 -0
  194. {ingestr-0.13.12 → ingestr-0.13.13}/package.json +0 -0
  195. {ingestr-0.13.12 → ingestr-0.13.13}/pyproject.toml +0 -0
  196. {ingestr-0.13.12 → ingestr-0.13.13}/requirements-dev.txt +0 -0
  197. {ingestr-0.13.12 → ingestr-0.13.13}/resources/demo.gif +0 -0
  198. {ingestr-0.13.12 → ingestr-0.13.13}/resources/demo.tape +0 -0
  199. {ingestr-0.13.12 → ingestr-0.13.13}/resources/ingestr.svg +0 -0
  200. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/AMPM.yml +0 -0
  201. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Acronyms.yml +0 -0
  202. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Colons.yml +0 -0
  203. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Contractions.yml +0 -0
  204. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/DateFormat.yml +0 -0
  205. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Ellipses.yml +0 -0
  206. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/EmDash.yml +0 -0
  207. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Exclamation.yml +0 -0
  208. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/FirstPerson.yml +0 -0
  209. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Gender.yml +0 -0
  210. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/GenderBias.yml +0 -0
  211. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/HeadingPunctuation.yml +0 -0
  212. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Headings.yml +0 -0
  213. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Latin.yml +0 -0
  214. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/LyHyphens.yml +0 -0
  215. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/OptionalPlurals.yml +0 -0
  216. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Ordinal.yml +0 -0
  217. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/OxfordComma.yml +0 -0
  218. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Parens.yml +0 -0
  219. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Passive.yml +0 -0
  220. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Periods.yml +0 -0
  221. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Quotes.yml +0 -0
  222. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Ranges.yml +0 -0
  223. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Semicolons.yml +0 -0
  224. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Slang.yml +0 -0
  225. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Spacing.yml +0 -0
  226. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Spelling.yml +0 -0
  227. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Units.yml +0 -0
  228. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/We.yml +0 -0
  229. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/Will.yml +0 -0
  230. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/WordList.yml +0 -0
  231. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/meta.json +0 -0
  232. {ingestr-0.13.12 → ingestr-0.13.13}/styles/Google/vocab.txt +0 -0
  233. {ingestr-0.13.12 → ingestr-0.13.13}/styles/bruin/Ingestr.yml +0 -0
  234. {ingestr-0.13.12 → ingestr-0.13.13}/styles/config/vocabularies/bruin/accept.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ingestr
3
- Version: 0.13.12
3
+ Version: 0.13.13
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
@@ -57,6 +57,7 @@ Requires-Dist: stripe==10.7.0
57
57
  Requires-Dist: tqdm==4.67.1
58
58
  Requires-Dist: typer==0.13.1
59
59
  Requires-Dist: types-requests==2.32.0.20240907
60
+ Requires-Dist: zstd==1.5.6.1
60
61
  Provides-Extra: odbc
61
62
  Requires-Dist: pyodbc==5.1.0; extra == 'odbc'
62
63
  Provides-Extra: oracle
@@ -149,7 +150,7 @@ Pull requests are welcome. However, please open an issue first to discuss what y
149
150
  </tr>
150
151
  <tr>
151
152
  <td>ClickHouse</td>
152
- <td>❌</td>
153
+ <td>✅</td>
153
154
  <td>✅</td>
154
155
  </tr>
155
156
  <tr>
@@ -84,7 +84,7 @@ Pull requests are welcome. However, please open an issue first to discuss what y
84
84
  </tr>
85
85
  <tr>
86
86
  <td>ClickHouse</td>
87
- <td>❌</td>
87
+ <td>✅</td>
88
88
  <td>✅</td>
89
89
  </tr>
90
90
  <tr>
@@ -6,12 +6,24 @@
6
6
  ## URI Format
7
7
  The URI format for Applovin Max is as follows:
8
8
  ```
9
- applovinmax://?api_key=<your_api_key>&application=<application_name>
9
+ applovinmax://?api_key=<your_api_key>
10
10
  ```
11
11
 
12
12
  URI Parameters:
13
13
  - `api_key`: It is the `report key` which is used for authenticating the request.
14
- - `application`: The application package name (for Android and Fire OS) or bundle ID (for iOS).
14
+
15
+ ## Source Table Format
16
+ The source table format should be specified as:
17
+ ```
18
+ <table_name>:<application_ids>
19
+ ```
20
+
21
+ Example:
22
+ ```
23
+ user_ad_revenue:com.example.app1,com.example.app2
24
+ ```
25
+
26
+ - `application_id` should be the application package name (for Android and Fire OS) or bundle ID (for iOS).
15
27
 
16
28
  ## Setting up Applovin Integration
17
29
 
@@ -19,12 +31,12 @@ URI Parameters:
19
31
  You can generate a report key from your [AppLovin dashboard](https://developers.applovin.com/en/max/max-dashboard/account/account-info/#keys).
20
32
 
21
33
  ### Example:
22
- To retrieve `ad revenue` data for an application `com.example.app` with api key `key_123`, and to store it in a DuckDB database, use the following command:
34
+ To retrieve `user ad revenue` data for an application `com.example.app` with api key `key_123`, and to store it in a DuckDB database, use the following command:
23
35
 
24
36
  ```sh
25
37
  ingestr ingest \
26
- --source-uri "applovinmax://?api_key=key_123&application=com.example.app" \
27
- --source-table "ad_revenue" \
38
+ --source-uri "applovinmax://?api_key=key_123" \
39
+ --source-table "user_ad_revenue:com.example.app" \
28
40
  --dest-uri "duckdb:///applovin_max.db" \
29
41
  --dest-table "dest.ad_revenue"
30
42
  ```
@@ -33,4 +45,4 @@ By default, `ingestr` retrieves data for the last 30 days. For a custom date ran
33
45
  <img alt="applovin_max_img" src="../media/applovin_max.png"/>
34
46
 
35
47
  ## Table
36
- [ad_revenue](https://developers.applovin.com/en/max/reporting-apis/user-level-ad-revenue-api/): Provides daily metrics from the user-level ad revenue API.User-level revenue data is available eight hours after UTC day end. So, for example, data for UTC 2025-01-01 is available on UTC 2025-01-02 after 08:00.
48
+ [user_ad_revenue](https://developers.applovin.com/en/max/reporting-apis/user-level-ad-revenue-api/): Provides daily metrics from the user level ad revenue API.User-level revenue data is available eight hours after UTC day end. So, for example, data for UTC 2025-01-01 is available on UTC 2025-01-02 after 08:00.
@@ -0,0 +1,115 @@
1
+ from datetime import timedelta
2
+ from typing import Iterator
3
+
4
+ import dlt
5
+ import pandas as pd # type: ignore[import-untyped]
6
+ import pendulum
7
+ import requests
8
+ from dlt.sources import DltResource
9
+ from dlt.sources.helpers.requests import Client
10
+ from pendulum.date import Date
11
+
12
+
13
+ @dlt.source(max_table_nesting=0)
14
+ def applovin_max_source(
15
+ start_date: Date,
16
+ applications: list[str],
17
+ api_key: str,
18
+ end_date: Date | None,
19
+ ) -> DltResource:
20
+ @dlt.resource(
21
+ name="user_ad_revenue",
22
+ write_disposition="merge",
23
+ merge_key="partition_date",
24
+ columns={
25
+ "partition_date": {"data_type": "date", "partition": True},
26
+ },
27
+ )
28
+ def fetch_ad_revenue_report(
29
+ dateTime=(
30
+ dlt.sources.incremental(
31
+ "partition_date",
32
+ initial_value=start_date,
33
+ end_value=end_date,
34
+ range_start="closed",
35
+ range_end="closed",
36
+ )
37
+ ),
38
+ ) -> Iterator[dict]:
39
+ url = "https://r.applovin.com/max/userAdRevenueReport"
40
+ start_date = dateTime.last_value
41
+
42
+ if dateTime.end_value is None:
43
+ end_date = (pendulum.yesterday("UTC")).date()
44
+ else:
45
+ end_date = dateTime.end_value
46
+
47
+ client = create_client()
48
+ platforms = ["ios", "android", "fireos"]
49
+
50
+ for app in applications:
51
+ current_date = start_date
52
+ while current_date <= end_date:
53
+ for platform in platforms:
54
+ df = get_data(
55
+ url=url,
56
+ current_date=current_date,
57
+ application=app,
58
+ api_key=api_key,
59
+ client=client,
60
+ platform=platform,
61
+ )
62
+ if df is not None:
63
+ yield df
64
+ current_date = current_date + timedelta(days=1)
65
+
66
+ return fetch_ad_revenue_report
67
+
68
+
69
+ def create_client() -> requests.Session:
70
+ return Client(
71
+ request_timeout=10.0,
72
+ raise_for_status=False,
73
+ retry_condition=retry_on_limit,
74
+ request_max_attempts=12,
75
+ ).session
76
+
77
+
78
+ def retry_on_limit(
79
+ response: requests.Response | None, exception: BaseException | None
80
+ ) -> bool:
81
+ if response is None:
82
+ return False
83
+ return response.status_code == 429
84
+
85
+
86
+ def get_data(
87
+ url: str,
88
+ current_date: Date,
89
+ application: str,
90
+ api_key: str,
91
+ platform: str,
92
+ client: requests.Session,
93
+ ):
94
+ params = {
95
+ "api_key": api_key,
96
+ "date": current_date.isoformat(),
97
+ "platform": platform,
98
+ "application": application,
99
+ "aggregated": "false",
100
+ }
101
+
102
+ response = client.get(url=url, params=params)
103
+
104
+ if response.status_code != 200:
105
+ if response.status_code == 404:
106
+ if "No Mediation App Id found for platform" in response.text:
107
+ return None
108
+ error_message = f"AppLovin MAX API error (status {response.status_code}): {response.text}"
109
+ raise requests.HTTPError(error_message)
110
+
111
+ response_url = response.json().get("ad_revenue_report_url")
112
+ df = pd.read_csv(response_url)
113
+ df["Date"] = pd.to_datetime(df["Date"])
114
+ df["partition_date"] = df["Date"].dt.date
115
+ return df
@@ -0,0 +1 @@
1
+ version = "v0.13.13"
@@ -1833,6 +1833,9 @@ class AppLovinSource:
1833
1833
 
1834
1834
 
1835
1835
  class ApplovinMaxSource:
1836
+ #expected uri format: applovinmax://?api_key=<api_key>
1837
+ #expected table format: user_ad_revenue:app_id_1,app_id_2
1838
+
1836
1839
  def handles_incrementality(self) -> bool:
1837
1840
  return True
1838
1841
 
@@ -1843,38 +1846,54 @@ class ApplovinMaxSource:
1843
1846
  api_key = params.get("api_key")
1844
1847
  if api_key is None:
1845
1848
  raise ValueError("api_key is required to connect to AppLovin Max API.")
1849
+
1850
+ AVAILABLE_TABLES = ["user_ad_revenue"]
1846
1851
 
1847
- application = params.get("application")
1848
- if application is None:
1849
- raise ValueError("application is required to connect to AppLovin Max API.")
1852
+ table_fields = table.split(":")
1853
+ requested_table = table_fields[0]
1850
1854
 
1851
- interval_start = kwargs.get("interval_start")
1852
- interval_end = kwargs.get("interval_end")
1853
-
1854
- if "ad_revenue" in table:
1855
- table = "ad_revenue"
1856
- else:
1855
+ if len(table_fields) != 2:
1857
1856
  raise ValueError(
1858
- f"Table name '{table}' is not supported for AppLovin Max source yet, if you are interested in it please create a GitHub issue at https://github.com/bruin-data/ingestr"
1857
+ "Invalid table format. Expected format is user_ad_revenue:app_id_1,app_id_2"
1858
+ )
1859
+
1860
+ if requested_table not in AVAILABLE_TABLES:
1861
+ raise ValueError(
1862
+ f"Table name '{requested_table}' is not supported for AppLovin Max source yet."
1863
+ f"Only '{AVAILABLE_TABLES}' are currently supported. "
1864
+ "If you need additional tables, please create a GitHub issue at "
1865
+ "https://github.com/bruin-data/ingestr"
1866
+ )
1867
+
1868
+ applications = [i for i in table_fields[1].replace(" ", "").split(",") if i.strip()]
1869
+ if len(applications) == 0:
1870
+ raise ValueError(
1871
+ "At least one application id is required"
1872
+ )
1873
+
1874
+ if len(applications) != len(set(applications)):
1875
+ raise ValueError(
1876
+ "Application ids must be unique."
1859
1877
  )
1860
1878
 
1879
+ interval_start = kwargs.get("interval_start")
1880
+ interval_end = kwargs.get("interval_end")
1881
+
1861
1882
  now = pendulum.now("UTC")
1862
1883
  default_start = now.subtract(days=30).date()
1863
1884
 
1864
1885
  start_date = (
1865
- interval_start if interval_start is not None else default_start
1866
- ).strftime("%Y-%m-%d")
1867
-
1868
- end_date = (
1869
- interval_end.strftime("%Y-%m-%d") if interval_end is not None else None
1886
+ interval_start.date() if interval_start is not None else default_start
1870
1887
  )
1871
1888
 
1889
+ end_date = interval_end.date() if interval_end is not None else None
1890
+
1872
1891
  return applovin_max_source(
1873
1892
  start_date=start_date,
1874
1893
  end_date=end_date,
1875
1894
  api_key=api_key[0],
1876
- application=application[0],
1877
- ).with_resources(table)
1895
+ applications=applications,
1896
+ ).with_resources(requested_table)
1878
1897
 
1879
1898
 
1880
1899
  class SalesforceSource:
@@ -45,3 +45,4 @@ clickhouse-connect==0.8.14
45
45
  clickhouse-driver==0.2.9
46
46
  clickhouse-sqlalchemy==0.2.7
47
47
  simple-salesforce==1.12.6
48
+ zstd==1.5.6.1
Binary file
@@ -1,99 +0,0 @@
1
- from typing import Iterator
2
-
3
- import dlt
4
- import pandas as pd # type: ignore[import-untyped]
5
- import pendulum
6
- import requests
7
- from dlt.sources import DltResource
8
- from dlt.sources.helpers.requests import Client
9
- from pendulum.date import Date
10
-
11
-
12
- @dlt.source(max_table_nesting=0)
13
- def applovin_max_source(
14
- start_date: str,
15
- application: str,
16
- api_key: str,
17
- end_date: str | None,
18
- ) -> DltResource:
19
- @dlt.resource(
20
- name="ad_revenue",
21
- write_disposition="merge",
22
- merge_key="_partition_date",
23
- )
24
- def fetch_ad_revenue_report(
25
- dateTime=(
26
- dlt.sources.incremental(
27
- "_partition_date",
28
- initial_value=start_date,
29
- end_value=end_date,
30
- range_start="closed",
31
- range_end="closed",
32
- )
33
- ),
34
- ) -> Iterator[dict]:
35
- url = "https://r.applovin.com/max/userAdRevenueReport"
36
- start_date = pendulum.from_format(dateTime.last_value, "YYYY-MM-DD").date()
37
- if dateTime.end_value is None:
38
- end_date = (pendulum.yesterday("UTC")).date()
39
- else:
40
- end_date = pendulum.from_format(dateTime.end_value, "YYYY-MM-DD").date()
41
- yield get_data(
42
- url=url,
43
- start_date=start_date,
44
- end_date=end_date,
45
- application=application,
46
- api_key=api_key,
47
- )
48
-
49
- return fetch_ad_revenue_report
50
-
51
-
52
- def create_client() -> requests.Session:
53
- return Client(
54
- request_timeout=10.0,
55
- raise_for_status=False,
56
- retry_condition=retry_on_limit,
57
- request_max_attempts=12,
58
- ).session
59
-
60
-
61
- def retry_on_limit(
62
- response: requests.Response | None, exception: BaseException | None
63
- ) -> bool:
64
- if response is None:
65
- return False
66
- return response.status_code == 429
67
-
68
-
69
- def get_data(
70
- url: str, start_date: Date, end_date: Date, application: str, api_key: str
71
- ):
72
- client = create_client()
73
- platforms = ["ios", "android", "fireos"]
74
- current_date = start_date
75
- while current_date <= end_date:
76
- for platform in platforms:
77
- params = {
78
- "api_key": api_key,
79
- "date": current_date.strftime("%Y-%m-%d"),
80
- "platform": platform,
81
- "application": application,
82
- "aggregated": "false",
83
- }
84
-
85
- response = client.get(url=url, params=params)
86
-
87
- if response.status_code == 400:
88
- raise ValueError(response.text)
89
-
90
- if response.status_code != 200:
91
- continue
92
-
93
- response_url = response.json().get("ad_revenue_report_url")
94
- df = pd.read_csv(response_url)
95
- df["Date"] = pd.to_datetime(df["Date"])
96
- df["_partition_date"] = df["Date"].dt.strftime("%Y-%m-%d")
97
- yield df
98
-
99
- current_date = current_date.add(days=1)
@@ -1 +0,0 @@
1
- version = "v0.13.12"
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