ingestr 0.13.11__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.
- {ingestr-0.13.11 → ingestr-0.13.13}/PKG-INFO +3 -2
- {ingestr-0.13.11 → ingestr-0.13.13}/README.md +1 -1
- ingestr-0.13.13/docs/media/applovin_max.png +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/applovin_max.md +18 -6
- ingestr-0.13.13/ingestr/src/applovin_max/__init__.py +115 -0
- ingestr-0.13.13/ingestr/src/buildinfo.py +1 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/personio/__init__.py +1 -1
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/personio/helpers.py +1 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/sources.py +40 -17
- {ingestr-0.13.11 → ingestr-0.13.13}/requirements.txt +1 -0
- ingestr-0.13.11/docs/media/applovin_max.png +0 -0
- ingestr-0.13.11/ingestr/src/applovin_max/__init__.py +0 -99
- ingestr-0.13.11/ingestr/src/buildinfo.py +0 -1
- {ingestr-0.13.11 → ingestr-0.13.13}/.dockerignore +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.githooks/pre-commit-hook.sh +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.github/workflows/deploy-docs.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.github/workflows/release.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.github/workflows/secrets-scan.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.github/workflows/tests.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.gitignore +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.gitleaksignore +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.python-version +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/.vale.ini +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/Dockerfile +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/LICENSE.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/Makefile +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/.vitepress/config.mjs +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/.vitepress/theme/custom.css +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/.vitepress/theme/index.js +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/commands/example-uris.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/commands/ingest.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/getting-started/core-concepts.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/getting-started/incremental-loading.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/getting-started/quickstart.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/getting-started/telemetry.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/index.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/media/athena.png +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/media/clickhouse_img.png +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/media/github.png +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/media/googleanalytics.png +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/media/linkedin_ads.png +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/media/personio.png +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/media/tiktok.png +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/adjust.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/airtable.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/applovin.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/appsflyer.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/appstore.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/asana.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/athena.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/bigquery.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/chess.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/clickhouse.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/csv.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/custom_queries.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/databricks.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/duckdb.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/dynamodb.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/facebook-ads.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/gcs.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/github.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/google-ads.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/google_analytics.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/gorgias.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/gsheets.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/hubspot.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/kafka.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/klaviyo.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/linkedin_ads.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/mongodb.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/mssql.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/mysql.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/notion.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/oracle.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/personio.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/postgres.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/redshift.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/s3.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/salesforce.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/sap-hana.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/shopify.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/slack.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/snowflake.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/sqlite.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/stripe.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/tiktok-ads.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/docs/supported-sources/zendesk.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/main.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/.gitignore +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/adjust/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/adjust/adjust_helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/airtable/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/applovin/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/appsflyer/_init_.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/appsflyer/client.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/appstore/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/appstore/client.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/appstore/errors.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/appstore/models.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/appstore/resources.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/arrow/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/asana_source/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/asana_source/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/asana_source/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/blob.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/chess/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/chess/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/chess/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/destinations.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/dynamodb/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/errors.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/facebook_ads/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/facebook_ads/exceptions.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/facebook_ads/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/facebook_ads/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/factory.py +1 -1
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/filesystem/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/filesystem/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/filesystem/readers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/filters.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/github/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/github/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/github/queries.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/github/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_ads/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_ads/field.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_ads/metrics.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_ads/predicates.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_ads/reports.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_analytics/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_analytics/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_sheets/README.md +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_sheets/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/gorgias/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/gorgias/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/hubspot/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/hubspot/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/hubspot/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/kafka/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/kafka/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/klaviyo/_init_.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/klaviyo/client.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/klaviyo/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/linkedin_ads/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/linkedin_ads/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/loader.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/mongodb/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/mongodb/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/notion/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/notion/helpers/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/notion/helpers/client.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/notion/helpers/database.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/notion/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/salesforce/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/salesforce/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/shopify/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/shopify/exceptions.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/shopify/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/shopify/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/slack/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/slack/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/slack/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/sql_database/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/sql_database/callbacks.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/stripe_analytics/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/stripe_analytics/helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/stripe_analytics/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/table_definition.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/telemetry/event.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/testdata/fakebqcredentials.json +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/tiktok_ads/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/time.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/version.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/zendesk/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/zendesk/helpers/__init__.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/zendesk/helpers/credentials.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/src/zendesk/settings.py +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/testdata/.gitignore +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/testdata/create_replace.csv +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/testdata/delete_insert_expected.csv +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/testdata/delete_insert_part1.csv +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/testdata/delete_insert_part2.csv +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/testdata/merge_expected.csv +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/testdata/merge_part1.csv +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/ingestr/testdata/merge_part2.csv +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/package-lock.json +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/package.json +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/pyproject.toml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/requirements-dev.txt +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/resources/demo.gif +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/resources/demo.tape +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/resources/ingestr.svg +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/AMPM.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Acronyms.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Colons.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Contractions.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/DateFormat.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Ellipses.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/EmDash.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Exclamation.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/FirstPerson.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Gender.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/GenderBias.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/HeadingPunctuation.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Headings.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Latin.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/LyHyphens.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/OptionalPlurals.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Ordinal.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/OxfordComma.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Parens.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Passive.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Periods.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Quotes.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Ranges.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Semicolons.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Slang.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Spacing.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Spelling.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Units.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/We.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/Will.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/WordList.yml +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/meta.json +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/Google/vocab.txt +0 -0
- {ingestr-0.13.11 → ingestr-0.13.13}/styles/bruin/Ingestr.yml +0 -0
- {ingestr-0.13.11 → 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.
|
|
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
|
|
153
|
+
<td>✅</td>
|
|
153
154
|
<td>✅</td>
|
|
154
155
|
</tr>
|
|
155
156
|
<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.13"
|
|
@@ -402,6 +402,7 @@ class LocalCsvSource:
|
|
|
402
402
|
if inc_value < incremental.start_value:
|
|
403
403
|
continue
|
|
404
404
|
|
|
405
|
+
dictionary = self.remove_empty_columns(dictionary)
|
|
405
406
|
page.append(dictionary)
|
|
406
407
|
current_items += 1
|
|
407
408
|
else:
|
|
@@ -425,6 +426,9 @@ class LocalCsvSource:
|
|
|
425
426
|
)
|
|
426
427
|
)
|
|
427
428
|
|
|
429
|
+
def remove_empty_columns(self, row: Dict[str, str]) -> Dict[str, str]:
|
|
430
|
+
return {k: v for k, v in row.items() if v.strip() != ""}
|
|
431
|
+
|
|
428
432
|
|
|
429
433
|
class NotionSource:
|
|
430
434
|
table_builder: Callable
|
|
@@ -1829,6 +1833,9 @@ class AppLovinSource:
|
|
|
1829
1833
|
|
|
1830
1834
|
|
|
1831
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
|
+
|
|
1832
1839
|
def handles_incrementality(self) -> bool:
|
|
1833
1840
|
return True
|
|
1834
1841
|
|
|
@@ -1839,38 +1846,54 @@ class ApplovinMaxSource:
|
|
|
1839
1846
|
api_key = params.get("api_key")
|
|
1840
1847
|
if api_key is None:
|
|
1841
1848
|
raise ValueError("api_key is required to connect to AppLovin Max API.")
|
|
1849
|
+
|
|
1850
|
+
AVAILABLE_TABLES = ["user_ad_revenue"]
|
|
1842
1851
|
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
raise ValueError("application is required to connect to AppLovin Max API.")
|
|
1846
|
-
|
|
1847
|
-
interval_start = kwargs.get("interval_start")
|
|
1848
|
-
interval_end = kwargs.get("interval_end")
|
|
1852
|
+
table_fields = table.split(":")
|
|
1853
|
+
requested_table = table_fields[0]
|
|
1849
1854
|
|
|
1850
|
-
if
|
|
1851
|
-
|
|
1852
|
-
|
|
1855
|
+
if len(table_fields) != 2:
|
|
1856
|
+
raise ValueError(
|
|
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:
|
|
1853
1870
|
raise ValueError(
|
|
1854
|
-
|
|
1871
|
+
"At least one application id is required"
|
|
1855
1872
|
)
|
|
1873
|
+
|
|
1874
|
+
if len(applications) != len(set(applications)):
|
|
1875
|
+
raise ValueError(
|
|
1876
|
+
"Application ids must be unique."
|
|
1877
|
+
)
|
|
1878
|
+
|
|
1879
|
+
interval_start = kwargs.get("interval_start")
|
|
1880
|
+
interval_end = kwargs.get("interval_end")
|
|
1856
1881
|
|
|
1857
1882
|
now = pendulum.now("UTC")
|
|
1858
1883
|
default_start = now.subtract(days=30).date()
|
|
1859
1884
|
|
|
1860
1885
|
start_date = (
|
|
1861
|
-
interval_start if interval_start is not None else default_start
|
|
1862
|
-
).strftime("%Y-%m-%d")
|
|
1863
|
-
|
|
1864
|
-
end_date = (
|
|
1865
|
-
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
|
|
1866
1887
|
)
|
|
1867
1888
|
|
|
1889
|
+
end_date = interval_end.date() if interval_end is not None else None
|
|
1890
|
+
|
|
1868
1891
|
return applovin_max_source(
|
|
1869
1892
|
start_date=start_date,
|
|
1870
1893
|
end_date=end_date,
|
|
1871
1894
|
api_key=api_key[0],
|
|
1872
|
-
|
|
1873
|
-
).with_resources(
|
|
1895
|
+
applications=applications,
|
|
1896
|
+
).with_resources(requested_table)
|
|
1874
1897
|
|
|
1875
1898
|
|
|
1876
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.11"
|
|
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
|