ingestr 0.14.2__tar.gz → 0.14.4__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.2 → ingestr-0.14.4}/Dockerfile +4 -1
- {ingestr-0.14.2 → ingestr-0.14.4}/Makefile +8 -2
- {ingestr-0.14.2 → ingestr-0.14.4}/PKG-INFO +1 -1
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/.vitepress/config.mjs +12 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/index.md +1 -1
- ingestr-0.14.4/docs/supported-sources/elasticsearch.md +80 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/fluxx.md +1 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/freshdesk.md +1 -0
- ingestr-0.14.4/docs/supported-sources/intercom.md +57 -0
- ingestr-0.14.4/docs/supported-sources/jira.md +61 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/mongodb.md +56 -5
- ingestr-0.14.4/ingestr/src/buildinfo.py +1 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/destinations.py +1 -24
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/elasticsearch/helpers.py +35 -9
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/factory.py +2 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/fluxx/__init__.py +9 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/freshdesk/__init__.py +2 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/freshdesk/freshdesk_client.py +15 -1
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/hubspot/__init__.py +6 -12
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/intercom/settings.py +3 -1
- ingestr-0.14.4/ingestr/src/jira_source/__init__.py +314 -0
- ingestr-0.14.4/ingestr/src/jira_source/helpers.py +452 -0
- ingestr-0.14.4/ingestr/src/jira_source/settings.py +170 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/mongodb/helpers.py +34 -6
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/sources.py +55 -0
- ingestr-0.14.4/resources/demo.gif +0 -0
- ingestr-0.14.2/docs/supported-sources/elasticsearch.md +0 -35
- ingestr-0.14.2/ingestr/src/buildinfo.py +0 -1
- {ingestr-0.14.2 → ingestr-0.14.4}/.dlt/config.toml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.dockerignore +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.githooks/pre-commit-hook.sh +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.github/workflows/deploy-docs.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.github/workflows/release.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.github/workflows/secrets-scan.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.github/workflows/tests.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.gitignore +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.gitleaksignore +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.python-version +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/.vale.ini +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/LICENSE.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/README.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/.vitepress/theme/custom.css +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/.vitepress/theme/index.js +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/commands/example-uris.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/commands/ingest.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/getting-started/core-concepts.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/getting-started/data-masking.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/getting-started/incremental-loading.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/getting-started/quickstart.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/getting-started/telemetry.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/applovin_max.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/athena.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/clickhouse_img.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/clickup_ingestion.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/cratedb-destination.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/cratedb-source.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/freshdesk_ingestion.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/gcp_spanner_ingestion.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/github.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/google_analytics_realtime_report.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/googleanalytics.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/ingestion_elasticsearch_img.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/kinesis.bigquery.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/linear.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/linkedin_ads.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/mixpanel_ingestion.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/personio.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/personio_duckdb.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/phantombuster.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/pipedrive.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/quickbook_ingestion.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/sftp.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/stripe_postgres.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/tiktok.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/wise_ingestion.png +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/media/zoom_ingestion.png +0 -0
- {ingestr-0.14.2/resources → ingestr-0.14.4/docs/public}/demo.gif +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/adjust.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/airtable.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/anthropic.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/applovin.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/applovin_max.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/appsflyer.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/appstore.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/asana.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/athena.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/attio.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/bigquery.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/chess.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/clickhouse.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/clickup.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/cratedb.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/csv.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/custom_queries.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/databricks.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/db2.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/docebo.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/duckdb.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/dynamodb.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/facebook-ads.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/frankfurter.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/fundraiseup.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/gcs.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/github.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/google-ads.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/google_analytics.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/gorgias.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/gsheets.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/hubspot.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/influxdb.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/isoc-pulse.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/kafka.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/kinesis.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/klaviyo.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/linear.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/linkedin_ads.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/mixpanel.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/motherduck.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/mssql.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/mysql.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/notion.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/oracle.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/personio.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/phantombuster.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/pinterest.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/pipedrive.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/postgres.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/quickbooks.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/redshift.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/revenuecat.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/s3.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/salesforce.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/sap-hana.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/sftp.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/shopify.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/slack.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/smartsheets.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/snowflake.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/solidgate.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/spanner.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/sqlite.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/stripe.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/tiktok-ads.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/trino.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/trustpilot.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/wise.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/zendesk.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/supported-sources/zoom.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/tutorials/load-kinesis-bigquery.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/tutorials/load-personio-duckdb.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/docs/tutorials/load-stripe-postgres.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/conftest.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/main.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/.gitignore +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/adjust/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/adjust/adjust_helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/airtable/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/anthropic/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/anthropic/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/applovin/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/applovin_max/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/appsflyer/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/appsflyer/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/appstore/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/appstore/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/appstore/errors.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/appstore/models.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/appstore/resources.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/arrow/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/asana_source/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/asana_source/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/asana_source/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/attio/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/attio/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/blob.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/chess/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/chess/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/chess/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/clickup/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/clickup/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/collector/spinner.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/docebo/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/docebo/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/docebo/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/dynamodb/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/elasticsearch/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/errors.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/facebook_ads/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/facebook_ads/exceptions.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/facebook_ads/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/facebook_ads/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/facebook_ads/utils.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/filesystem/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/filesystem/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/filesystem/readers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/filters.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/fluxx/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/frankfurter/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/frankfurter/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/freshdesk/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/fundraiseup/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/fundraiseup/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/github/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/github/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/github/queries.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/github/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_ads/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_ads/field.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_ads/metrics.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_ads/predicates.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_ads/reports.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_analytics/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_analytics/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_sheets/README.md +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_sheets/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_sheets/helpers/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_sheets/helpers/api_calls.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/google_sheets/helpers/data_processing.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/gorgias/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/gorgias/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/http_client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/hubspot/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/hubspot/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/influxdb/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/influxdb/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/intercom/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/intercom/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/isoc_pulse/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/kafka/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/kafka/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/kinesis/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/kinesis/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/klaviyo/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/klaviyo/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/klaviyo/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/linear/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/linear/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/linkedin_ads/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/linkedin_ads/dimension_time_enum.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/linkedin_ads/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/loader.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/masking.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/mixpanel/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/mixpanel/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/mongodb/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/notion/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/notion/helpers/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/notion/helpers/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/notion/helpers/database.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/notion/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/partition.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/personio/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/personio/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/phantombuster/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/phantombuster/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/pinterest/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/pipedrive/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/pipedrive/helpers/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/pipedrive/helpers/custom_fields_munger.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/pipedrive/helpers/pages.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/pipedrive/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/pipedrive/typing.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/quickbooks/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/resource.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/revenuecat/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/revenuecat/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/salesforce/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/salesforce/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/shopify/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/shopify/exceptions.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/shopify/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/shopify/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/slack/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/slack/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/slack/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/smartsheets/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/solidgate/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/solidgate/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/sql_database/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/sql_database/callbacks.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/stripe_analytics/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/stripe_analytics/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/stripe_analytics/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/table_definition.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/telemetry/event.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/testdata/fakebqcredentials.json +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/tiktok_ads/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/tiktok_ads/tiktok_helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/time.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/trustpilot/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/trustpilot/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/version.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/wise/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/wise/client.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/zendesk/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/zendesk/helpers/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/zendesk/helpers/api_helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/zendesk/helpers/credentials.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/zendesk/helpers/talk_api.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/zendesk/settings.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/zoom/__init__.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/src/zoom/helpers.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/testdata/.gitignore +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/testdata/create_replace.csv +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/testdata/delete_insert_expected.csv +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/testdata/delete_insert_part1.csv +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/testdata/delete_insert_part2.csv +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/testdata/merge_expected.csv +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/testdata/merge_part1.csv +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/testdata/merge_part2.csv +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/ingestr/tests/unit/test_smartsheets.py +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/package-lock.json +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/package.json +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/pyproject.toml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/requirements-dev.txt +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/requirements.in +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/requirements.txt +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/requirements_arm64.txt +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/resources/demo.tape +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/resources/ingestr.svg +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/AMPM.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Acronyms.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Colons.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Contractions.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/DateFormat.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Ellipses.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/EmDash.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Exclamation.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/FirstPerson.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Gender.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/GenderBias.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/HeadingPunctuation.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Headings.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Latin.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/LyHyphens.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/OptionalPlurals.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Ordinal.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/OxfordComma.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Parens.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Passive.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Periods.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Quotes.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Ranges.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Semicolons.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Slang.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Spacing.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Spelling.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Units.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/We.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/Will.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/WordList.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/meta.json +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/Google/vocab.txt +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/bruin/Ingestr.yml +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/styles/config/vocabularies/bruin/accept.txt +0 -0
- {ingestr-0.14.2 → ingestr-0.14.4}/test.env.template +0 -0
|
@@ -26,7 +26,7 @@ RUN \
|
|
|
26
26
|
export ACCEPT_EULA='Y' && \
|
|
27
27
|
# Install build dependencies
|
|
28
28
|
apt-get update && \
|
|
29
|
-
apt-get install -y curl gcc gpg libpq-dev build-essential unixodbc-dev g++ apt-transport-https
|
|
29
|
+
apt-get install -y curl gcc gpg libpq-dev build-essential unixodbc-dev g++ apt-transport-https git
|
|
30
30
|
|
|
31
31
|
RUN \
|
|
32
32
|
# Install pyodbc db drivers for MSSQL and PostgreSQL
|
|
@@ -50,6 +50,9 @@ RUN if [ "$(uname -m)" = "aarch64" ]; then \
|
|
|
50
50
|
cp /app/requirements_arm64.txt /app/requirements.txt; \
|
|
51
51
|
fi
|
|
52
52
|
|
|
53
|
+
# Generate version file
|
|
54
|
+
RUN make write-build-info
|
|
55
|
+
|
|
53
56
|
# Install all required packages and the application.
|
|
54
57
|
RUN uv pip install --requirement requirements.txt pyodbc .
|
|
55
58
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
SHELL := /bin/bash
|
|
2
2
|
.ONESHELL:
|
|
3
|
-
.PHONY: test lint format test-ci lint-ci build upload-release setup docker-shell
|
|
3
|
+
.PHONY: test lint format test-ci lint-ci build upload-release setup docker-shell write-build-info remove-build-info
|
|
4
4
|
|
|
5
5
|
BUILDINFO=ingestr/src/buildinfo.py
|
|
6
6
|
|
|
@@ -46,8 +46,14 @@ lint-docs:
|
|
|
46
46
|
tl: test lint
|
|
47
47
|
|
|
48
48
|
build: lock-deps
|
|
49
|
-
|
|
49
|
+
$(MAKE) write-build-info
|
|
50
50
|
rm -rf dist && python3 -m build
|
|
51
|
+
$(MAKE) remove-build-info
|
|
52
|
+
|
|
53
|
+
write-build-info:
|
|
54
|
+
cat > ${BUILDINFO} <<< "version = \"$$(git describe --tags --abbrev=0)\""
|
|
55
|
+
|
|
56
|
+
remove-build-info:
|
|
51
57
|
rm -f ${BUILDINFO}
|
|
52
58
|
|
|
53
59
|
upload-release:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ingestr
|
|
3
|
-
Version: 0.14.
|
|
3
|
+
Version: 0.14.4
|
|
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
|
|
@@ -5,6 +5,17 @@ export default defineConfig({
|
|
|
5
5
|
title: "ingestr",
|
|
6
6
|
description: "Ingest & copy data between any source and any destination",
|
|
7
7
|
base: "/ingestr/",
|
|
8
|
+
transformPageData(pageData) {
|
|
9
|
+
const canonicalUrl = `https://getbruin.com/docs/ingestr/${pageData.relativePath}`
|
|
10
|
+
.replace(/index\.md$/, '')
|
|
11
|
+
.replace(/\.md$/, '.html')
|
|
12
|
+
|
|
13
|
+
pageData.frontmatter.head ??= []
|
|
14
|
+
pageData.frontmatter.head.push([
|
|
15
|
+
'link',
|
|
16
|
+
{ rel: 'canonical', href: canonicalUrl }
|
|
17
|
+
])
|
|
18
|
+
},
|
|
8
19
|
head: [
|
|
9
20
|
[
|
|
10
21
|
"script",
|
|
@@ -141,6 +152,7 @@ export default defineConfig({
|
|
|
141
152
|
{ text: "Gorgias", link: "/supported-sources/gorgias.md" },
|
|
142
153
|
{ text: "HubSpot", link: "/supported-sources/hubspot.md" },
|
|
143
154
|
{ text: "Internet Society Pulse", link: "/supported-sources/isoc-pulse.md" },
|
|
155
|
+
{ text: "Jira", link: "/supported-sources/jira.md" },
|
|
144
156
|
{ text: "Klaviyo", link: "/supported-sources/klaviyo.md" },
|
|
145
157
|
{ text: "Linear", link: "/supported-sources/linear.md" },
|
|
146
158
|
{ text: "LinkedIn Ads", link: "/supported-sources/linkedin_ads.md" },
|
|
@@ -7,7 +7,7 @@ hero:
|
|
|
7
7
|
text: Copy data between any source and any destination
|
|
8
8
|
tagline: "ingestr is a command-line application that allows copying data from any source into any destination database."
|
|
9
9
|
image:
|
|
10
|
-
src:
|
|
10
|
+
src: /demo.gif
|
|
11
11
|
alt: ingestr logo
|
|
12
12
|
actions:
|
|
13
13
|
- theme: brand
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Elasticsearch
|
|
2
|
+
[Elasticsearch](https://www.elastic.co/elasticsearch) is a distributed, RESTful search and analytics engine designed for fast and scalable data retrieval.
|
|
3
|
+
|
|
4
|
+
ingestr supports Elasticsearch as both a source and destination.
|
|
5
|
+
|
|
6
|
+
## URI format
|
|
7
|
+
The URI format for Elasticsearch is as follows:
|
|
8
|
+
|
|
9
|
+
```plaintext
|
|
10
|
+
elasticsearch://username:password@host:port?secure=<secure>&verify_certs=<verify_certs>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
URI parameters:
|
|
14
|
+
- `username`: The username used to authenticate with Elasticsearch (optional).
|
|
15
|
+
- `password`: The password associated with the specified username (optional).
|
|
16
|
+
- `host`: The host address of the Elasticsearch server.
|
|
17
|
+
- `port`: The port number used by the Elasticsearch server (default: 9200).
|
|
18
|
+
- `secure`: Enables HTTPS when set to true. By default, it is true. Set to false for HTTP connections.
|
|
19
|
+
- `verify_certs`: Verifies TLS certificates when set to true. By default, it is true. Only used for sources.
|
|
20
|
+
|
|
21
|
+
The same URI structure can be used both for sources and destinations.
|
|
22
|
+
|
|
23
|
+
## Using Elasticsearch as a source
|
|
24
|
+
|
|
25
|
+
### Source Table
|
|
26
|
+
|
|
27
|
+
`<index-name>`: Fetches all available documents from the specified index.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
ingestr ingest \
|
|
31
|
+
--source-uri "elasticsearch://elastic:changeme@localhost:9200?secure=false&verify_certs=false" \
|
|
32
|
+
--source-table 'test-index' \
|
|
33
|
+
--dest-uri "duckdb:///users.duckdb" \
|
|
34
|
+
--dest-table 'dest.users_detail'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This command retrieves all documents from the test-index in Elasticsearch and copy them to the dest.users_detail table in DuckDB.
|
|
38
|
+
|
|
39
|
+
<img alt="ingestion_elasticsearch_img" src="../media/ingestion_elasticsearch_img.png" />
|
|
40
|
+
|
|
41
|
+
## Using Elasticsearch as a destination
|
|
42
|
+
|
|
43
|
+
Elasticsearch can be used as a destination to load data from various sources. The `--dest-table` option specifies the index name where data will be loaded.
|
|
44
|
+
|
|
45
|
+
### Elasticsearch Cloud (with authentication)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
ingestr ingest \
|
|
49
|
+
--source-uri "postgres://user:pass@localhost:5432/mydb" \
|
|
50
|
+
--source-table "public.users" \
|
|
51
|
+
--dest-uri "elasticsearch://username:password@cluster.cloud.es.io:443" \
|
|
52
|
+
--dest-table "users_index"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
> [!NOTE]
|
|
56
|
+
> Cloud Elasticsearch instances typically use HTTPS (port 443). The `secure` parameter defaults to `true`, so HTTPS is used automatically.
|
|
57
|
+
|
|
58
|
+
### Local Elasticsearch with authentication
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
ingestr ingest \
|
|
62
|
+
--source-uri "csv:///path/to/data.csv" \
|
|
63
|
+
--source-table "data" \
|
|
64
|
+
--dest-uri "elasticsearch://elastic:changeme@localhost:9200?secure=false" \
|
|
65
|
+
--dest-table "myindex"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Local Elasticsearch without authentication
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
ingestr ingest \
|
|
72
|
+
--source-uri "csv:///path/to/data.csv" \
|
|
73
|
+
--source-table "data" \
|
|
74
|
+
--dest-uri "elasticsearch://localhost:9200?secure=false" \
|
|
75
|
+
--dest-table "myindex"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
> [!TIP]
|
|
79
|
+
> By default, ingestr uses a "replace" strategy which deletes the existing index before loading new data. The target index will be created automatically if it doesn't exist.
|
|
80
|
+
|
|
@@ -104,6 +104,7 @@ Fluxx source allows ingesting the following sources into separate tables:
|
|
|
104
104
|
| `affiliate_type` | id | - | replace | Affiliate Type management and tracking |
|
|
105
105
|
| `aha_requirements_tickets` | id | - | replace | Aha Requirements Tickets management and tracking |
|
|
106
106
|
| `alert` | id | - | replace | Alert management and tracking |
|
|
107
|
+
| `alert_email` | id | - | replace | Alert email configurations and templates for notification delivery |
|
|
107
108
|
| `alert_email_user` | id | - | replace | Alert Email User management and tracking |
|
|
108
109
|
| `alert_model_log` | id | - | replace | Alert Model Log management and tracking |
|
|
109
110
|
| `alert_recipient` | id | - | replace | Alert Recipient management and tracking |
|
|
@@ -44,5 +44,6 @@ The Freshdesk source allows you to ingest the following tables:
|
|
|
44
44
|
| [groups](https://developers.freshdesk.com/api/#groups) | id | updated_at | merge | Retrieves agents organized based on specific criteria. |
|
|
45
45
|
| [roles](https://developers.freshdesk.com/api/#roles) | id | updated_at | merge | Retrieves predefined sets of permissions that determine what actions an agent can perform.|
|
|
46
46
|
| [tickets](https://developers.freshdesk.com/api/#tickets) | id | updated_at | merge | Retrieves customer inquiries or issues submitted via various channels like email, chat, phone, etc.
|
|
47
|
+
| [tickets:<query>](https://developers.freshdesk.com/api/#filter_tickets) | id | updated_at | merge | Executes the [Freshdesk ticket filter query](https://developers.freshdesk.com/api/#filter_tickets) while preserving incremental sync. |
|
|
47
48
|
|
|
48
49
|
Use these as the `--source-table` parameter in the `ingestr ingest` command.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Intercom
|
|
2
|
+
|
|
3
|
+
[Intercom](https://www.intercom.com/) is a customer messaging platform that helps businesses connect with customers through targeted, behavior-driven messages.
|
|
4
|
+
|
|
5
|
+
ingestr supports Intercom as a source.
|
|
6
|
+
|
|
7
|
+
## URI format
|
|
8
|
+
|
|
9
|
+
The URI format for Intercom is as follows:
|
|
10
|
+
|
|
11
|
+
```plaintext
|
|
12
|
+
intercom://?access_token=<access_token>®ion=<region>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
URI parameters:
|
|
16
|
+
|
|
17
|
+
- `access_token`: The access token is used for authentication with the Intercom API.
|
|
18
|
+
- `region`: The data region where your Intercom workspace is hosted. Valid values are `us`, `eu`, or `au`. Defaults to `us`.
|
|
19
|
+
|
|
20
|
+
The URI is used to connect to the Intercom API for extracting data.
|
|
21
|
+
|
|
22
|
+
## Setting up an Intercom Integration
|
|
23
|
+
|
|
24
|
+
Intercom requires a few steps to set up an integration, please follow the guide dltHub [has built here](https://dlthub.com/docs/dlt-ecosystem/verified-sources/intercom).
|
|
25
|
+
|
|
26
|
+
Once you complete the guide, you should have an access token. Let's say your access token is `dG9rOjE...` and your workspace is in the US region, here's a sample command that will copy the data from Intercom into a DuckDB database:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
ingestr ingest \
|
|
30
|
+
--source-uri 'intercom://?access_token=dG9rOjE...®ion=us' \
|
|
31
|
+
--source-table 'contacts' \
|
|
32
|
+
--dest-uri duckdb:///intercom.duckdb \
|
|
33
|
+
--dest-table 'intercom.contacts'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The result of this command will be a table in the `intercom.duckdb` database.
|
|
37
|
+
|
|
38
|
+
## Tables
|
|
39
|
+
|
|
40
|
+
Intercom source allows ingesting the following sources into separate tables:
|
|
41
|
+
|
|
42
|
+
| Table | PK | Inc Key | Inc Strategy | Details |
|
|
43
|
+
|-------|----|---------|--------------|---------|
|
|
44
|
+
| [contacts](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Contacts/contact/) | id | updated_at | merge | Retrieves information about contacts (visitors, users, and leads) |
|
|
45
|
+
| [companies](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Companies/company/) | id | updated_at | merge | Retrieves information about companies |
|
|
46
|
+
| [conversations](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Conversations/conversation/) | id | updated_at | merge | Retrieves conversation data |
|
|
47
|
+
| [articles](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Articles/article/) | id | updated_at | merge | Retrieves help center articles |
|
|
48
|
+
| [tags](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Tags/tag/) | id | - | replace | Retrieves tags used to organize contacts and companies |
|
|
49
|
+
| [segments](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Segments/segment/) | id | - | replace | Retrieves segments for filtering contacts and companies |
|
|
50
|
+
| [admins](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Admins/admin/) | id | - | replace | Retrieves admin user information |
|
|
51
|
+
| [teams](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Teams/team/) | id | - | replace | Retrieves team information |
|
|
52
|
+
| [data_attributes](https://developers.intercom.com/docs/references/rest-api/api.intercom.io/Data%20Attributes/dataattribute/) | name | - | replace | Retrieves data attributes (both built-in and custom attributes) |
|
|
53
|
+
|
|
54
|
+
Use these as `--source-table` parameter in the `ingestr ingest` command.
|
|
55
|
+
|
|
56
|
+
> [!TIP]
|
|
57
|
+
> Resources marked with "merge" Inc Strategy support incremental loading based on the `updated_at` timestamp, which means subsequent runs will only fetch new or updated records.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Jira
|
|
2
|
+
|
|
3
|
+
[Jira](https://www.atlassian.com/software/jira) is a proprietary issue tracking product developed by Atlassian that allows bug tracking and agile project management.
|
|
4
|
+
|
|
5
|
+
ingestr supports Jira as a source through [Jira's REST API v3](https://developer.atlassian.com/cloud/jira/platform/rest/v3/).
|
|
6
|
+
|
|
7
|
+
## URI format
|
|
8
|
+
|
|
9
|
+
The URI format for Jira is:
|
|
10
|
+
|
|
11
|
+
```plaintext
|
|
12
|
+
jira://your-domain.atlassian.net?email=<email>&api_token=<api_token>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
URI parameters:
|
|
16
|
+
- `email`: the email address used for authentication with the Jira API
|
|
17
|
+
- `api_token`: the API token for authentication (required for Jira Cloud)
|
|
18
|
+
|
|
19
|
+
## Example usage
|
|
20
|
+
|
|
21
|
+
Assuming your Jira domain is `company.atlassian.net`, email is `user@company.com`, and API token is `ATATT3xFfGF0...`, you can ingest issues into DuckDB using:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
ingestr ingest \
|
|
25
|
+
--source-uri 'jira://company.atlassian.net?email=user@company.com&api_token=ATATT3xFfGF0...' \
|
|
26
|
+
--source-table 'issues' \
|
|
27
|
+
--dest-uri duckdb:///jira.duckdb \
|
|
28
|
+
--dest-table 'dest.issues'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Authentication
|
|
32
|
+
|
|
33
|
+
To connect to Jira, you need:
|
|
34
|
+
|
|
35
|
+
1. **Email**: Your Atlassian account email
|
|
36
|
+
2. **API Token**: Create one from your [Atlassian Account Settings](https://id.atlassian.com/manage-profile/security/api-tokens)
|
|
37
|
+
|
|
38
|
+
## Tables
|
|
39
|
+
|
|
40
|
+
Jira source allows ingesting the following tables:
|
|
41
|
+
|
|
42
|
+
| Table | PK | Inc Key | Inc Strategy | Details |
|
|
43
|
+
| ----- | -- | ------- | ------------ | ------- |
|
|
44
|
+
| `projects` | id | - | replace | Fetches all projects from your Jira instance. |
|
|
45
|
+
| `issues` | id | fields.updated | merge | Fetches all issues with support for incremental loading based on updated timestamp. |
|
|
46
|
+
| `users` | accountId | - | replace | Fetches users from your Jira instance. |
|
|
47
|
+
| `issue_types` | id | - | replace | Fetches all issue types configured in your Jira instance. |
|
|
48
|
+
| `statuses` | id | - | replace | Fetches all workflow statuses from your Jira instance. |
|
|
49
|
+
| `priorities` | id | - | replace | Fetches all issue priorities from your Jira instance. |
|
|
50
|
+
| `resolutions` | id | - | replace | Fetches all issue resolutions from your Jira instance. |
|
|
51
|
+
| `project_versions` | id | - | replace | Fetches versions for each project. |
|
|
52
|
+
| `project_components` | id | - | replace | Fetches components for each project. |
|
|
53
|
+
|
|
54
|
+
Use these as the `--source-table` parameter in the `ingestr ingest` command.
|
|
55
|
+
|
|
56
|
+
## Incremental Loading
|
|
57
|
+
|
|
58
|
+
The `issues` table supports incremental loading based on the `updated` field. This means subsequent runs will only fetch issues that have been modified since the last run, making the data ingestion more efficient for large Jira instances.
|
|
59
|
+
|
|
60
|
+
> [!NOTE]
|
|
61
|
+
> Most tables use "replace" write disposition, meaning they will overwrite existing data on each run. Only the `issues` table supports incremental loading with "merge" disposition.
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# MongoDB
|
|
2
2
|
MongoDB is a popular, open source NoSQL database known for its flexibility, scalability, and wide adoption in a variety of applications.
|
|
3
3
|
|
|
4
|
-
ingestr supports MongoDB as a source.
|
|
4
|
+
ingestr supports MongoDB as both a source and destination.
|
|
5
5
|
|
|
6
6
|
## URI format
|
|
7
|
-
The URI format for MongoDB is as follows:
|
|
8
7
|
|
|
8
|
+
MongoDB supports two connection string formats:
|
|
9
|
+
|
|
10
|
+
### Standard format (local/self-hosted)
|
|
9
11
|
```plaintext
|
|
10
12
|
mongodb://user:password@host:port
|
|
11
13
|
```
|
|
@@ -16,12 +18,21 @@ URI parameters:
|
|
|
16
18
|
- `host`: the host address of the database server
|
|
17
19
|
- `port`: the port number the database server is listening on, default is 27017 for MongoDB
|
|
18
20
|
|
|
21
|
+
### SRV format (MongoDB Atlas)
|
|
22
|
+
```plaintext
|
|
23
|
+
mongodb+srv://user:password@cluster.xxxxx.mongodb.net/?retryWrites=true&w=majority
|
|
24
|
+
```
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
URI parameters:
|
|
27
|
+
- `user`: the user name to connect to the database
|
|
28
|
+
- `password`: the password for the user
|
|
29
|
+
- `cluster.xxxxx.mongodb.net`: the cluster hostname provided by MongoDB Atlas
|
|
30
|
+
- Query parameters like `retryWrites` and `w` are optional but recommended for Atlas connections
|
|
22
31
|
|
|
32
|
+
> [!CAUTION]
|
|
33
|
+
> Do not put the database name at the end of the URI for MongoDB, instead make it a part of `--source-table` or `--dest-table` option as `database.collection` format.
|
|
23
34
|
|
|
24
|
-
You can read more about MongoDB's connection string format [here](https://docs.mongodb.com/manual/reference/connection-string/).
|
|
35
|
+
The same URI structure can be used both for sources and destinations. You can read more about MongoDB's connection string format [here](https://docs.mongodb.com/manual/reference/connection-string/).
|
|
25
36
|
|
|
26
37
|
## Source table format
|
|
27
38
|
|
|
@@ -148,3 +159,43 @@ ingestr performs several validations on custom aggregation pipelines:
|
|
|
148
159
|
- Add appropriate indexes to support your aggregation pipeline
|
|
149
160
|
- Consider using `$limit` to restrict the number of documents processed
|
|
150
161
|
- For large datasets, MongoDB's `allowDiskUse: true` option is automatically enabled for aggregation pipelines
|
|
162
|
+
|
|
163
|
+
## Using MongoDB as a destination
|
|
164
|
+
|
|
165
|
+
MongoDB can be used as a destination to load data from various sources. The `--dest-table` option follows the same format: `database.collection`.
|
|
166
|
+
|
|
167
|
+
### MongoDB Atlas
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
ingestr ingest \
|
|
171
|
+
--source-uri "postgres://user:pass@localhost:5432/mydb" \
|
|
172
|
+
--source-table "public.users" \
|
|
173
|
+
--dest-uri "mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority" \
|
|
174
|
+
--dest-table "mydb.users"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
> [!NOTE]
|
|
178
|
+
> When using MongoDB Atlas as a destination, ensure your IP address is whitelisted in Network Access settings.
|
|
179
|
+
|
|
180
|
+
### Local MongoDB with authentication
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
ingestr ingest \
|
|
184
|
+
--source-uri "csv:///path/to/data.csv" \
|
|
185
|
+
--source-table "data" \
|
|
186
|
+
--dest-uri "mongodb://username:password@localhost:27017/?authSource=admin" \
|
|
187
|
+
--dest-table "mydb.mycollection"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Local MongoDB without authentication
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
ingestr ingest \
|
|
194
|
+
--source-uri "csv:///path/to/data.csv" \
|
|
195
|
+
--source-table "data" \
|
|
196
|
+
--dest-uri "mongodb://localhost:27017" \
|
|
197
|
+
--dest-table "mydb.mycollection"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
> [!TIP]
|
|
201
|
+
> By default, ingestr uses a "replace" strategy which deletes existing data in the collection before loading new data. The target database and collection will be created automatically if they don't exist.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "v0.14.4"
|
|
@@ -813,30 +813,7 @@ class ElasticsearchDestination:
|
|
|
813
813
|
|
|
814
814
|
class MongoDBDestination:
|
|
815
815
|
def dlt_dest(self, uri: str, **kwargs):
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
parsed_uri = urlparse(uri)
|
|
819
|
-
|
|
820
|
-
# Extract connection details from URI
|
|
821
|
-
host = parsed_uri.hostname or "localhost"
|
|
822
|
-
port = parsed_uri.port or 27017
|
|
823
|
-
username = parsed_uri.username
|
|
824
|
-
password = parsed_uri.password
|
|
825
|
-
database = (
|
|
826
|
-
parsed_uri.path.lstrip("/") if parsed_uri.path.lstrip("/") else "ingestr_db"
|
|
827
|
-
)
|
|
828
|
-
|
|
829
|
-
# Build connection string
|
|
830
|
-
if username and password:
|
|
831
|
-
connection_string = f"mongodb://{username}:{password}@{host}:{port}"
|
|
832
|
-
else:
|
|
833
|
-
connection_string = f"mongodb://{host}:{port}"
|
|
834
|
-
|
|
835
|
-
# Add query parameters if any
|
|
836
|
-
if parsed_uri.query:
|
|
837
|
-
connection_string += f"?{parsed_uri.query}"
|
|
838
|
-
|
|
839
|
-
return mongodb_insert(connection_string, database)
|
|
816
|
+
return mongodb_insert(uri)
|
|
840
817
|
|
|
841
818
|
def dlt_run_params(self, uri: str, table: str, **kwargs) -> dict:
|
|
842
819
|
return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Elasticsearch destination helpers"""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
import logging
|
|
4
5
|
from typing import Any, Dict, Iterator
|
|
5
6
|
from urllib.parse import urlparse
|
|
6
7
|
|
|
@@ -9,6 +10,10 @@ import dlt
|
|
|
9
10
|
from elasticsearch import Elasticsearch
|
|
10
11
|
from elasticsearch.helpers import bulk
|
|
11
12
|
|
|
13
|
+
# Suppress Elasticsearch transport logging
|
|
14
|
+
logging.getLogger("elasticsearch.transport").setLevel(logging.WARNING)
|
|
15
|
+
logging.getLogger("elastic_transport.transport").setLevel(logging.WARNING)
|
|
16
|
+
|
|
12
17
|
|
|
13
18
|
def process_file_items(file_path: str) -> Iterator[Dict[str, Any]]:
|
|
14
19
|
"""Process items from a file path (JSONL format)."""
|
|
@@ -52,15 +57,36 @@ def elasticsearch_insert(
|
|
|
52
57
|
parsed = urlparse(connection_string)
|
|
53
58
|
|
|
54
59
|
# Build Elasticsearch client configuration
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
actual_url = connection_string
|
|
61
|
+
secure = True # Default to HTTPS (secure by default)
|
|
62
|
+
|
|
63
|
+
if connection_string.startswith("elasticsearch://"):
|
|
64
|
+
actual_url = connection_string.replace("elasticsearch://", "")
|
|
65
|
+
|
|
66
|
+
# Parse to check for query parameters
|
|
67
|
+
temp_parsed = urlparse("http://" + actual_url)
|
|
68
|
+
from urllib.parse import parse_qs
|
|
69
|
+
|
|
70
|
+
query_params = parse_qs(temp_parsed.query)
|
|
71
|
+
|
|
72
|
+
# Check ?secure parameter (defaults to true)
|
|
73
|
+
if "secure" in query_params:
|
|
74
|
+
secure = query_params["secure"][0].lower() in ["true", "1", "yes"]
|
|
75
|
+
|
|
76
|
+
# Remove query params from URL for ES client
|
|
77
|
+
actual_url = actual_url.split("?")[0]
|
|
78
|
+
|
|
79
|
+
# Add scheme
|
|
80
|
+
scheme = "https" if secure else "http"
|
|
81
|
+
actual_url = f"{scheme}://{actual_url}"
|
|
82
|
+
|
|
83
|
+
parsed = urlparse(actual_url)
|
|
84
|
+
|
|
85
|
+
es_config: Dict[str, Any] = {
|
|
86
|
+
"hosts": [actual_url],
|
|
87
|
+
"verify_certs": secure,
|
|
88
|
+
"ssl_show_warn": False,
|
|
89
|
+
}
|
|
64
90
|
|
|
65
91
|
# Add authentication if present
|
|
66
92
|
if parsed.username and parsed.password:
|
|
@@ -56,6 +56,7 @@ from ingestr.src.sources import (
|
|
|
56
56
|
InfluxDBSource,
|
|
57
57
|
IntercomSource,
|
|
58
58
|
IsocPulseSource,
|
|
59
|
+
JiraSource,
|
|
59
60
|
KafkaSource,
|
|
60
61
|
KinesisSource,
|
|
61
62
|
KlaviyoSource,
|
|
@@ -168,6 +169,7 @@ class SourceDestinationFactory:
|
|
|
168
169
|
"slack": SlackSource,
|
|
169
170
|
"hubspot": HubspotSource,
|
|
170
171
|
"intercom": IntercomSource,
|
|
172
|
+
"jira": JiraSource,
|
|
171
173
|
"airtable": AirtableSource,
|
|
172
174
|
"klaviyo": KlaviyoSource,
|
|
173
175
|
"mixpanel": MixpanelSource,
|
|
@@ -96,6 +96,15 @@ FLUXX_RESOURCES = {
|
|
|
96
96
|
"workflow_events": {"data_type": "json", "field_type": "relation"},
|
|
97
97
|
},
|
|
98
98
|
},
|
|
99
|
+
"alert_email": {
|
|
100
|
+
"endpoint": "alert_email",
|
|
101
|
+
"fields": {
|
|
102
|
+
"alert_id": {"data_type": "bigint", "field_type": "column"},
|
|
103
|
+
"created_at": {"data_type": "timestamp", "field_type": "column"},
|
|
104
|
+
"id": {"data_type": "bigint", "field_type": "column"},
|
|
105
|
+
"updated_at": {"data_type": "timestamp", "field_type": "column"},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
99
108
|
"affiliate": {
|
|
100
109
|
"endpoint": "affiliate",
|
|
101
110
|
"fields": {
|
|
@@ -20,6 +20,7 @@ def freshdesk_source(
|
|
|
20
20
|
end_date: Optional[pendulum.DateTime] = None,
|
|
21
21
|
per_page: int = 100,
|
|
22
22
|
endpoints: Optional[List[str]] = None,
|
|
23
|
+
query: Optional[str] = None,
|
|
23
24
|
) -> Iterable[DltResource]:
|
|
24
25
|
"""
|
|
25
26
|
Retrieves data from specified Freshdesk API endpoints.
|
|
@@ -72,6 +73,7 @@ def freshdesk_source(
|
|
|
72
73
|
per_page=per_page,
|
|
73
74
|
start_date=start_date,
|
|
74
75
|
end_date=end_date,
|
|
76
|
+
query=query,
|
|
75
77
|
)
|
|
76
78
|
|
|
77
79
|
# Set default endpoints if not provided
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
import time
|
|
5
|
-
from typing import Any, Dict, Iterable
|
|
5
|
+
from typing import Any, Dict, Iterable, Optional
|
|
6
6
|
|
|
7
7
|
import pendulum
|
|
8
8
|
from dlt.common.typing import TDataItem
|
|
@@ -70,6 +70,7 @@ class FreshdeskClient:
|
|
|
70
70
|
per_page: int,
|
|
71
71
|
start_date: pendulum.DateTime,
|
|
72
72
|
end_date: pendulum.DateTime,
|
|
73
|
+
query: Optional[str] = None,
|
|
73
74
|
) -> Iterable[TDataItem]:
|
|
74
75
|
"""
|
|
75
76
|
Fetches a paginated response from a specified endpoint.
|
|
@@ -79,6 +80,9 @@ class FreshdeskClient:
|
|
|
79
80
|
updated at the specified timestamp.
|
|
80
81
|
"""
|
|
81
82
|
page = 1
|
|
83
|
+
if query is not None:
|
|
84
|
+
query = query.replace('"', "").strip()
|
|
85
|
+
|
|
82
86
|
while True:
|
|
83
87
|
# Construct the URL for the specific endpoint
|
|
84
88
|
url = f"{self.base_url}/{endpoint}"
|
|
@@ -93,11 +97,21 @@ class FreshdeskClient:
|
|
|
93
97
|
|
|
94
98
|
params[param_key] = start_date.to_iso8601_string()
|
|
95
99
|
|
|
100
|
+
if query and endpoint == "tickets":
|
|
101
|
+
url = f"{self.base_url}/search/tickets"
|
|
102
|
+
params = {
|
|
103
|
+
"query": f'"{query}"',
|
|
104
|
+
"page": page,
|
|
105
|
+
}
|
|
106
|
+
|
|
96
107
|
# Handle requests with rate-limiting
|
|
97
108
|
# A maximum of 300 pages (30000 tickets) will be returned.
|
|
98
109
|
response = self._request_with_rate_limit(url, params=params)
|
|
99
110
|
data = response.json()
|
|
100
111
|
|
|
112
|
+
if query and endpoint == "tickets":
|
|
113
|
+
data = data["results"]
|
|
114
|
+
|
|
101
115
|
if not data:
|
|
102
116
|
break # Stop if no data or max page limit reached
|
|
103
117
|
|