ingestr 0.13.12__tar.gz → 0.13.14__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.
- {ingestr-0.13.12 → ingestr-0.13.14}/PKG-INFO +4 -2
- {ingestr-0.13.12 → ingestr-0.13.14}/README.md +1 -1
- ingestr-0.13.14/docs/media/applovin_max.png +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/applovin_max.md +18 -6
- ingestr-0.13.14/ingestr/src/applovin_max/__init__.py +115 -0
- ingestr-0.13.14/ingestr/src/buildinfo.py +1 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/factory.py +1 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/sources.py +36 -17
- {ingestr-0.13.12 → ingestr-0.13.14}/requirements.txt +2 -0
- ingestr-0.13.12/docs/media/applovin_max.png +0 -0
- ingestr-0.13.12/ingestr/src/applovin_max/__init__.py +0 -99
- ingestr-0.13.12/ingestr/src/buildinfo.py +0 -1
- {ingestr-0.13.12 → ingestr-0.13.14}/.dockerignore +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.githooks/pre-commit-hook.sh +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.github/workflows/deploy-docs.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.github/workflows/release.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.github/workflows/secrets-scan.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.github/workflows/tests.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.gitignore +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.gitleaksignore +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.python-version +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/.vale.ini +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/Dockerfile +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/LICENSE.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/Makefile +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/.vitepress/config.mjs +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/.vitepress/theme/custom.css +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/.vitepress/theme/index.js +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/commands/example-uris.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/commands/ingest.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/getting-started/core-concepts.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/getting-started/incremental-loading.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/getting-started/quickstart.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/getting-started/telemetry.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/index.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/media/athena.png +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/media/clickhouse_img.png +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/media/github.png +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/media/googleanalytics.png +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/media/linkedin_ads.png +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/media/personio.png +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/media/tiktok.png +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/adjust.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/airtable.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/applovin.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/appsflyer.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/appstore.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/asana.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/athena.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/bigquery.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/chess.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/clickhouse.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/csv.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/custom_queries.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/databricks.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/duckdb.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/dynamodb.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/facebook-ads.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/gcs.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/github.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/google-ads.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/google_analytics.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/gorgias.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/gsheets.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/hubspot.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/kafka.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/klaviyo.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/linkedin_ads.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/mongodb.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/mssql.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/mysql.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/notion.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/oracle.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/personio.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/postgres.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/redshift.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/s3.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/salesforce.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/sap-hana.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/shopify.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/slack.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/snowflake.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/sqlite.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/stripe.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/tiktok-ads.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/docs/supported-sources/zendesk.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/main.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/.gitignore +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/adjust/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/adjust/adjust_helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/airtable/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/applovin/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/appsflyer/_init_.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/appsflyer/client.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/appstore/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/appstore/client.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/appstore/errors.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/appstore/models.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/appstore/resources.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/arrow/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/asana_source/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/asana_source/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/asana_source/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/blob.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/chess/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/chess/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/chess/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/destinations.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/dynamodb/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/errors.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/facebook_ads/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/facebook_ads/exceptions.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/facebook_ads/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/facebook_ads/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/filesystem/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/filesystem/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/filesystem/readers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/filters.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/github/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/github/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/github/queries.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/github/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_ads/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_ads/field.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_ads/metrics.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_ads/predicates.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_ads/reports.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_analytics/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_analytics/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_sheets/README.md +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_sheets/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/gorgias/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/gorgias/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/hubspot/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/hubspot/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/hubspot/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/kafka/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/kafka/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/klaviyo/_init_.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/klaviyo/client.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/klaviyo/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/linkedin_ads/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/linkedin_ads/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/loader.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/mongodb/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/mongodb/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/notion/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/notion/helpers/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/notion/helpers/client.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/notion/helpers/database.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/notion/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/personio/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/personio/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/salesforce/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/salesforce/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/shopify/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/shopify/exceptions.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/shopify/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/shopify/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/slack/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/slack/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/slack/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/sql_database/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/sql_database/callbacks.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/stripe_analytics/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/stripe_analytics/helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/stripe_analytics/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/table_definition.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/telemetry/event.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/testdata/fakebqcredentials.json +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/tiktok_ads/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/time.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/version.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/zendesk/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/zendesk/helpers/__init__.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/zendesk/helpers/credentials.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/src/zendesk/settings.py +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/testdata/.gitignore +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/testdata/create_replace.csv +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/testdata/delete_insert_expected.csv +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/testdata/delete_insert_part1.csv +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/testdata/delete_insert_part2.csv +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/testdata/merge_expected.csv +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/testdata/merge_part1.csv +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/ingestr/testdata/merge_part2.csv +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/package-lock.json +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/package.json +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/pyproject.toml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/requirements-dev.txt +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/resources/demo.gif +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/resources/demo.tape +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/resources/ingestr.svg +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/AMPM.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Acronyms.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Colons.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Contractions.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/DateFormat.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Ellipses.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/EmDash.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Exclamation.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/FirstPerson.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Gender.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/GenderBias.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/HeadingPunctuation.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Headings.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Latin.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/LyHyphens.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/OptionalPlurals.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Ordinal.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/OxfordComma.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Parens.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Passive.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Periods.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Quotes.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Ranges.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Semicolons.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Slang.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Spacing.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Spelling.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Units.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/We.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/Will.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/WordList.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/meta.json +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/Google/vocab.txt +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/styles/bruin/Ingestr.yml +0 -0
- {ingestr-0.13.12 → ingestr-0.13.14}/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.
|
|
3
|
+
Version: 0.13.14
|
|
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
|
|
@@ -20,6 +20,7 @@ Requires-Dist: clickhouse-driver==0.2.9
|
|
|
20
20
|
Requires-Dist: clickhouse-sqlalchemy==0.2.7
|
|
21
21
|
Requires-Dist: confluent-kafka>=2.8.0
|
|
22
22
|
Requires-Dist: databricks-sql-connector==2.9.3
|
|
23
|
+
Requires-Dist: databricks-sqlalchemy==1.0.2
|
|
23
24
|
Requires-Dist: dataclasses-json==0.6.7
|
|
24
25
|
Requires-Dist: dlt==1.6.1
|
|
25
26
|
Requires-Dist: duckdb-engine==0.15.0
|
|
@@ -57,6 +58,7 @@ Requires-Dist: stripe==10.7.0
|
|
|
57
58
|
Requires-Dist: tqdm==4.67.1
|
|
58
59
|
Requires-Dist: typer==0.13.1
|
|
59
60
|
Requires-Dist: types-requests==2.32.0.20240907
|
|
61
|
+
Requires-Dist: zstd==1.5.6.1
|
|
60
62
|
Provides-Extra: odbc
|
|
61
63
|
Requires-Dist: pyodbc==5.1.0; extra == 'odbc'
|
|
62
64
|
Provides-Extra: oracle
|
|
@@ -149,7 +151,7 @@ Pull requests are welcome. However, please open an issue first to discuss what y
|
|
|
149
151
|
</tr>
|
|
150
152
|
<tr>
|
|
151
153
|
<td>ClickHouse</td>
|
|
152
|
-
<td
|
|
154
|
+
<td>✅</td>
|
|
153
155
|
<td>✅</td>
|
|
154
156
|
</tr>
|
|
155
157
|
<tr>
|
|
Binary file
|
|
@@ -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
|
|
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
|
-
|
|
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
|
|
27
|
-
--source-table "
|
|
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
|
-
[
|
|
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.14"
|
|
@@ -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
|
-
|
|
1848
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1877
|
-
).with_resources(
|
|
1895
|
+
applications=applications,
|
|
1896
|
+
).with_resources(requested_table)
|
|
1878
1897
|
|
|
1879
1898
|
|
|
1880
1899
|
class SalesforceSource:
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|