ingestr 0.14.4__tar.gz → 0.14.6__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.14.4 → ingestr-0.14.6}/PKG-INFO +1 -1
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/.vitepress/config.mjs +10 -9
- ingestr-0.14.6/docs/supported-sources/http.md +111 -0
- ingestr-0.14.6/docs/supported-sources/monday.md +59 -0
- ingestr-0.14.6/docs/supported-sources/plusvibeai.md +93 -0
- ingestr-0.14.6/ingestr/src/buildinfo.py +1 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/factory.py +7 -0
- ingestr-0.14.6/ingestr/src/http/__init__.py +35 -0
- ingestr-0.14.6/ingestr/src/http/readers.py +114 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/jira_source/__init__.py +27 -1
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/jira_source/helpers.py +8 -21
- ingestr-0.14.6/ingestr/src/monday/__init__.py +246 -0
- ingestr-0.14.6/ingestr/src/monday/helpers.py +392 -0
- ingestr-0.14.6/ingestr/src/monday/settings.py +328 -0
- ingestr-0.14.6/ingestr/src/plusvibeai/__init__.py +335 -0
- ingestr-0.14.6/ingestr/src/plusvibeai/helpers.py +544 -0
- ingestr-0.14.6/ingestr/src/plusvibeai/settings.py +252 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/sources.py +130 -0
- ingestr-0.14.4/ingestr/src/buildinfo.py +0 -1
- {ingestr-0.14.4 → ingestr-0.14.6}/.dlt/config.toml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.dockerignore +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.githooks/pre-commit-hook.sh +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.github/workflows/deploy-docs.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.github/workflows/release.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.github/workflows/secrets-scan.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.github/workflows/tests.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.gitignore +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.gitleaksignore +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.python-version +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/.vale.ini +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/Dockerfile +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/LICENSE.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/Makefile +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/README.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/.vitepress/theme/custom.css +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/.vitepress/theme/index.js +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/commands/example-uris.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/commands/ingest.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/getting-started/core-concepts.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/getting-started/data-masking.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/getting-started/incremental-loading.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/getting-started/quickstart.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/getting-started/telemetry.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/index.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/applovin_max.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/athena.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/clickhouse_img.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/clickup_ingestion.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/cratedb-destination.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/cratedb-source.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/freshdesk_ingestion.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/gcp_spanner_ingestion.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/github.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/google_analytics_realtime_report.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/googleanalytics.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/ingestion_elasticsearch_img.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/kinesis.bigquery.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/linear.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/linkedin_ads.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/mixpanel_ingestion.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/personio.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/personio_duckdb.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/phantombuster.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/pipedrive.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/quickbook_ingestion.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/sftp.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/stripe_postgres.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/tiktok.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/wise_ingestion.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/media/zoom_ingestion.png +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/public/demo.gif +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/adjust.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/airtable.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/anthropic.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/applovin.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/applovin_max.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/appsflyer.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/appstore.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/asana.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/athena.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/attio.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/bigquery.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/chess.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/clickhouse.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/clickup.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/cratedb.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/csv.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/custom_queries.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/databricks.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/db2.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/docebo.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/duckdb.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/dynamodb.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/elasticsearch.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/facebook-ads.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/fluxx.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/frankfurter.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/freshdesk.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/fundraiseup.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/gcs.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/github.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/google-ads.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/google_analytics.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/gorgias.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/gsheets.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/hubspot.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/influxdb.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/intercom.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/isoc-pulse.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/jira.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/kafka.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/kinesis.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/klaviyo.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/linear.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/linkedin_ads.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/mixpanel.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/mongodb.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/motherduck.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/mssql.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/mysql.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/notion.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/oracle.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/personio.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/phantombuster.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/pinterest.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/pipedrive.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/postgres.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/quickbooks.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/redshift.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/revenuecat.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/s3.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/salesforce.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/sap-hana.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/sftp.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/shopify.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/slack.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/smartsheets.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/snowflake.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/solidgate.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/spanner.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/sqlite.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/stripe.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/tiktok-ads.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/trino.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/trustpilot.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/wise.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/zendesk.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/supported-sources/zoom.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/tutorials/load-kinesis-bigquery.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/tutorials/load-personio-duckdb.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/docs/tutorials/load-stripe-postgres.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/conftest.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/main.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/.gitignore +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/adjust/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/adjust/adjust_helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/airtable/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/anthropic/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/anthropic/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/applovin/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/applovin_max/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/appsflyer/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/appsflyer/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/appstore/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/appstore/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/appstore/errors.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/appstore/models.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/appstore/resources.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/arrow/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/asana_source/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/asana_source/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/asana_source/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/attio/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/attio/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/blob.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/chess/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/chess/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/chess/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/clickup/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/clickup/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/collector/spinner.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/destinations.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/docebo/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/docebo/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/docebo/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/dynamodb/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/elasticsearch/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/elasticsearch/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/errors.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/facebook_ads/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/facebook_ads/exceptions.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/facebook_ads/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/facebook_ads/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/facebook_ads/utils.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/filesystem/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/filesystem/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/filesystem/readers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/filters.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/fluxx/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/fluxx/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/frankfurter/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/frankfurter/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/freshdesk/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/freshdesk/freshdesk_client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/freshdesk/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/fundraiseup/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/fundraiseup/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/github/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/github/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/github/queries.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/github/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_ads/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_ads/field.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_ads/metrics.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_ads/predicates.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_ads/reports.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_analytics/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_analytics/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_sheets/README.md +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_sheets/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/gorgias/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/gorgias/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/http_client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/hubspot/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/hubspot/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/hubspot/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/influxdb/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/influxdb/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/intercom/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/intercom/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/intercom/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/isoc_pulse/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/jira_source/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/kafka/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/kafka/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/kinesis/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/kinesis/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/klaviyo/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/klaviyo/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/klaviyo/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/linear/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/linear/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/linkedin_ads/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/linkedin_ads/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/loader.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/masking.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/mixpanel/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/mixpanel/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/mongodb/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/mongodb/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/notion/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/notion/helpers/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/notion/helpers/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/notion/helpers/database.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/notion/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/partition.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/personio/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/personio/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/phantombuster/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/phantombuster/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/pinterest/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/pipedrive/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/pipedrive/helpers/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/pipedrive/helpers/custom_fields_munger.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/pipedrive/helpers/pages.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/pipedrive/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/pipedrive/typing.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/quickbooks/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/resource.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/revenuecat/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/revenuecat/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/salesforce/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/salesforce/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/shopify/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/shopify/exceptions.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/shopify/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/shopify/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/slack/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/slack/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/slack/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/smartsheets/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/solidgate/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/solidgate/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/sql_database/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/sql_database/callbacks.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/stripe_analytics/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/stripe_analytics/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/stripe_analytics/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/table_definition.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/telemetry/event.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/testdata/fakebqcredentials.json +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/tiktok_ads/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/time.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/trustpilot/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/trustpilot/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/version.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/wise/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/wise/client.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/zendesk/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/zendesk/helpers/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/zendesk/helpers/credentials.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/zendesk/settings.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/zoom/__init__.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/src/zoom/helpers.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/testdata/.gitignore +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/testdata/create_replace.csv +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/testdata/delete_insert_expected.csv +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/testdata/delete_insert_part1.csv +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/testdata/delete_insert_part2.csv +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/testdata/merge_expected.csv +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/testdata/merge_part1.csv +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/testdata/merge_part2.csv +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/ingestr/tests/unit/test_smartsheets.py +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/package-lock.json +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/package.json +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/pyproject.toml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/requirements-dev.txt +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/requirements.in +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/requirements.txt +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/requirements_arm64.txt +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/resources/demo.gif +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/resources/demo.tape +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/resources/ingestr.svg +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/AMPM.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Acronyms.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Colons.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Contractions.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/DateFormat.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Ellipses.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/EmDash.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Exclamation.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/FirstPerson.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Gender.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/GenderBias.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/HeadingPunctuation.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Headings.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Latin.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/LyHyphens.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/OptionalPlurals.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Ordinal.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/OxfordComma.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Parens.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Passive.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Periods.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Quotes.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Ranges.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Semicolons.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Slang.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Spacing.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Spelling.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Units.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/We.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/Will.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/WordList.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/meta.json +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/Google/vocab.txt +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/bruin/Ingestr.yml +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/styles/config/vocabularies/bruin/accept.txt +0 -0
- {ingestr-0.14.4 → ingestr-0.14.6}/test.env.template +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ingestr
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.6
|
|
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
|
|
@@ -19,18 +19,17 @@ export default defineConfig({
|
|
|
19
19
|
head: [
|
|
20
20
|
[
|
|
21
21
|
"script",
|
|
22
|
-
{
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
{},
|
|
23
|
+
`(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
24
|
+
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
25
|
+
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
26
|
+
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
27
|
+
})(window,document,'script','dataLayer','GTM-K2L7S5FP');`,
|
|
26
28
|
],
|
|
27
29
|
[
|
|
28
|
-
"
|
|
30
|
+
"noscript",
|
|
29
31
|
{},
|
|
30
|
-
|
|
31
|
-
function gtag(){dataLayer.push(arguments);}
|
|
32
|
-
gtag('js', new Date());
|
|
33
|
-
gtag('config', 'G-MZJ20PP4MJ');`,
|
|
32
|
+
`<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K2L7S5FP" height="0" width="0" style="display:none;visibility:hidden"></iframe>`,
|
|
34
33
|
],
|
|
35
34
|
],
|
|
36
35
|
themeConfig: {
|
|
@@ -157,11 +156,13 @@ export default defineConfig({
|
|
|
157
156
|
{ text: "Linear", link: "/supported-sources/linear.md" },
|
|
158
157
|
{ text: "LinkedIn Ads", link: "/supported-sources/linkedin_ads.md" },
|
|
159
158
|
{ text: "Mixpanel", link: "/supported-sources/mixpanel.md" },
|
|
159
|
+
{ text: "Monday", link: "/supported-sources/monday.md" },
|
|
160
160
|
{ text: "Notion", link: "/supported-sources/notion.md" },
|
|
161
161
|
{ text: "Personio", link: "/supported-sources/personio.md" },
|
|
162
162
|
{ text: "PhantomBuster", link: "/supported-sources/phantombuster.md" },
|
|
163
163
|
{ text: "Pinterest", link: "/supported-sources/pinterest.md" },
|
|
164
164
|
{ text: "Pipedrive", link: "/supported-sources/pipedrive.md" },
|
|
165
|
+
{ text: "Plus Vibe AI", link: "/supported-sources/plusvibeai.md" },
|
|
165
166
|
{ text: "QuickBooks", link: "/supported-sources/quickbooks.md" },
|
|
166
167
|
{ text: "RevenueCat", link: "/supported-sources/revenuecat.md" },
|
|
167
168
|
{ text: "S3", link: "/supported-sources/s3.md" },
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# HTTP
|
|
2
|
+
|
|
3
|
+
ingestr supports reading CSV, JSON, and Parquet files from public HTTP/HTTPS URLs. This allows you to ingest data from publicly accessible file URLs directly into your databases.
|
|
4
|
+
|
|
5
|
+
## URI format
|
|
6
|
+
|
|
7
|
+
The URI format for HTTP sources is as follows:
|
|
8
|
+
|
|
9
|
+
```plaintext
|
|
10
|
+
http://example.com/path/to/file.csv
|
|
11
|
+
https://example.com/path/to/file.json
|
|
12
|
+
https://example.com/path/to/file.parquet
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Supported file formats
|
|
16
|
+
|
|
17
|
+
The HTTP source supports the following file formats:
|
|
18
|
+
|
|
19
|
+
- **CSV** (`.csv`) - Comma-separated values files
|
|
20
|
+
- **JSON** (`.json`, `.jsonl`) - JSON objects and JSON Lines format
|
|
21
|
+
- **Parquet** (`.parquet`) - Apache Parquet columnar format
|
|
22
|
+
|
|
23
|
+
The file format is automatically inferred from the URL extension. You can also explicitly specify the format using the `file_format` parameter.
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Basic example
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
ingestr ingest \
|
|
31
|
+
--source-uri "https://example.com/data.csv" \
|
|
32
|
+
--dest-uri "duckdb:///local.duckdb" \
|
|
33
|
+
--dest-table "my_table"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Example with Phantombuster CSV
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
ingestr ingest \
|
|
40
|
+
--source-uri "https://phantombuster.s3.amazonaws.com/hNQdB02WKv0/l7xqy7HlU0wyWIvPjqKk5Q/dts_size.csv" \
|
|
41
|
+
--dest-uri "postgres://user:pass@localhost:5432/mydb" \
|
|
42
|
+
--dest-table "phantombuster_data"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Example with JSON file
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
ingestr ingest \
|
|
49
|
+
--source-uri "https://api.example.com/export/data.json" \
|
|
50
|
+
--dest-uri "snowflake://user:pass@account/database/schema" \
|
|
51
|
+
--dest-table "json_data"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Example with Parquet file
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ingestr ingest \
|
|
58
|
+
--source-uri "https://storage.example.com/data.parquet" \
|
|
59
|
+
--dest-uri "bigquery://project/dataset" \
|
|
60
|
+
--dest-table "parquet_data"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Parameters
|
|
64
|
+
|
|
65
|
+
### `file_format`
|
|
66
|
+
|
|
67
|
+
Optional. Explicitly specify the file format if it cannot be inferred from the URL extension.
|
|
68
|
+
|
|
69
|
+
**Valid values:** `csv`, `json`, `parquet`
|
|
70
|
+
|
|
71
|
+
**Example:**
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
ingestr ingest \
|
|
75
|
+
--source-uri "https://example.com/data?format=csv" \
|
|
76
|
+
--source-file-format "csv" \
|
|
77
|
+
--dest-uri "duckdb:///local.duckdb" \
|
|
78
|
+
--dest-table "my_table"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `chunksize`
|
|
82
|
+
|
|
83
|
+
Optional. Number of records to process at once. This helps manage memory usage for large files.
|
|
84
|
+
|
|
85
|
+
**Default values:**
|
|
86
|
+
- CSV: 10,000 rows
|
|
87
|
+
- JSON: 1,000 objects
|
|
88
|
+
- Parquet: 10,000 rows
|
|
89
|
+
|
|
90
|
+
**Example:**
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
ingestr ingest \
|
|
94
|
+
--source-uri "https://example.com/large-file.csv" \
|
|
95
|
+
--source-chunksize 5000 \
|
|
96
|
+
--dest-uri "postgres://user:pass@localhost:5432/mydb" \
|
|
97
|
+
--dest-table "chunked_data"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Notes
|
|
101
|
+
|
|
102
|
+
- The HTTP source downloads the entire file before processing, so ensure you have sufficient memory for large files
|
|
103
|
+
- Authentication is not currently supported; only publicly accessible URLs can be used
|
|
104
|
+
- The file must be accessible without requiring cookies, headers, or other authentication mechanisms
|
|
105
|
+
- For very large files, consider using chunked transfer or a dedicated file storage source (e.g., S3, GCS)
|
|
106
|
+
|
|
107
|
+
## Limitations
|
|
108
|
+
|
|
109
|
+
- Only supports public URLs (no authentication)
|
|
110
|
+
- The entire file is downloaded into memory before processing
|
|
111
|
+
- No support for incremental loading
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Monday.com
|
|
2
|
+
[Monday.com](https://monday.com/) is a Work OS that powers teams to run projects and workflows with confidence. It's a simple, yet powerful platform that enables people to manage work, meet deadlines, and build a culture of transparency.
|
|
3
|
+
|
|
4
|
+
## URI format
|
|
5
|
+
|
|
6
|
+
The URI format for Monday.com is as follows:
|
|
7
|
+
```
|
|
8
|
+
monday://?api_token=<api_token>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
URI parameters:
|
|
12
|
+
- `api_token` is your Monday.com API token for authentication.
|
|
13
|
+
|
|
14
|
+
## Setting up a Monday.com Integration
|
|
15
|
+
|
|
16
|
+
You can obtain an API token from the [Monday.com Developer Console](https://developer.monday.com/). For more information, see [Monday.com authentication documentation](https://developer.monday.com/api-reference/docs/authentication).
|
|
17
|
+
|
|
18
|
+
To get your API token:
|
|
19
|
+
1. Go to your Monday.com account
|
|
20
|
+
2. Click on your profile picture in the top right corner
|
|
21
|
+
3. Select "Admin" → "API"
|
|
22
|
+
4. Generate a new API token
|
|
23
|
+
|
|
24
|
+
## Example
|
|
25
|
+
Let's say you want to ingest all boards into a DuckDB database called `monday.db`. For this example the value of `api_token` will be `fake_token`.
|
|
26
|
+
|
|
27
|
+
You can run the following to achieve this:
|
|
28
|
+
```sh
|
|
29
|
+
ingestr ingest \
|
|
30
|
+
--source-uri "monday://?api_token=fake_token" \
|
|
31
|
+
--source-table "boards" \
|
|
32
|
+
--dest-uri "duckdb://./monday.db" \
|
|
33
|
+
--dest-table "public.boards"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Tables
|
|
37
|
+
|
|
38
|
+
Monday.com source allows ingesting the following resources into separate tables:
|
|
39
|
+
|
|
40
|
+
| Table | Primary/Merge Key | Inc Key | Inc Strategy | Details |
|
|
41
|
+
|-------|-------------------|---------|--------------|---------|
|
|
42
|
+
| `account` | - | - | replace | Account information including name, slug, tier, and plan details. Full reload on each run. |
|
|
43
|
+
| `account_roles` | - | - | replace | Account roles with their types and permissions. Full reload on each run. |
|
|
44
|
+
| `users` | - | - | replace | Users in your Monday.com account with their profiles and permissions. Full reload on each run. |
|
|
45
|
+
| `boards` | id | updated_at | merge | Boards with their metadata, state, and configuration. Incrementally loads only updated boards. |
|
|
46
|
+
| `workspaces` | - | - | replace | Workspaces containing boards and their settings. Full reload on each run. |
|
|
47
|
+
| `webhooks` | - | - | replace | Webhooks configured for boards with their events and configurations. Full reload on each run. |
|
|
48
|
+
| `updates` | id | updated_at | merge | Updates (comments) on items with their content and metadata. Incrementally loads only updated entries. |
|
|
49
|
+
| `teams` | - | - | replace | Teams in your account with their members. Full reload on each run. |
|
|
50
|
+
| `tags` | - | - | replace | Tags used across your account for organizing items. Full reload on each run. |
|
|
51
|
+
| `custom_activities` | - | - | replace | Custom activity types defined in your account. Full reload on each run. |
|
|
52
|
+
| `board_columns` | - | - | replace | Columns defined in all boards with their types and settings. Full reload on each run. |
|
|
53
|
+
| `board_views` | - | - | replace | Views configured for boards with their filters and settings. Full reload on each run. |
|
|
54
|
+
|
|
55
|
+
Use these as `--source-table` parameter in the `ingestr ingest` command.
|
|
56
|
+
|
|
57
|
+
> [!NOTE]
|
|
58
|
+
> Monday.com has rate limits for API requests. The source handles pagination automatically and respects the API's maximum page size of 100 items.
|
|
59
|
+
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Plus Vibe AI
|
|
2
|
+
|
|
3
|
+
[Plus Vibe AI](https://plusvibe.ai/) is an email marketing and outreach platform that helps businesses automate their email campaigns, manage leads, and track engagement metrics.
|
|
4
|
+
|
|
5
|
+
ingestr supports Plus Vibe AI as a source.
|
|
6
|
+
|
|
7
|
+
## URI format
|
|
8
|
+
|
|
9
|
+
The URI format for Plus Vibe AI is as follows:
|
|
10
|
+
|
|
11
|
+
```plaintext
|
|
12
|
+
plusvibeai://?api_key=<api-key-here>&workspace_id=<workspace-id-here>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
URI parameters:
|
|
16
|
+
|
|
17
|
+
- `api_key`: API key for authentication (get from https://app.plusvibe.ai/v2/settings/api-access/)
|
|
18
|
+
- `workspace_id`: Workspace ID to access your data
|
|
19
|
+
|
|
20
|
+
The URI is used to connect to the Plus Vibe AI API for extracting data.
|
|
21
|
+
|
|
22
|
+
## Setting up a Plus Vibe AI Integration
|
|
23
|
+
|
|
24
|
+
To set up a Plus Vibe AI integration, you need to:
|
|
25
|
+
|
|
26
|
+
1. Log in to your Plus Vibe AI account
|
|
27
|
+
2. Navigate to Settings > API Access (https://app.plusvibe.ai/v2/settings/api-access/)
|
|
28
|
+
3. Generate an API key
|
|
29
|
+
4. Find your workspace ID in your account settings
|
|
30
|
+
|
|
31
|
+
Once you have your API key and workspace ID, here's a sample command that will copy the data from Plus Vibe AI into a DuckDB database:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
ingestr ingest --source-uri 'plusvibeai://?api_key=your_api_key&workspace_id=your_workspace_id' --source-table 'campaigns' --dest-uri duckdb:///plusvibeai.duckdb --dest-table 'campaigns.data'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The result of this command will be a table in the `plusvibeai.duckdb` database with JSON columns for nested objects.
|
|
38
|
+
|
|
39
|
+
## Tables
|
|
40
|
+
|
|
41
|
+
Plus Vibe AI source allows ingesting the following sources into separate tables:
|
|
42
|
+
|
|
43
|
+
| Table | PK | Inc Key | Inc Strategy | Details |
|
|
44
|
+
| ----- | -- | ------- | ------------ | ------- |
|
|
45
|
+
| `campaigns` | id | modified_at | merge | Contains campaign information including configuration, schedules, sequences, and performance metrics. Nested objects (schedule, sequences) are stored as JSON columns. |
|
|
46
|
+
| `leads` | _id | modified_at | merge | Contains lead information including contact details, campaign association, engagement metrics, and professional information. |
|
|
47
|
+
| `email_accounts` | _id | timestamp_updated | merge | Contains email account configurations including SMTP/IMAP settings, warmup configurations, and analytics data stored in payload JSON. |
|
|
48
|
+
| `emails` | id | timestamp_created | merge | Contains email data including message content, headers, thread information, and recipient details. Uses cursor-based pagination. |
|
|
49
|
+
| `blocklist` | _id | created_at | merge | Contains blocklist entries for email addresses or domains that should be excluded from campaigns. |
|
|
50
|
+
| `webhooks` | _id | modified_at | merge | Contains webhook configurations for receiving real-time notifications about campaign events and lead interactions. |
|
|
51
|
+
| `tags` | _id | modified_at | merge | Contains tag information used for organizing and categorizing campaigns, leads, and other resources. |
|
|
52
|
+
|
|
53
|
+
Use these as `--source-table` parameter in the `ingestr ingest` command.
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
### Incremental Loading
|
|
58
|
+
|
|
59
|
+
Plus Vibe AI source supports incremental loading based on modification timestamps. Each table uses its respective timestamp field to fetch only updated records since the last sync:
|
|
60
|
+
|
|
61
|
+
- **Campaigns**: Uses `modified_at` field
|
|
62
|
+
- **Leads**: Uses `modified_at` field
|
|
63
|
+
- **Email Accounts**: Uses `timestamp_updated` field
|
|
64
|
+
- **Emails**: Uses `timestamp_created` field
|
|
65
|
+
- **Blocklist**: Uses `created_at` field
|
|
66
|
+
- **Webhooks**: Uses `modified_at` field
|
|
67
|
+
- **Tags**: Uses `modified_at` field
|
|
68
|
+
|
|
69
|
+
### Nested Data Handling
|
|
70
|
+
|
|
71
|
+
The source preserves nested objects as JSON columns with `max_table_nesting=0` to maintain data structure integrity:
|
|
72
|
+
|
|
73
|
+
- **Campaigns**: Schedule, sequences, and events are stored as JSON
|
|
74
|
+
- **Email Accounts**: All configuration data is stored in the `payload` JSON field
|
|
75
|
+
- **Emails**: Headers and address information are stored as JSON
|
|
76
|
+
|
|
77
|
+
### Rate Limiting
|
|
78
|
+
|
|
79
|
+
Plus Vibe AI API has a rate limit of 5 requests per second. The source automatically handles rate limiting with exponential backoff and retry logic.
|
|
80
|
+
|
|
81
|
+
### Error Handling
|
|
82
|
+
|
|
83
|
+
The source includes comprehensive error handling for:
|
|
84
|
+
- Authentication failures (401/403)
|
|
85
|
+
- Rate limiting (429)
|
|
86
|
+
- Server errors (5xx) with automatic retries
|
|
87
|
+
- Network timeouts and connection issues
|
|
88
|
+
|
|
89
|
+
> [!TIP]
|
|
90
|
+
> For optimal performance, use incremental loading for regular syncs and full loading only for initial data extraction or when you need to capture all historical updates.
|
|
91
|
+
|
|
92
|
+
> [!NOTE]
|
|
93
|
+
> The emails endpoint uses cursor-based pagination with `page_trail` parameter, while other endpoints use standard offset-based pagination.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "v0.14.6"
|
|
@@ -52,6 +52,7 @@ from ingestr.src.sources import (
|
|
|
52
52
|
GoogleAnalyticsSource,
|
|
53
53
|
GoogleSheetsSource,
|
|
54
54
|
GorgiasSource,
|
|
55
|
+
HttpSource,
|
|
55
56
|
HubspotSource,
|
|
56
57
|
InfluxDBSource,
|
|
57
58
|
IntercomSource,
|
|
@@ -64,12 +65,14 @@ from ingestr.src.sources import (
|
|
|
64
65
|
LinkedInAdsSource,
|
|
65
66
|
LocalCsvSource,
|
|
66
67
|
MixpanelSource,
|
|
68
|
+
MondaySource,
|
|
67
69
|
MongoDbSource,
|
|
68
70
|
NotionSource,
|
|
69
71
|
PersonioSource,
|
|
70
72
|
PhantombusterSource,
|
|
71
73
|
PinterestSource,
|
|
72
74
|
PipedriveSource,
|
|
75
|
+
PlusVibeAISource,
|
|
73
76
|
QuickBooksSource,
|
|
74
77
|
RevenueCatSource,
|
|
75
78
|
S3Source,
|
|
@@ -155,6 +158,8 @@ class SourceDestinationFactory:
|
|
|
155
158
|
"anthropic": AnthropicSource,
|
|
156
159
|
"csv": LocalCsvSource,
|
|
157
160
|
"docebo": DoceboSource,
|
|
161
|
+
"http": HttpSource,
|
|
162
|
+
"https": HttpSource,
|
|
158
163
|
"mongodb": MongoDbSource,
|
|
159
164
|
"mongodb+srv": MongoDbSource,
|
|
160
165
|
"notion": NotionSource,
|
|
@@ -212,6 +217,8 @@ class SourceDestinationFactory:
|
|
|
212
217
|
"clickup": ClickupSource,
|
|
213
218
|
"influxdb": InfluxDBSource,
|
|
214
219
|
"wise": WiseSource,
|
|
220
|
+
"plusvibeai": PlusVibeAISource,
|
|
221
|
+
"monday": MondaySource,
|
|
215
222
|
}
|
|
216
223
|
destinations: Dict[str, Type[DestinationProtocol]] = {
|
|
217
224
|
"bigquery": BigQueryDestination,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""HTTP source for reading CSV, JSON, and Parquet files from public URLs"""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
import dlt
|
|
6
|
+
from dlt.sources import DltResource
|
|
7
|
+
|
|
8
|
+
from .readers import HttpReader
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dlt.source
|
|
12
|
+
def http_source(
|
|
13
|
+
url: str,
|
|
14
|
+
file_format: Optional[str] = None,
|
|
15
|
+
**kwargs: Any,
|
|
16
|
+
) -> DltResource:
|
|
17
|
+
"""Source for reading files from HTTP URLs.
|
|
18
|
+
|
|
19
|
+
Supports CSV, JSON, and Parquet file formats.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
url (str): The HTTP(S) URL to the file
|
|
23
|
+
file_format (str, optional): File format ('csv', 'json', 'parquet').
|
|
24
|
+
If not provided, will be inferred from URL extension.
|
|
25
|
+
**kwargs: Additional arguments passed to the reader functions
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
DltResource: A dlt resource that yields the file data
|
|
29
|
+
"""
|
|
30
|
+
reader = HttpReader(url, file_format)
|
|
31
|
+
|
|
32
|
+
return dlt.resource(
|
|
33
|
+
reader.read_file(**kwargs),
|
|
34
|
+
name="http_data",
|
|
35
|
+
)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""Readers for HTTP file sources"""
|
|
2
|
+
|
|
3
|
+
import io
|
|
4
|
+
from typing import Any, Iterator, Optional
|
|
5
|
+
from urllib.parse import urlparse
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
from dlt.sources import TDataItems
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class HttpReader:
|
|
12
|
+
"""Reader for HTTP-based file sources"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, url: str, file_format: Optional[str] = None):
|
|
15
|
+
self.url = url
|
|
16
|
+
self.file_format = file_format or self._infer_format(url)
|
|
17
|
+
|
|
18
|
+
if self.file_format not in ["csv", "json", "parquet"]:
|
|
19
|
+
raise ValueError(
|
|
20
|
+
f"Unsupported file format: {self.file_format}. "
|
|
21
|
+
"Supported formats: csv, json, parquet"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def _infer_format(self, url: str) -> str:
|
|
25
|
+
"""Infer file format from URL extension"""
|
|
26
|
+
parsed = urlparse(url)
|
|
27
|
+
path = parsed.path.lower()
|
|
28
|
+
|
|
29
|
+
if path.endswith(".csv"):
|
|
30
|
+
return "csv"
|
|
31
|
+
elif path.endswith(".json") or path.endswith(".jsonl"):
|
|
32
|
+
return "json"
|
|
33
|
+
elif path.endswith(".parquet"):
|
|
34
|
+
return "parquet"
|
|
35
|
+
else:
|
|
36
|
+
raise ValueError(
|
|
37
|
+
f"Cannot infer file format from URL: {url}. "
|
|
38
|
+
"Please specify file_format parameter."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def _download_file(self) -> bytes:
|
|
42
|
+
"""Download file from URL"""
|
|
43
|
+
response = requests.get(self.url, stream=True, timeout=30)
|
|
44
|
+
response.raise_for_status()
|
|
45
|
+
return response.content
|
|
46
|
+
|
|
47
|
+
def read_file(self, **kwargs: Any) -> Iterator[TDataItems]:
|
|
48
|
+
"""Read file and yield data in chunks"""
|
|
49
|
+
content = self._download_file()
|
|
50
|
+
|
|
51
|
+
if self.file_format == "csv":
|
|
52
|
+
yield from self._read_csv(content, **kwargs)
|
|
53
|
+
elif self.file_format == "json":
|
|
54
|
+
yield from self._read_json(content, **kwargs)
|
|
55
|
+
elif self.file_format == "parquet":
|
|
56
|
+
yield from self._read_parquet(content, **kwargs)
|
|
57
|
+
|
|
58
|
+
def _read_csv(
|
|
59
|
+
self, content: bytes, chunksize: int = 10000, **pandas_kwargs: Any
|
|
60
|
+
) -> Iterator[TDataItems]:
|
|
61
|
+
"""Read CSV file with Pandas chunk by chunk"""
|
|
62
|
+
import pandas as pd # type: ignore
|
|
63
|
+
|
|
64
|
+
kwargs = {**{"header": "infer", "chunksize": chunksize}, **pandas_kwargs}
|
|
65
|
+
|
|
66
|
+
file_obj = io.BytesIO(content)
|
|
67
|
+
for df in pd.read_csv(file_obj, **kwargs):
|
|
68
|
+
yield df.to_dict(orient="records")
|
|
69
|
+
|
|
70
|
+
def _read_json(
|
|
71
|
+
self, content: bytes, chunksize: int = 1000, **kwargs: Any
|
|
72
|
+
) -> Iterator[TDataItems]:
|
|
73
|
+
"""Read JSON or JSONL file"""
|
|
74
|
+
from dlt.common import json
|
|
75
|
+
|
|
76
|
+
file_obj = io.BytesIO(content)
|
|
77
|
+
text = file_obj.read().decode("utf-8")
|
|
78
|
+
|
|
79
|
+
# Try to detect if it's JSONL format (one JSON object per line)
|
|
80
|
+
lines = text.strip().split("\n")
|
|
81
|
+
|
|
82
|
+
if len(lines) > 1:
|
|
83
|
+
# Likely JSONL format
|
|
84
|
+
lines_chunk = []
|
|
85
|
+
for line in lines:
|
|
86
|
+
if line.strip():
|
|
87
|
+
lines_chunk.append(json.loads(line))
|
|
88
|
+
if len(lines_chunk) >= chunksize:
|
|
89
|
+
yield lines_chunk
|
|
90
|
+
lines_chunk = []
|
|
91
|
+
if lines_chunk:
|
|
92
|
+
yield lines_chunk
|
|
93
|
+
else:
|
|
94
|
+
# Single JSON object or array
|
|
95
|
+
data = json.loads(text)
|
|
96
|
+
if isinstance(data, list):
|
|
97
|
+
# Chunk the list
|
|
98
|
+
for i in range(0, len(data), chunksize):
|
|
99
|
+
yield data[i : i + chunksize]
|
|
100
|
+
else:
|
|
101
|
+
# Single object
|
|
102
|
+
yield [data]
|
|
103
|
+
|
|
104
|
+
def _read_parquet(
|
|
105
|
+
self, content: bytes, chunksize: int = 10000, **kwargs: Any
|
|
106
|
+
) -> Iterator[TDataItems]:
|
|
107
|
+
"""Read Parquet file"""
|
|
108
|
+
from pyarrow import parquet as pq # type: ignore
|
|
109
|
+
|
|
110
|
+
file_obj = io.BytesIO(content)
|
|
111
|
+
parquet_file = pq.ParquetFile(file_obj)
|
|
112
|
+
|
|
113
|
+
for batch in parquet_file.iter_batches(batch_size=chunksize):
|
|
114
|
+
yield batch.to_pylist()
|
|
@@ -37,6 +37,7 @@ def jira_source() -> Any:
|
|
|
37
37
|
resolutions,
|
|
38
38
|
project_versions,
|
|
39
39
|
project_components,
|
|
40
|
+
events,
|
|
40
41
|
]
|
|
41
42
|
|
|
42
43
|
|
|
@@ -65,7 +66,11 @@ def projects(
|
|
|
65
66
|
yield from client.get_projects(expand=expand, recent=recent)
|
|
66
67
|
|
|
67
68
|
|
|
68
|
-
@dlt.resource(
|
|
69
|
+
@dlt.resource(
|
|
70
|
+
write_disposition="merge",
|
|
71
|
+
primary_key="id",
|
|
72
|
+
max_table_nesting=2,
|
|
73
|
+
)
|
|
69
74
|
def issues(
|
|
70
75
|
base_url: str = dlt.secrets.value,
|
|
71
76
|
email: str = dlt.secrets.value,
|
|
@@ -312,3 +317,24 @@ def project_components(
|
|
|
312
317
|
return []
|
|
313
318
|
|
|
314
319
|
return list(client.get_project_components(project_key))
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
@dlt.resource(write_disposition="replace")
|
|
323
|
+
def events(
|
|
324
|
+
base_url: str = dlt.secrets.value,
|
|
325
|
+
email: str = dlt.secrets.value,
|
|
326
|
+
api_token: str = dlt.secrets.value,
|
|
327
|
+
) -> Iterable[TDataItem]:
|
|
328
|
+
"""
|
|
329
|
+
Fetches all event types from Jira (e.g., Issue Created, Issue Updated, etc.).
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
base_url (str): Jira instance URL
|
|
333
|
+
email (str): User email for authentication
|
|
334
|
+
api_token (str): API token for authentication
|
|
335
|
+
|
|
336
|
+
Yields:
|
|
337
|
+
dict: The event data.
|
|
338
|
+
"""
|
|
339
|
+
client = get_client(base_url, email, api_token)
|
|
340
|
+
yield from client.get_events()
|
|
@@ -98,8 +98,6 @@ class JiraClient:
|
|
|
98
98
|
|
|
99
99
|
for attempt in range(max_retries + 1):
|
|
100
100
|
try:
|
|
101
|
-
logger.debug(f"Making request to {url} (attempt {attempt + 1})")
|
|
102
|
-
|
|
103
101
|
response = requests.request(
|
|
104
102
|
method=method,
|
|
105
103
|
url=url,
|
|
@@ -214,10 +212,6 @@ class JiraClient:
|
|
|
214
212
|
consecutive_empty_pages = 0
|
|
215
213
|
max_empty_pages = 3
|
|
216
214
|
|
|
217
|
-
logger.info(
|
|
218
|
-
f"Starting paginated request to {endpoint} with page_size={page_size}"
|
|
219
|
-
)
|
|
220
|
-
|
|
221
215
|
while True:
|
|
222
216
|
try:
|
|
223
217
|
response = self._make_request(endpoint, params)
|
|
@@ -238,7 +232,6 @@ class JiraClient:
|
|
|
238
232
|
is_last = True
|
|
239
233
|
else:
|
|
240
234
|
# Single item response
|
|
241
|
-
logger.debug(f"Received single item response from {endpoint}")
|
|
242
235
|
yield response
|
|
243
236
|
break
|
|
244
237
|
|
|
@@ -253,27 +246,18 @@ class JiraClient:
|
|
|
253
246
|
else:
|
|
254
247
|
consecutive_empty_pages = 0
|
|
255
248
|
|
|
256
|
-
logger.debug(
|
|
257
|
-
f"Retrieved {len(items)} items from {endpoint} (page {params['startAt'] // page_size + 1})"
|
|
258
|
-
)
|
|
259
|
-
|
|
260
249
|
for item in items:
|
|
261
250
|
if max_results and total_returned >= max_results:
|
|
262
|
-
logger.info(f"Reached max_results limit of {max_results}")
|
|
263
251
|
return
|
|
264
252
|
yield item
|
|
265
253
|
total_returned += 1
|
|
266
254
|
|
|
267
255
|
# Check if we've reached the end
|
|
268
256
|
if is_last or len(items) < page_size:
|
|
269
|
-
logger.debug(f"Reached end of pagination for {endpoint}")
|
|
270
257
|
break
|
|
271
258
|
|
|
272
259
|
# Check if we've got all available items
|
|
273
260
|
if total and total_returned >= total:
|
|
274
|
-
logger.debug(
|
|
275
|
-
f"Retrieved all {total} available items from {endpoint}"
|
|
276
|
-
)
|
|
277
261
|
break
|
|
278
262
|
|
|
279
263
|
# Move to next page
|
|
@@ -295,10 +279,6 @@ class JiraClient:
|
|
|
295
279
|
)
|
|
296
280
|
raise JiraAPIError(f"Pagination failed: {str(e)}")
|
|
297
281
|
|
|
298
|
-
logger.info(
|
|
299
|
-
f"Completed pagination for {endpoint}, returned {total_returned} items"
|
|
300
|
-
)
|
|
301
|
-
|
|
302
282
|
def search_issues(
|
|
303
283
|
self,
|
|
304
284
|
jql: str,
|
|
@@ -327,7 +307,7 @@ class JiraClient:
|
|
|
327
307
|
params["expand"] = expand
|
|
328
308
|
|
|
329
309
|
yield from self.get_paginated(
|
|
330
|
-
"search", params=params, page_size=page_size, max_results=max_results
|
|
310
|
+
"search/jql", params=params, page_size=page_size, max_results=max_results
|
|
331
311
|
)
|
|
332
312
|
|
|
333
313
|
def get_projects(
|
|
@@ -433,6 +413,13 @@ class JiraClient:
|
|
|
433
413
|
"""
|
|
434
414
|
yield from self.get_paginated(f"project/{project_key}/component")
|
|
435
415
|
|
|
416
|
+
def get_events(self) -> Iterator[Dict[str, Any]]:
|
|
417
|
+
"""Get all events (issue events like created, updated, etc.)."""
|
|
418
|
+
response = self._make_request("events")
|
|
419
|
+
if isinstance(response, list):
|
|
420
|
+
for event in response:
|
|
421
|
+
yield event
|
|
422
|
+
|
|
436
423
|
|
|
437
424
|
def get_client(
|
|
438
425
|
base_url: str, email: str, api_token: str, timeout: int = REQUEST_TIMEOUT
|