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