ingestr 0.13.80__tar.gz → 0.13.81__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.80 → ingestr-0.13.81}/PKG-INFO +1 -1
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/facebook-ads.md +63 -5
- ingestr-0.13.81/ingestr/src/buildinfo.py +1 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/facebook_ads/__init__.py +9 -15
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/facebook_ads/helpers.py +46 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/linear/__init__.py +4 -2
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/linear/helpers.py +6 -8
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/sources.py +2 -19
- ingestr-0.13.80/ingestr/src/buildinfo.py +0 -1
- {ingestr-0.13.80 → ingestr-0.13.81}/.dlt/config.toml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.dockerignore +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.githooks/pre-commit-hook.sh +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.github/workflows/deploy-docs.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.github/workflows/release.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.github/workflows/secrets-scan.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.github/workflows/tests.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.gitignore +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.gitleaksignore +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.python-version +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/.vale.ini +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/Dockerfile +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/LICENSE.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/Makefile +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/README.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/.vitepress/config.mjs +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/.vitepress/theme/custom.css +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/.vitepress/theme/index.js +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/commands/example-uris.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/commands/ingest.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/getting-started/core-concepts.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/getting-started/incremental-loading.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/getting-started/quickstart.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/getting-started/telemetry.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/index.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/applovin_max.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/athena.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/clickhouse_img.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/clickup_ingestion.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/cratedb-destination.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/cratedb-source.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/freshdesk_ingestion.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/gcp_spanner_ingestion.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/github.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/google_analytics_realtime_report.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/googleanalytics.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/ingestion_elasticsearch_img.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/kinesis.bigquery.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/linear.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/linkedin_ads.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/mixpanel_ingestion.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/personio.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/personio_duckdb.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/phantombuster.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/pipedrive.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/quickbook_ingestion.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/sftp.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/stripe_postgres.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/tiktok.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/media/zoom_ingestion.png +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/adjust.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/airtable.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/applovin.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/applovin_max.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/appsflyer.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/appstore.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/asana.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/athena.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/attio.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/bigquery.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/chess.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/clickhouse.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/clickup.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/cratedb.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/csv.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/custom_queries.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/databricks.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/db2.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/duckdb.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/dynamodb.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/elasticsearch.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/frankfurter.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/freshdesk.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/gcs.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/github.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/google-ads.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/google_analytics.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/gorgias.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/gsheets.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/hubspot.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/influxdb.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/isoc-pulse.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/kafka.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/kinesis.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/klaviyo.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/linear.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/linkedin_ads.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/mixpanel.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/mongodb.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/motherduck.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/mssql.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/mysql.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/notion.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/oracle.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/personio.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/phantombuster.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/pinterest.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/pipedrive.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/postgres.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/quickbooks.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/redshift.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/s3.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/salesforce.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/sap-hana.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/sftp.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/shopify.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/slack.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/smartsheets.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/snowflake.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/solidgate.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/spanner.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/sqlite.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/stripe.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/tiktok-ads.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/trustpilot.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/zendesk.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/supported-sources/zoom.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/tutorials/load-kinesis-bigquery.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/tutorials/load-personio-duckdb.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/docs/tutorials/load-stripe-postgres.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/conftest.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/main.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/.gitignore +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/adjust/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/adjust/adjust_helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/airtable/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/applovin/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/applovin_max/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/appsflyer/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/appsflyer/client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/appstore/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/appstore/client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/appstore/errors.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/appstore/models.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/appstore/resources.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/arrow/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/asana_source/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/asana_source/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/asana_source/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/attio/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/attio/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/blob.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/chess/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/chess/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/chess/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/clickup/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/clickup/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/collector/spinner.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/destinations.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/dynamodb/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/elasticsearch/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/errors.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/facebook_ads/exceptions.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/facebook_ads/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/facebook_ads/utils.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/factory.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/filesystem/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/filesystem/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/filesystem/readers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/filters.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/frankfurter/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/frankfurter/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/freshdesk/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/freshdesk/freshdesk_client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/freshdesk/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/github/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/github/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/github/queries.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/github/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_ads/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_ads/field.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_ads/metrics.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_ads/predicates.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_ads/reports.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_analytics/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_analytics/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_sheets/README.md +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_sheets/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/gorgias/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/gorgias/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/http_client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/hubspot/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/hubspot/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/hubspot/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/influxdb/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/influxdb/client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/isoc_pulse/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/kafka/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/kafka/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/kinesis/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/kinesis/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/klaviyo/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/klaviyo/client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/klaviyo/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/linkedin_ads/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/linkedin_ads/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/loader.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/mixpanel/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/mixpanel/client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/mongodb/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/mongodb/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/notion/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/notion/helpers/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/notion/helpers/client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/notion/helpers/database.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/notion/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/partition.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/personio/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/personio/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/phantombuster/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/phantombuster/client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/pinterest/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/pipedrive/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/pipedrive/helpers/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/pipedrive/helpers/custom_fields_munger.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/pipedrive/helpers/pages.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/pipedrive/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/pipedrive/typing.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/quickbooks/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/resource.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/salesforce/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/salesforce/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/shopify/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/shopify/exceptions.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/shopify/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/shopify/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/slack/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/slack/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/slack/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/smartsheets/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/solidgate/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/solidgate/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/sql_database/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/sql_database/callbacks.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/stripe_analytics/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/stripe_analytics/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/stripe_analytics/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/table_definition.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/telemetry/event.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/testdata/fakebqcredentials.json +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/tiktok_ads/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/time.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/trustpilot/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/trustpilot/client.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/version.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/zendesk/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/zendesk/helpers/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/zendesk/helpers/credentials.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/zendesk/settings.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/zoom/__init__.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/src/zoom/helpers.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/testdata/.gitignore +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/testdata/create_replace.csv +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/testdata/delete_insert_expected.csv +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/testdata/delete_insert_part1.csv +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/testdata/delete_insert_part2.csv +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/testdata/merge_expected.csv +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/testdata/merge_part1.csv +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/testdata/merge_part2.csv +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/ingestr/tests/unit/test_smartsheets.py +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/package-lock.json +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/package.json +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/pyproject.toml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/requirements-dev.txt +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/requirements.in +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/requirements.txt +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/requirements_arm64.txt +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/resources/demo.gif +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/resources/demo.tape +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/resources/ingestr.svg +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/AMPM.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Acronyms.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Colons.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Contractions.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/DateFormat.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Ellipses.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/EmDash.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Exclamation.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/FirstPerson.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Gender.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/GenderBias.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/HeadingPunctuation.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Headings.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Latin.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/LyHyphens.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/OptionalPlurals.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Ordinal.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/OxfordComma.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Parens.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Passive.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Periods.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Quotes.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Ranges.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Semicolons.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Slang.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Spacing.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Spelling.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Units.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/We.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/Will.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/WordList.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/meta.json +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/Google/vocab.txt +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/bruin/Ingestr.yml +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/styles/config/vocabularies/bruin/accept.txt +0 -0
- {ingestr-0.13.80 → ingestr-0.13.81}/test.env.template +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ingestr
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.81
|
|
4
4
|
Summary: ingestr is a command-line application that ingests data from various sources and stores them in any database.
|
|
5
5
|
Project-URL: Homepage, https://github.com/bruin-data/ingestr
|
|
6
6
|
Project-URL: Issues, https://github.com/bruin-data/ingestr/issues
|
|
@@ -160,13 +160,19 @@ The `facebook_insights` table supports advanced configuration for breakdowns and
|
|
|
160
160
|
1. **Default usage**: `facebook_insights`
|
|
161
161
|
- Uses default breakdown and default fields
|
|
162
162
|
|
|
163
|
-
2. **
|
|
164
|
-
- Uses specified breakdown with default fields
|
|
163
|
+
2. **Predefined breakdown**: `facebook_insights:breakdown_type`
|
|
164
|
+
- Uses specified predefined breakdown with default fields
|
|
165
165
|
|
|
166
|
-
3. **
|
|
167
|
-
- Uses specified breakdown with custom metrics
|
|
166
|
+
3. **Predefined breakdown + custom metrics**: `facebook_insights:breakdown_type:metric1,metric2,metric3`
|
|
167
|
+
- Uses specified predefined breakdown with custom metrics
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
4. **Custom dimensions + metrics**: `facebook_insights:dimension1,dimension2:metric1,metric2,metric3`
|
|
170
|
+
- Uses custom dimensions with custom metrics
|
|
171
|
+
|
|
172
|
+
5. **Level + dimensions + metrics**: `facebook_insights:level,dimension1,dimension2:metric1,metric2,metric3`
|
|
173
|
+
- Uses specified level with custom dimensions and metrics
|
|
174
|
+
|
|
175
|
+
#### Available Predefined Breakdown Types
|
|
170
176
|
|
|
171
177
|
- `ads_insights` (default)
|
|
172
178
|
- `ads_insights_age_and_gender`
|
|
@@ -176,6 +182,30 @@ The `facebook_insights` table supports advanced configuration for breakdowns and
|
|
|
176
182
|
- `ads_insights_dma`
|
|
177
183
|
- `ads_insights_hourly_advertiser`
|
|
178
184
|
|
|
185
|
+
#### Available Levels
|
|
186
|
+
|
|
187
|
+
When using custom dimensions, you can specify one of these levels:
|
|
188
|
+
- `account` - Account level insights
|
|
189
|
+
- `campaign` - Campaign level insights
|
|
190
|
+
- `adset` - Ad set level insights
|
|
191
|
+
- `ad` - Ad level insights
|
|
192
|
+
|
|
193
|
+
Note: If multiple levels are specified in the dimensions list, the last valid level will be used and removed from the dimensions list.
|
|
194
|
+
|
|
195
|
+
#### Common Dimensions
|
|
196
|
+
|
|
197
|
+
You can use any valid Facebook Ads dimension in your custom configurations. Some commonly used dimensions include:
|
|
198
|
+
- `age` - Age ranges
|
|
199
|
+
- `gender` - Gender breakdown
|
|
200
|
+
- `country` - Country breakdown
|
|
201
|
+
- `region` - Region breakdown
|
|
202
|
+
- `platform_position` - Platform position
|
|
203
|
+
- `publisher_platform` - Publisher platform
|
|
204
|
+
- `impression_device` - Device type
|
|
205
|
+
- `placement` - Ad placement
|
|
206
|
+
|
|
207
|
+
Note: Not all dimension combinations are valid according to Facebook's API. Refer to [Facebook's Marketing API](https://developers.facebook.com/docs/marketing-api/insights/breakdowns/) documentation for valid dimension combinations.
|
|
208
|
+
|
|
179
209
|
#### Examples
|
|
180
210
|
|
|
181
211
|
```sh
|
|
@@ -199,4 +229,32 @@ ingestr ingest \
|
|
|
199
229
|
--source-table 'facebook_insights:ads_insights_country:impressions,clicks,spend,reach,cpm,ctr' \
|
|
200
230
|
--dest-uri 'duckdb:///facebook.duckdb' \
|
|
201
231
|
--dest-table 'dest.insights_by_country'
|
|
232
|
+
|
|
233
|
+
# Custom dimensions (age and gender) with custom metrics
|
|
234
|
+
ingestr ingest \
|
|
235
|
+
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
|
|
236
|
+
--source-table 'facebook_insights:age,gender:impressions,clicks,spend' \
|
|
237
|
+
--dest-uri 'duckdb:///facebook.duckdb' \
|
|
238
|
+
--dest-table 'dest.insights_custom_dimensions'
|
|
239
|
+
|
|
240
|
+
# Campaign level with custom dimensions and metrics
|
|
241
|
+
ingestr ingest \
|
|
242
|
+
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
|
|
243
|
+
--source-table 'facebook_insights:campaign,age,gender:impressions,clicks,spend,reach' \
|
|
244
|
+
--dest-uri 'duckdb:///facebook.duckdb' \
|
|
245
|
+
--dest-table 'dest.campaign_insights_demographics'
|
|
246
|
+
|
|
247
|
+
# Ad level with geographic dimensions
|
|
248
|
+
ingestr ingest \
|
|
249
|
+
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
|
|
250
|
+
--source-table 'facebook_insights:ad,country,region:clicks,impressions,spend' \
|
|
251
|
+
--dest-uri 'duckdb:///facebook.duckdb' \
|
|
252
|
+
--dest-table 'dest.ad_insights_geographic'
|
|
253
|
+
|
|
254
|
+
# Account level insights only (no additional dimensions)
|
|
255
|
+
ingestr ingest \
|
|
256
|
+
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
|
|
257
|
+
--source-table 'facebook_insights:account:impressions,clicks,spend,reach' \
|
|
258
|
+
--dest-uri 'duckdb:///facebook.duckdb' \
|
|
259
|
+
--dest-table 'dest.account_level_insights'
|
|
202
260
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "v0.13.81"
|
|
@@ -22,12 +22,8 @@ from .settings import (
|
|
|
22
22
|
DEFAULT_ADCREATIVE_FIELDS,
|
|
23
23
|
DEFAULT_ADSET_FIELDS,
|
|
24
24
|
DEFAULT_CAMPAIGN_FIELDS,
|
|
25
|
-
DEFAULT_INSIGHT_FIELDS,
|
|
26
25
|
DEFAULT_LEAD_FIELDS,
|
|
27
26
|
INSIGHT_FIELDS_TYPES,
|
|
28
|
-
INSIGHTS_BREAKDOWNS_OPTIONS,
|
|
29
|
-
INVALID_INSIGHTS_FIELDS,
|
|
30
|
-
TInsightsBreakdownOptions,
|
|
31
27
|
TInsightsLevels,
|
|
32
28
|
)
|
|
33
29
|
|
|
@@ -105,10 +101,9 @@ def facebook_insights_source(
|
|
|
105
101
|
account_id: str = dlt.config.value,
|
|
106
102
|
access_token: str = dlt.secrets.value,
|
|
107
103
|
initial_load_past_days: int = 1,
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
dimensions: Sequence[str] = None,
|
|
105
|
+
fields: Sequence[str] = None,
|
|
110
106
|
time_increment_days: int = 1,
|
|
111
|
-
breakdowns: TInsightsBreakdownOptions = "ads_insights",
|
|
112
107
|
action_breakdowns: Sequence[str] = ALL_ACTION_BREAKDOWNS,
|
|
113
108
|
level: TInsightsLevels = "ad",
|
|
114
109
|
action_attribution_windows: Sequence[str] = ALL_ACTION_ATTRIBUTION_WINDOWS,
|
|
@@ -155,6 +150,11 @@ def facebook_insights_source(
|
|
|
155
150
|
if start_date is None:
|
|
156
151
|
start_date = pendulum.today().subtract(days=initial_load_past_days)
|
|
157
152
|
|
|
153
|
+
if dimensions is None:
|
|
154
|
+
dimensions = []
|
|
155
|
+
if fields is None:
|
|
156
|
+
fields = []
|
|
157
|
+
|
|
158
158
|
columns = {}
|
|
159
159
|
for field in fields:
|
|
160
160
|
if field in INSIGHT_FIELDS_TYPES:
|
|
@@ -187,15 +187,9 @@ def facebook_insights_source(
|
|
|
187
187
|
query = {
|
|
188
188
|
"level": level,
|
|
189
189
|
"action_breakdowns": list(action_breakdowns),
|
|
190
|
-
"breakdowns":
|
|
191
|
-
INSIGHTS_BREAKDOWNS_OPTIONS[breakdowns]["breakdowns"]
|
|
192
|
-
),
|
|
190
|
+
"breakdowns": dimensions,
|
|
193
191
|
"limit": batch_size,
|
|
194
|
-
"fields":
|
|
195
|
-
set(fields)
|
|
196
|
-
.union(INSIGHTS_BREAKDOWNS_OPTIONS[breakdowns]["fields"])
|
|
197
|
-
.difference(INVALID_INSIGHTS_FIELDS)
|
|
198
|
-
),
|
|
192
|
+
"fields": fields,
|
|
199
193
|
"time_increment": time_increment_days,
|
|
200
194
|
"action_attribution_windows": list(action_attribution_windows),
|
|
201
195
|
"time_ranges": [
|
|
@@ -229,3 +229,49 @@ def notify_on_token_expiration(access_token_expires_at: int = None) -> None:
|
|
|
229
229
|
logger.error(
|
|
230
230
|
f"Access Token expires in {humanize.precisedelta(pendulum.now() - expires_at)}. Replace the token now!"
|
|
231
231
|
)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def parse_insights_table_to_source_kwargs(table: str) -> DictStrAny:
|
|
235
|
+
import typing
|
|
236
|
+
|
|
237
|
+
from ingestr.src.facebook_ads.settings import (
|
|
238
|
+
INSIGHTS_BREAKDOWNS_OPTIONS,
|
|
239
|
+
TInsightsBreakdownOptions,
|
|
240
|
+
TInsightsLevels,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
parts = table.split(":")
|
|
244
|
+
|
|
245
|
+
source_kwargs = {}
|
|
246
|
+
|
|
247
|
+
breakdown_type = parts[1]
|
|
248
|
+
|
|
249
|
+
valid_breakdowns = list(typing.get_args(TInsightsBreakdownOptions))
|
|
250
|
+
if breakdown_type in valid_breakdowns:
|
|
251
|
+
dimensions = INSIGHTS_BREAKDOWNS_OPTIONS[breakdown_type]["breakdowns"]
|
|
252
|
+
fields = INSIGHTS_BREAKDOWNS_OPTIONS[breakdown_type]["fields"]
|
|
253
|
+
source_kwargs["dimensions"] = dimensions
|
|
254
|
+
source_kwargs["fields"] = fields
|
|
255
|
+
else:
|
|
256
|
+
dimensions = breakdown_type.split(",")
|
|
257
|
+
valid_levels = list(typing.get_args(TInsightsLevels))
|
|
258
|
+
level = None
|
|
259
|
+
for valid_level in reversed(valid_levels):
|
|
260
|
+
if valid_level in dimensions:
|
|
261
|
+
level = valid_level
|
|
262
|
+
dimensions.remove(valid_level)
|
|
263
|
+
break
|
|
264
|
+
|
|
265
|
+
source_kwargs["level"] = level
|
|
266
|
+
source_kwargs["dimensions"] = dimensions
|
|
267
|
+
|
|
268
|
+
# If custom metrics are provided, parse them
|
|
269
|
+
if len(parts) == 3:
|
|
270
|
+
fields = [f.strip() for f in parts[2].split(",") if f.strip()]
|
|
271
|
+
if not fields:
|
|
272
|
+
raise ValueError(
|
|
273
|
+
"Custom metrics must be provided after the second colon in format: facebook_insights:breakdown_type:metric1,metric2..."
|
|
274
|
+
)
|
|
275
|
+
source_kwargs["fields"] = fields
|
|
276
|
+
|
|
277
|
+
return source_kwargs
|
|
@@ -17,9 +17,10 @@ def _get_date_range(updated_at, start_date):
|
|
|
17
17
|
current_end_date = pendulum.parse(updated_at.end_value)
|
|
18
18
|
else:
|
|
19
19
|
current_end_date = pendulum.now(tz="UTC")
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
return current_start_date, current_end_date
|
|
22
22
|
|
|
23
|
+
|
|
23
24
|
ISSUES_QUERY = """
|
|
24
25
|
query Issues($cursor: String) {
|
|
25
26
|
issues(first: 50, after: $cursor) {
|
|
@@ -119,6 +120,7 @@ query WorkflowStates($cursor: String) {
|
|
|
119
120
|
}
|
|
120
121
|
"""
|
|
121
122
|
|
|
123
|
+
|
|
122
124
|
@dlt.source(name="linear", max_table_nesting=0)
|
|
123
125
|
def linear_source(
|
|
124
126
|
api_key: str,
|
|
@@ -211,5 +213,5 @@ def linear_source(
|
|
|
211
213
|
if pendulum.parse(item["updatedAt"]) >= current_start_date:
|
|
212
214
|
if pendulum.parse(item["updatedAt"]) <= current_end_date:
|
|
213
215
|
yield normalize_dictionaries(item)
|
|
214
|
-
return [issues, projects, teams, users, workflow_states]
|
|
215
216
|
|
|
217
|
+
return [issues, projects, teams, users, workflow_states]
|
|
@@ -32,8 +32,6 @@ def _paginate(api_key: str, query: str, root: str) -> Iterator[Dict[str, Any]]:
|
|
|
32
32
|
cursor = data["pageInfo"]["endCursor"]
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
35
|
def normalize_dictionaries(item: Dict[str, Any]) -> Dict[str, Any]:
|
|
38
36
|
"""
|
|
39
37
|
Automatically normalize dictionary fields by detecting their structure:
|
|
@@ -41,15 +39,15 @@ def normalize_dictionaries(item: Dict[str, Any]) -> Dict[str, Any]:
|
|
|
41
39
|
- Convert objects with 'nodes' field to arrays
|
|
42
40
|
"""
|
|
43
41
|
normalized_item = item.copy()
|
|
44
|
-
|
|
42
|
+
|
|
45
43
|
for key, value in list(normalized_item.items()):
|
|
46
44
|
if isinstance(value, dict):
|
|
47
45
|
# If the dict has an 'id' field, replace with {key}_id
|
|
48
|
-
if
|
|
49
|
-
normalized_item[f"{key}_id"] = value[
|
|
46
|
+
if "id" in value:
|
|
47
|
+
normalized_item[f"{key}_id"] = value["id"]
|
|
50
48
|
del normalized_item[key]
|
|
51
49
|
# If the dict has 'nodes' field, extract the nodes array
|
|
52
|
-
elif
|
|
53
|
-
normalized_item[key] = value[
|
|
54
|
-
|
|
50
|
+
elif "nodes" in value:
|
|
51
|
+
normalized_item[key] = value["nodes"]
|
|
52
|
+
|
|
55
53
|
return normalized_item
|
|
@@ -1056,33 +1056,16 @@ class FacebookAdsSource:
|
|
|
1056
1056
|
# Validate breakdown type against available options from settings
|
|
1057
1057
|
import typing
|
|
1058
1058
|
|
|
1059
|
-
from ingestr.src.facebook_ads.
|
|
1060
|
-
|
|
1061
|
-
# Get valid breakdown options from the type definition
|
|
1062
|
-
valid_breakdowns = list(typing.get_args(TInsightsBreakdownOptions))
|
|
1063
|
-
|
|
1064
|
-
if breakdown_type not in valid_breakdowns:
|
|
1065
|
-
raise ValueError(
|
|
1066
|
-
f"Invalid breakdown type '{breakdown_type}'. Valid options: {', '.join(valid_breakdowns)}"
|
|
1067
|
-
)
|
|
1059
|
+
from ingestr.src.facebook_ads.helpers import parse_insights_table_to_source_kwargs
|
|
1068
1060
|
|
|
1069
1061
|
source_kwargs = {
|
|
1070
1062
|
"access_token": access_token[0],
|
|
1071
1063
|
"account_id": account_id[0],
|
|
1072
1064
|
"start_date": kwargs.get("interval_start"),
|
|
1073
1065
|
"end_date": kwargs.get("interval_end"),
|
|
1074
|
-
"breakdowns": breakdown_type,
|
|
1075
1066
|
}
|
|
1076
1067
|
|
|
1077
|
-
|
|
1078
|
-
if len(parts) == 3:
|
|
1079
|
-
fields = [f.strip() for f in parts[2].split(",") if f.strip()]
|
|
1080
|
-
if not fields:
|
|
1081
|
-
raise ValueError(
|
|
1082
|
-
"Custom metrics must be provided after the second colon in format: facebook_insights:breakdown_type:metric1,metric2..."
|
|
1083
|
-
)
|
|
1084
|
-
source_kwargs["fields"] = fields
|
|
1085
|
-
|
|
1068
|
+
source_kwargs.update(parse_insights_table_to_source_kwargs(table))
|
|
1086
1069
|
return facebook_insights_source(**source_kwargs).with_resources(
|
|
1087
1070
|
"facebook_insights"
|
|
1088
1071
|
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version = "v0.13.80"
|
|
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
|
|
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
|