outhad-integrations 0.32.0
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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +43 -0
- data/.ruby-version +1 -0
- data/.vscode/settings.json +5 -0
- data/README.md +76 -0
- data/Rakefile +12 -0
- data/lib/outhad/integrations/config.rb +14 -0
- data/lib/outhad/integrations/core/base_connector.rb +79 -0
- data/lib/outhad/integrations/core/constants.rb +103 -0
- data/lib/outhad/integrations/core/destination_connector.rb +20 -0
- data/lib/outhad/integrations/core/fullrefresher.rb +19 -0
- data/lib/outhad/integrations/core/http_client.rb +17 -0
- data/lib/outhad/integrations/core/http_helper.rb +36 -0
- data/lib/outhad/integrations/core/query_builder.rb +33 -0
- data/lib/outhad/integrations/core/rate_limiter.rb +19 -0
- data/lib/outhad/integrations/core/source_connector.rb +66 -0
- data/lib/outhad/integrations/core/streaming_http_client.rb +21 -0
- data/lib/outhad/integrations/core/unstructured_source_connector.rb +52 -0
- data/lib/outhad/integrations/core/utils.rb +123 -0
- data/lib/outhad/integrations/core/vector_source_connector.rb +14 -0
- data/lib/outhad/integrations/destination/airtable/client.rb +157 -0
- data/lib/outhad/integrations/destination/airtable/config/catalog.json +6 -0
- data/lib/outhad/integrations/destination/airtable/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/airtable/config/spec.json +23 -0
- data/lib/outhad/integrations/destination/airtable/icon.svg +6 -0
- data/lib/outhad/integrations/destination/airtable/schema_helper.rb +141 -0
- data/lib/outhad/integrations/destination/ais_data_store/client.rb +130 -0
- data/lib/outhad/integrations/destination/ais_data_store/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/ais_data_store/config/spec.json +68 -0
- data/lib/outhad/integrations/destination/ais_data_store/icon.svg +4 -0
- data/lib/outhad/integrations/destination/amazon_s3/client.rb +92 -0
- data/lib/outhad/integrations/destination/amazon_s3/config/catalog.json +16 -0
- data/lib/outhad/integrations/destination/amazon_s3/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/amazon_s3/config/spec.json +56 -0
- data/lib/outhad/integrations/destination/amazon_s3/icon.svg +34 -0
- data/lib/outhad/integrations/destination/databricks_lakehouse/client.rb +147 -0
- data/lib/outhad/integrations/destination/databricks_lakehouse/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/databricks_lakehouse/config/spec.json +44 -0
- data/lib/outhad/integrations/destination/databricks_lakehouse/icon.svg +65 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/client.rb +125 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/config/catalog.json +42 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/config/spec.json +28 -0
- data/lib/outhad/integrations/destination/facebook_custom_audience/icon.svg +23 -0
- data/lib/outhad/integrations/destination/google_sheets/client.rb +240 -0
- data/lib/outhad/integrations/destination/google_sheets/config/catalog.json +6 -0
- data/lib/outhad/integrations/destination/google_sheets/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/google_sheets/config/spec.json +75 -0
- data/lib/outhad/integrations/destination/google_sheets/icon.svg +1 -0
- data/lib/outhad/integrations/destination/http/client.rb +106 -0
- data/lib/outhad/integrations/destination/http/config/catalog.json +16 -0
- data/lib/outhad/integrations/destination/http/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/http/config/spec.json +24 -0
- data/lib/outhad/integrations/destination/http/icon.svg +9 -0
- data/lib/outhad/integrations/destination/hubspot/client.rb +122 -0
- data/lib/outhad/integrations/destination/hubspot/config/catalog.json +351 -0
- data/lib/outhad/integrations/destination/hubspot/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/hubspot/config/spec.json +18 -0
- data/lib/outhad/integrations/destination/hubspot/icon.svg +5 -0
- data/lib/outhad/integrations/destination/iterable/client.rb +111 -0
- data/lib/outhad/integrations/destination/iterable/config/catalog.json +47 -0
- data/lib/outhad/integrations/destination/iterable/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/iterable/config/spec.json +19 -0
- data/lib/outhad/integrations/destination/iterable/icon.svg +71 -0
- data/lib/outhad/integrations/destination/klaviyo/client.rb +119 -0
- data/lib/outhad/integrations/destination/klaviyo/config/catalog.json +103 -0
- data/lib/outhad/integrations/destination/klaviyo/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/klaviyo/config/spec.json +24 -0
- data/lib/outhad/integrations/destination/klaviyo/icon.svg +6 -0
- data/lib/outhad/integrations/destination/mailchimp/client.rb +141 -0
- data/lib/outhad/integrations/destination/mailchimp/config/catalog.json +142 -0
- data/lib/outhad/integrations/destination/mailchimp/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/mailchimp/config/spec.json +28 -0
- data/lib/outhad/integrations/destination/mailchimp/icon.svg +4 -0
- data/lib/outhad/integrations/destination/maria_db/client.rb +114 -0
- data/lib/outhad/integrations/destination/maria_db/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/maria_db/config/spec.json +48 -0
- data/lib/outhad/integrations/destination/maria_db/icon.svg +15 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/client.rb +150 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/config/catalog.json +161 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/config/spec.json +35 -0
- data/lib/outhad/integrations/destination/microsoft_dynamics/icon.svg +2 -0
- data/lib/outhad/integrations/destination/microsoft_excel/client.rb +198 -0
- data/lib/outhad/integrations/destination/microsoft_excel/config/catalog.json +7 -0
- data/lib/outhad/integrations/destination/microsoft_excel/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/microsoft_excel/config/spec.json +19 -0
- data/lib/outhad/integrations/destination/microsoft_excel/icon.svg +18 -0
- data/lib/outhad/integrations/destination/microsoft_sql/client.rb +137 -0
- data/lib/outhad/integrations/destination/microsoft_sql/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/microsoft_sql/config/spec.json +68 -0
- data/lib/outhad/integrations/destination/microsoft_sql/icon.svg +22 -0
- data/lib/outhad/integrations/destination/odoo/client.rb +109 -0
- data/lib/outhad/integrations/destination/odoo/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/odoo/config/spec.json +39 -0
- data/lib/outhad/integrations/destination/odoo/icon.svg +21 -0
- data/lib/outhad/integrations/destination/oracle_db/client.rb +112 -0
- data/lib/outhad/integrations/destination/oracle_db/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/oracle_db/config/spec.json +47 -0
- data/lib/outhad/integrations/destination/oracle_db/icon.svg +4 -0
- data/lib/outhad/integrations/destination/pinecone_db/client.rb +154 -0
- data/lib/outhad/integrations/destination/pinecone_db/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/pinecone_db/config/spec.json +32 -0
- data/lib/outhad/integrations/destination/pinecone_db/icon.svg +1 -0
- data/lib/outhad/integrations/destination/postgresql/client.rb +130 -0
- data/lib/outhad/integrations/destination/postgresql/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/postgresql/config/spec.json +68 -0
- data/lib/outhad/integrations/destination/postgresql/icon.svg +20 -0
- data/lib/outhad/integrations/destination/qdrant/client.rb +184 -0
- data/lib/outhad/integrations/destination/qdrant/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/qdrant/config/spec.json +23 -0
- data/lib/outhad/integrations/destination/qdrant/icon.svg +1 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/client.rb +136 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/meta.json +16 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/config/spec.json +52 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/icon.svg +16 -0
- data/lib/outhad/integrations/destination/salesforce_consumer_goods_cloud/schema_helper.rb +132 -0
- data/lib/outhad/integrations/destination/salesforce_crm/client.rb +114 -0
- data/lib/outhad/integrations/destination/salesforce_crm/config/catalog.json +320 -0
- data/lib/outhad/integrations/destination/salesforce_crm/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/salesforce_crm/config/spec.json +46 -0
- data/lib/outhad/integrations/destination/salesforce_crm/icon.svg +16 -0
- data/lib/outhad/integrations/destination/sftp/client.rb +186 -0
- data/lib/outhad/integrations/destination/sftp/config/catalog.json +16 -0
- data/lib/outhad/integrations/destination/sftp/config/meta.json +16 -0
- data/lib/outhad/integrations/destination/sftp/config/spec.json +73 -0
- data/lib/outhad/integrations/destination/sftp/icon.svg +1 -0
- data/lib/outhad/integrations/destination/slack/client.rb +125 -0
- data/lib/outhad/integrations/destination/slack/config/catalog.json +22 -0
- data/lib/outhad/integrations/destination/slack/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/slack/config/spec.json +23 -0
- data/lib/outhad/integrations/destination/slack/icon.svg +26 -0
- data/lib/outhad/integrations/destination/stripe/client.rb +94 -0
- data/lib/outhad/integrations/destination/stripe/config/catalog.json +128 -0
- data/lib/outhad/integrations/destination/stripe/config/meta.json +15 -0
- data/lib/outhad/integrations/destination/stripe/config/spec.json +18 -0
- data/lib/outhad/integrations/destination/stripe/icon.svg +10 -0
- data/lib/outhad/integrations/destination/zendesk/client.rb +132 -0
- data/lib/outhad/integrations/destination/zendesk/config/catalog.json +110 -0
- data/lib/outhad/integrations/destination/zendesk/config/meta.json +18 -0
- data/lib/outhad/integrations/destination/zendesk/config/spec.json +32 -0
- data/lib/outhad/integrations/destination/zendesk/icon.svg +63 -0
- data/lib/outhad/integrations/protocol/protocol.json +189 -0
- data/lib/outhad/integrations/protocol/protocol.rb +228 -0
- data/lib/outhad/integrations/rollout.rb +66 -0
- data/lib/outhad/integrations/service.rb +55 -0
- data/lib/outhad/integrations/source/amazon_s3/client.rb +235 -0
- data/lib/outhad/integrations/source/amazon_s3/config/meta.json +16 -0
- data/lib/outhad/integrations/source/amazon_s3/config/spec.json +119 -0
- data/lib/outhad/integrations/source/amazon_s3/icon.svg +34 -0
- data/lib/outhad/integrations/source/anthropic/client.rb +135 -0
- data/lib/outhad/integrations/source/anthropic/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/anthropic/config/meta.json +16 -0
- data/lib/outhad/integrations/source/anthropic/config/spec.json +56 -0
- data/lib/outhad/integrations/source/anthropic/icon.svg +1 -0
- data/lib/outhad/integrations/source/aws_athena/client.rb +109 -0
- data/lib/outhad/integrations/source/aws_athena/config/meta.json +16 -0
- data/lib/outhad/integrations/source/aws_athena/config/spec.json +63 -0
- data/lib/outhad/integrations/source/aws_athena/icon.svg +22 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/client.rb +91 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/config/meta.json +16 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/config/spec.json +58 -0
- data/lib/outhad/integrations/source/aws_bedrock_model/icon.svg +1 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/client.rb +79 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/config/meta.json +16 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/config/spec.json +52 -0
- data/lib/outhad/integrations/source/aws_sagemaker_model/icon.svg +7 -0
- data/lib/outhad/integrations/source/bigquery/client.rb +98 -0
- data/lib/outhad/integrations/source/bigquery/config/meta.json +16 -0
- data/lib/outhad/integrations/source/bigquery/config/spec.json +83 -0
- data/lib/outhad/integrations/source/bigquery/icon.svg +1 -0
- data/lib/outhad/integrations/source/clickhouse/client.rb +102 -0
- data/lib/outhad/integrations/source/clickhouse/config/meta.json +16 -0
- data/lib/outhad/integrations/source/clickhouse/config/spec.json +42 -0
- data/lib/outhad/integrations/source/clickhouse/icon.svg +25 -0
- data/lib/outhad/integrations/source/databricks/client.rb +98 -0
- data/lib/outhad/integrations/source/databricks/config/meta.json +17 -0
- data/lib/outhad/integrations/source/databricks/config/spec.json +56 -0
- data/lib/outhad/integrations/source/databricks/icon.svg +19 -0
- data/lib/outhad/integrations/source/databrics_model/client.rb +89 -0
- data/lib/outhad/integrations/source/databrics_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/databrics_model/config/meta.json +17 -0
- data/lib/outhad/integrations/source/databrics_model/config/spec.json +63 -0
- data/lib/outhad/integrations/source/databrics_model/icon.svg +19 -0
- data/lib/outhad/integrations/source/firecrawl/client.rb +151 -0
- data/lib/outhad/integrations/source/firecrawl/config/catalog.json +29 -0
- data/lib/outhad/integrations/source/firecrawl/config/meta.json +17 -0
- data/lib/outhad/integrations/source/firecrawl/config/spec.json +31 -0
- data/lib/outhad/integrations/source/firecrawl/icon.svg +4 -0
- data/lib/outhad/integrations/source/generic_open_ai/client.rb +118 -0
- data/lib/outhad/integrations/source/generic_open_ai/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/generic_open_ai/config/meta.json +16 -0
- data/lib/outhad/integrations/source/generic_open_ai/config/spec.json +63 -0
- data/lib/outhad/integrations/source/generic_open_ai/icon.svg +6 -0
- data/lib/outhad/integrations/source/google_vertex_model/client.rb +83 -0
- data/lib/outhad/integrations/source/google_vertex_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/google_vertex_model/config/meta.json +17 -0
- data/lib/outhad/integrations/source/google_vertex_model/config/spec.json +105 -0
- data/lib/outhad/integrations/source/google_vertex_model/icon.svg +2 -0
- data/lib/outhad/integrations/source/http_model/client.rb +108 -0
- data/lib/outhad/integrations/source/http_model/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/http_model/config/meta.json +16 -0
- data/lib/outhad/integrations/source/http_model/config/spec.json +70 -0
- data/lib/outhad/integrations/source/http_model/icon.svg +9 -0
- data/lib/outhad/integrations/source/intuit_quick_books/client.rb +213 -0
- data/lib/outhad/integrations/source/intuit_quick_books/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/intuit_quick_books/config/meta.json +17 -0
- data/lib/outhad/integrations/source/intuit_quick_books/config/spec.json +44 -0
- data/lib/outhad/integrations/source/intuit_quick_books/icon.svg +1 -0
- data/lib/outhad/integrations/source/maria_db/client.rb +92 -0
- data/lib/outhad/integrations/source/maria_db/config/meta.json +16 -0
- data/lib/outhad/integrations/source/maria_db/config/spec.json +48 -0
- data/lib/outhad/integrations/source/maria_db/icon.svg +15 -0
- data/lib/outhad/integrations/source/odoo/client.rb +106 -0
- data/lib/outhad/integrations/source/odoo/config/meta.json +15 -0
- data/lib/outhad/integrations/source/odoo/config/spec.json +39 -0
- data/lib/outhad/integrations/source/odoo/icon.svg +21 -0
- data/lib/outhad/integrations/source/open_ai/client.rb +118 -0
- data/lib/outhad/integrations/source/open_ai/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/open_ai/config/meta.json +16 -0
- data/lib/outhad/integrations/source/open_ai/config/spec.json +56 -0
- data/lib/outhad/integrations/source/open_ai/icon.svg +1 -0
- data/lib/outhad/integrations/source/oracle_db/client.rb +127 -0
- data/lib/outhad/integrations/source/oracle_db/config/meta.json +16 -0
- data/lib/outhad/integrations/source/oracle_db/config/spec.json +47 -0
- data/lib/outhad/integrations/source/oracle_db/icon.svg +4 -0
- data/lib/outhad/integrations/source/pinecone_db/client.rb +73 -0
- data/lib/outhad/integrations/source/pinecone_db/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/pinecone_db/config/meta.json +16 -0
- data/lib/outhad/integrations/source/pinecone_db/config/spec.json +34 -0
- data/lib/outhad/integrations/source/pinecone_db/icon.svg +2 -0
- data/lib/outhad/integrations/source/postgresql/client.rb +112 -0
- data/lib/outhad/integrations/source/postgresql/config/meta.json +16 -0
- data/lib/outhad/integrations/source/postgresql/config/spec.json +86 -0
- data/lib/outhad/integrations/source/postgresql/icon.svg +20 -0
- data/lib/outhad/integrations/source/qdrant/client.rb +86 -0
- data/lib/outhad/integrations/source/qdrant/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/qdrant/config/meta.json +16 -0
- data/lib/outhad/integrations/source/qdrant/config/spec.json +29 -0
- data/lib/outhad/integrations/source/qdrant/icon.svg +1 -0
- data/lib/outhad/integrations/source/redshift/client.rb +109 -0
- data/lib/outhad/integrations/source/redshift/config/meta.json +16 -0
- data/lib/outhad/integrations/source/redshift/config/spec.json +71 -0
- data/lib/outhad/integrations/source/redshift/icon.svg +15 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/client.rb +133 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/meta.json +18 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/config/spec.json +53 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/icon.svg +16 -0
- data/lib/outhad/integrations/source/salesforce_consumer_goods_cloud/schema_helper.rb +130 -0
- data/lib/outhad/integrations/source/sftp/client.rb +133 -0
- data/lib/outhad/integrations/source/sftp/config/meta.json +16 -0
- data/lib/outhad/integrations/source/sftp/config/spec.json +59 -0
- data/lib/outhad/integrations/source/sftp/icon.svg +1 -0
- data/lib/outhad/integrations/source/snowflake/client.rb +92 -0
- data/lib/outhad/integrations/source/snowflake/config/meta.json +16 -0
- data/lib/outhad/integrations/source/snowflake/config/spec.json +82 -0
- data/lib/outhad/integrations/source/snowflake/icon.svg +10 -0
- data/lib/outhad/integrations/source/watsonx_ai/client.rb +194 -0
- data/lib/outhad/integrations/source/watsonx_ai/config/catalog.json +6 -0
- data/lib/outhad/integrations/source/watsonx_ai/config/meta.json +16 -0
- data/lib/outhad/integrations/source/watsonx_ai/config/spec.json +74 -0
- data/lib/outhad/integrations/source/watsonx_ai/icon.svg +1 -0
- data/lib/outhad/integrations/source/watsonx_data/client.rb +146 -0
- data/lib/outhad/integrations/source/watsonx_data/config/meta.json +17 -0
- data/lib/outhad/integrations/source/watsonx_data/config/spec.json +72 -0
- data/lib/outhad/integrations/source/watsonx_data/icon.svg +1 -0
- data/lib/outhad/integrations.rb +129 -0
- data/outhad-integrations.gemspec +79 -0
- data/sig/outhad/integrations.rbs +6 -0
- metadata +866 -0
@@ -0,0 +1,228 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Outhad
|
4
|
+
module Integrations::Protocol
|
5
|
+
module Types
|
6
|
+
include Dry.Types()
|
7
|
+
end
|
8
|
+
|
9
|
+
SyncMode = Types::String.enum("full_refresh", "incremental")
|
10
|
+
SyncStatus = Types::String.enum("started", "running", "complete", "incomplete")
|
11
|
+
DestinationSyncMode = Types::String.enum("insert", "upsert")
|
12
|
+
ConnectorType = Types::String.enum("source", "destination")
|
13
|
+
ConnectorQueryType = Types::String.enum("raw_sql", "soql", "ai_ml", "vector_search")
|
14
|
+
ModelQueryType = Types::String.enum("raw_sql", "dbt", "soql", "table_selector", "ai_ml", "dynamic_sql", "unstructured", "vector_search")
|
15
|
+
ConnectionStatusType = Types::String.enum("succeeded", "failed")
|
16
|
+
StreamType = Types::String.enum("static", "dynamic", "user_defined")
|
17
|
+
StreamAction = Types::String.enum("fetch", "create", "update", "delete")
|
18
|
+
OuthadMessageType = Types::String.enum(
|
19
|
+
"record", "log", "connector_spec",
|
20
|
+
"connection_status", "catalog", "control",
|
21
|
+
"tracking"
|
22
|
+
)
|
23
|
+
ControlMessageType = Types::String.enum(
|
24
|
+
"rate_limit", "connection_config", "full_refresh"
|
25
|
+
)
|
26
|
+
LogLevel = Types::String.enum("fatal", "error", "warn", "info", "debug", "trace")
|
27
|
+
RequestRateLimitingUnit = Types::String.default("minute").enum("minute", "hour", "day")
|
28
|
+
SchemaMode = Types::String.enum("schema", "schemaless")
|
29
|
+
FileFormatType = Types::String.enum("csv")
|
30
|
+
CompressionType = Types::String.enum("un_compressed", "zip")
|
31
|
+
|
32
|
+
class ProtocolModel < Dry::Struct
|
33
|
+
extend Outhad::Integrations::Core::Utils
|
34
|
+
class << self
|
35
|
+
def from_json(json_string)
|
36
|
+
data = JSON.parse(json_string)
|
37
|
+
new(keys_to_symbols(data))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class ConnectionStatus < ProtocolModel
|
43
|
+
attribute :status, ConnectionStatusType
|
44
|
+
attribute? :message, Types::String.optional
|
45
|
+
|
46
|
+
def to_outhad_message
|
47
|
+
OuthadMessage.new(
|
48
|
+
type: OuthadMessageType["connection_status"],
|
49
|
+
connection_status: self
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class ConnectorSpecification < ProtocolModel
|
55
|
+
attribute? :documentation_url, Types::String.optional
|
56
|
+
attribute? :changelog_url, Types::String.optional
|
57
|
+
attribute :connection_specification, Types::Hash
|
58
|
+
attribute :supports_normalization, Types::Bool.default(false)
|
59
|
+
attribute :supports_dbt, Types::Bool.default(false)
|
60
|
+
attribute :stream_type, StreamType
|
61
|
+
attribute? :supported_destination_sync_modes, Types::Array.of(DestinationSyncMode).optional
|
62
|
+
attribute? :connector_query_type, ConnectorQueryType
|
63
|
+
|
64
|
+
def to_outhad_message
|
65
|
+
OuthadMessage.new(
|
66
|
+
type: OuthadMessageType["connector_spec"],
|
67
|
+
connector_spec: self
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Connector < ProtocolModel
|
73
|
+
attribute :name, Types::String
|
74
|
+
attribute :type, ConnectorType
|
75
|
+
attribute :connection_specification, Types::Hash
|
76
|
+
attribute :connector_instance, Types::Any.optional.default(nil)
|
77
|
+
attribute :query_type, Types::String.default("raw_sql").enum(*ConnectorQueryType.values)
|
78
|
+
end
|
79
|
+
|
80
|
+
class LogMessage < ProtocolModel
|
81
|
+
attribute :level, LogLevel
|
82
|
+
attribute :message, Types::String
|
83
|
+
attribute? :name, Types::String.optional
|
84
|
+
attribute? :stack_trace, Types::String.optional
|
85
|
+
|
86
|
+
def to_outhad_message
|
87
|
+
OuthadMessage.new(
|
88
|
+
type: OuthadMessageType["log"],
|
89
|
+
log: self
|
90
|
+
)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Model < ProtocolModel
|
95
|
+
attribute? :name, Types::String.optional
|
96
|
+
attribute :query, Types::String
|
97
|
+
attribute :query_type, ModelQueryType
|
98
|
+
attribute :primary_key, Types::String
|
99
|
+
end
|
100
|
+
|
101
|
+
class RecordMessage < ProtocolModel
|
102
|
+
attribute :data, Types::Hash
|
103
|
+
attribute :emitted_at, Types::Integer
|
104
|
+
|
105
|
+
def to_outhad_message
|
106
|
+
OuthadMessage.new(
|
107
|
+
type: OuthadMessageType["record"],
|
108
|
+
record: self
|
109
|
+
)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class Stream < ProtocolModel
|
114
|
+
# Common
|
115
|
+
attribute :name, Types::String
|
116
|
+
attribute? :action, StreamAction
|
117
|
+
attribute :json_schema, Types::Hash
|
118
|
+
attribute? :supported_sync_modes, Types::Array.of(SyncMode).optional.default(["incremental"])
|
119
|
+
|
120
|
+
# Applicable for database streams
|
121
|
+
attribute :source_defined_cursor, Types::Bool.default(false)
|
122
|
+
attribute? :default_cursor_field, Types::Array.of(Types::String).optional
|
123
|
+
attribute? :source_defined_primary_key, Types::Array.of(Types::Array.of(Types::String)).optional
|
124
|
+
attribute? :namespace, Types::String.optional
|
125
|
+
# Applicable for API streams
|
126
|
+
attribute? :url, Types::String.optional
|
127
|
+
attribute? :request_method, Types::String.optional
|
128
|
+
attribute :batch_support, Types::Bool.default(false)
|
129
|
+
attribute :batch_size, Types::Integer.default(1)
|
130
|
+
# Rate limits
|
131
|
+
attribute? :request_rate_limit, Types::Integer
|
132
|
+
attribute? :request_rate_limit_unit, RequestRateLimitingUnit
|
133
|
+
attribute? :request_rate_concurrency, Types::Integer
|
134
|
+
|
135
|
+
def rate_limit_unit_seconds
|
136
|
+
case request_rate_limit_unit
|
137
|
+
when "minute"
|
138
|
+
60 # Seconds in a minute
|
139
|
+
when "hour"
|
140
|
+
3600 # Seconds in an hour
|
141
|
+
when "day"
|
142
|
+
86_400 # Seconds in a day
|
143
|
+
else
|
144
|
+
1 # Default case, consider as seconds or handle as error
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class Catalog < ProtocolModel
|
150
|
+
attribute :streams, Types::Array.of(Stream)
|
151
|
+
|
152
|
+
# Rate limits
|
153
|
+
attribute? :request_rate_limit, Types::Integer.default(60)
|
154
|
+
attribute? :request_rate_limit_unit, RequestRateLimitingUnit
|
155
|
+
attribute? :request_rate_concurrency, Types::Integer.default(10)
|
156
|
+
attribute? :schema_mode, Types::String.optional.default("schema")
|
157
|
+
attribute :source_defined_cursor, Types::Bool.default(false)
|
158
|
+
attribute? :default_cursor_field, Types::Array.of(Types::String).optional
|
159
|
+
|
160
|
+
def to_outhad_message
|
161
|
+
OuthadMessage.new(
|
162
|
+
type: OuthadMessageType["catalog"],
|
163
|
+
catalog: self
|
164
|
+
)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
class SyncConfig < ProtocolModel
|
169
|
+
attr_accessor :offset, :limit, :sync_run_id
|
170
|
+
|
171
|
+
attribute :source, Connector
|
172
|
+
attribute :destination, Connector
|
173
|
+
attribute :model, Model
|
174
|
+
attribute :stream, Stream
|
175
|
+
attribute :sync_mode, SyncMode
|
176
|
+
attribute? :cursor_field, Types::String.optional
|
177
|
+
attribute? :current_cursor_field, Types::String.optional
|
178
|
+
attribute :destination_sync_mode, DestinationSyncMode
|
179
|
+
# reference ids
|
180
|
+
attribute :sync_id, Types::String.default("unknown")
|
181
|
+
end
|
182
|
+
|
183
|
+
class VectorConfig < ProtocolModel
|
184
|
+
attribute :source, Connector
|
185
|
+
attribute :vector, Types::Array.of(Types::Float)
|
186
|
+
attribute :limit, Types::Integer.default(1)
|
187
|
+
end
|
188
|
+
|
189
|
+
class ControlMessage < ProtocolModel
|
190
|
+
attribute :type, ControlMessageType
|
191
|
+
attribute :emitted_at, Types::Integer
|
192
|
+
attribute? :status, ConnectionStatusType.optional
|
193
|
+
attribute? :meta, Types::Hash
|
194
|
+
|
195
|
+
def to_outhad_message
|
196
|
+
OuthadMessage.new(
|
197
|
+
type: OuthadMessageType["control"],
|
198
|
+
control: self
|
199
|
+
)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
class TrackingMessage < ProtocolModel
|
204
|
+
attribute :success, Types::Integer.default(0)
|
205
|
+
attribute :failed, Types::Integer.default(0)
|
206
|
+
attribute? :meta, Types::Hash
|
207
|
+
attribute? :logs, Types::Array.of(LogMessage)
|
208
|
+
|
209
|
+
def to_outhad_message
|
210
|
+
OuthadMessage.new(
|
211
|
+
type: OuthadMessageType["tracking"],
|
212
|
+
tracking: self
|
213
|
+
)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
class OuthadMessage < ProtocolModel
|
218
|
+
attribute :type, OuthadMessageType
|
219
|
+
attribute? :log, LogMessage.optional
|
220
|
+
attribute? :connection_status, ConnectionStatus.optional
|
221
|
+
attribute? :connector_spec, ConnectorSpecification.optional
|
222
|
+
attribute? :catalog, Catalog.optional
|
223
|
+
attribute? :record, RecordMessage.optional
|
224
|
+
attribute? :control, ControlMessage.optional
|
225
|
+
attribute? :tracking, TrackingMessage.optional
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Outhad
|
4
|
+
module Integrations
|
5
|
+
VERSION = "0.32.0"
|
6
|
+
|
7
|
+
ENABLED_SOURCES = %w[
|
8
|
+
Snowflake
|
9
|
+
Redshift
|
10
|
+
Bigquery
|
11
|
+
Postgresql
|
12
|
+
Databricks
|
13
|
+
SalesforceConsumerGoodsCloud
|
14
|
+
AwsAthena
|
15
|
+
Clickhouse
|
16
|
+
AmazonS3
|
17
|
+
MariaDB
|
18
|
+
Oracle
|
19
|
+
DatabricksModel
|
20
|
+
AwsSagemakerModel
|
21
|
+
VertexModel
|
22
|
+
HttpModel
|
23
|
+
OpenAI
|
24
|
+
Sftp
|
25
|
+
WatsonxAi
|
26
|
+
WatsonxData
|
27
|
+
Anthropic
|
28
|
+
AwsBedrockModel
|
29
|
+
GenericOpenAI
|
30
|
+
IntuitQuickBooks
|
31
|
+
PineconeDB
|
32
|
+
Qdrant
|
33
|
+
Firecrawl
|
34
|
+
Odoo
|
35
|
+
].freeze
|
36
|
+
|
37
|
+
ENABLED_DESTINATIONS = %w[
|
38
|
+
Klaviyo
|
39
|
+
SalesforceCrm
|
40
|
+
FacebookCustomAudience
|
41
|
+
Slack
|
42
|
+
Hubspot
|
43
|
+
GoogleSheets
|
44
|
+
Airtable
|
45
|
+
Stripe
|
46
|
+
SalesforceConsumerGoodsCloud
|
47
|
+
Sftp
|
48
|
+
Postgresql
|
49
|
+
Zendesk
|
50
|
+
Http
|
51
|
+
Iterable
|
52
|
+
MariaDB
|
53
|
+
DatabricksLakehouse
|
54
|
+
Oracle
|
55
|
+
MicrosoftExcel
|
56
|
+
MicrosoftSql
|
57
|
+
Mailchimp
|
58
|
+
AISDataStore
|
59
|
+
AmazonS3
|
60
|
+
MicrosoftDynamics
|
61
|
+
Qdrant
|
62
|
+
PineconeDB
|
63
|
+
Odoo
|
64
|
+
].freeze
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Outhad
|
4
|
+
module Integrations
|
5
|
+
class Service
|
6
|
+
def initialize
|
7
|
+
yield(self.class.config) if block_given?
|
8
|
+
end
|
9
|
+
class << self
|
10
|
+
def connectors
|
11
|
+
{
|
12
|
+
source: build_connectors(
|
13
|
+
ENABLED_SOURCES, "Source"
|
14
|
+
),
|
15
|
+
destination: build_connectors(
|
16
|
+
ENABLED_DESTINATIONS, "Destination"
|
17
|
+
)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def connector_class(connector_type, connector_name)
|
22
|
+
Object.const_get(
|
23
|
+
"Outhad::Integrations::#{connector_type}::#{connector_name}::Client"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def logger
|
28
|
+
config.logger || default_logger
|
29
|
+
end
|
30
|
+
|
31
|
+
def exception_reporter
|
32
|
+
config.exception_reporter
|
33
|
+
end
|
34
|
+
|
35
|
+
def config
|
36
|
+
@config ||= Config.new
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def build_connectors(enabled_connectors, type)
|
42
|
+
enabled_connectors.map do |connector|
|
43
|
+
client = connector_class(type, connector).new
|
44
|
+
client.meta_data[:data][:connector_spec] = client.connector_spec.to_h
|
45
|
+
client.meta_data[:data]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def default_logger
|
50
|
+
@default_logger ||= Logger.new($stdout)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,235 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Outhad::Integrations::Source
|
4
|
+
module AmazonS3
|
5
|
+
include Outhad::Integrations::Core
|
6
|
+
class Client < UnstructuredSourceConnector
|
7
|
+
@session_name = ""
|
8
|
+
|
9
|
+
def check_connection(connection_config)
|
10
|
+
connection_config = connection_config.with_indifferent_access
|
11
|
+
@session_name = "connection-#{connection_config[:region]}-#{connection_config[:bucket]}"
|
12
|
+
|
13
|
+
if unstructured_data?(connection_config)
|
14
|
+
create_s3_connection(connection_config)
|
15
|
+
@s3_resource.bucket(connection_config[:bucket]).objects.limit(1).first
|
16
|
+
else
|
17
|
+
conn = create_connection(connection_config)
|
18
|
+
path = build_path(connection_config)
|
19
|
+
get_results(conn, "DESCRIBE SELECT * FROM '#{path}';")
|
20
|
+
end
|
21
|
+
ConnectionStatus.new(status: ConnectionStatusType["succeeded"]).to_outhad_message
|
22
|
+
rescue StandardError => e
|
23
|
+
ConnectionStatus.new(status: ConnectionStatusType["failed"], message: e.message).to_outhad_message
|
24
|
+
end
|
25
|
+
|
26
|
+
def discover(connection_config)
|
27
|
+
connection_config = connection_config.with_indifferent_access
|
28
|
+
@session_name = "discover-#{connection_config[:region]}-#{connection_config[:bucket]}"
|
29
|
+
|
30
|
+
streams = if unstructured_data?(connection_config)
|
31
|
+
[create_unstructured_stream]
|
32
|
+
else
|
33
|
+
conn = create_connection(connection_config)
|
34
|
+
# If pulling from multiple files, all files must have the same schema
|
35
|
+
path = build_path(connection_config)
|
36
|
+
records = get_results(conn, "DESCRIBE SELECT * FROM '#{path}';")
|
37
|
+
columns = build_discover_columns(records)
|
38
|
+
[Outhad::Integrations::Protocol::Stream.new(name: path, action: StreamAction["fetch"], json_schema: convert_to_json_schema(columns))]
|
39
|
+
end
|
40
|
+
catalog = Catalog.new(streams: streams)
|
41
|
+
catalog.to_outhad_message
|
42
|
+
rescue StandardError => e
|
43
|
+
handle_exception(e, { context: "AMAZONS3:DISCOVER:EXCEPTION", type: "error" })
|
44
|
+
end
|
45
|
+
|
46
|
+
def read(sync_config)
|
47
|
+
connection_config = sync_config.source.connection_specification.with_indifferent_access
|
48
|
+
@session_name = "#{sync_config.sync_id}-#{sync_config.source.name}-#{sync_config.destination.name}"
|
49
|
+
|
50
|
+
return handle_unstructured_data(sync_config) if unstructured_data?(connection_config)
|
51
|
+
|
52
|
+
conn = create_connection(connection_config)
|
53
|
+
query = sync_config.model.query
|
54
|
+
query = batched_query(query, sync_config.limit, sync_config.offset) unless sync_config.limit.nil? && sync_config.offset.nil?
|
55
|
+
query(conn, query)
|
56
|
+
rescue StandardError => e
|
57
|
+
handle_exception(e, {
|
58
|
+
context: "AMAZONS3:READ:EXCEPTION",
|
59
|
+
type: "error",
|
60
|
+
sync_id: sync_config.sync_id,
|
61
|
+
sync_run_id: sync_config.sync_run_id
|
62
|
+
})
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def get_auth_data(connection_config)
|
68
|
+
session = @session_name.gsub(/\s+/, "-")
|
69
|
+
@session_name = ""
|
70
|
+
if connection_config[:auth_type] == "user"
|
71
|
+
Aws::Credentials.new(connection_config[:access_id], connection_config[:secret_access])
|
72
|
+
elsif connection_config[:auth_type] == "role"
|
73
|
+
sts_client = Aws::STS::Client.new(region: connection_config[:region])
|
74
|
+
resp = sts_client.assume_role({
|
75
|
+
role_arn: connection_config[:arn],
|
76
|
+
role_session_name: session,
|
77
|
+
external_id: connection_config[:external_id]
|
78
|
+
})
|
79
|
+
Aws::Credentials.new(
|
80
|
+
resp.credentials.access_key_id,
|
81
|
+
resp.credentials.secret_access_key,
|
82
|
+
resp.credentials.session_token
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_s3_connection(connection_config)
|
88
|
+
connection_config = connection_config.with_indifferent_access
|
89
|
+
|
90
|
+
# Get authentication credentials
|
91
|
+
auth_data = get_auth_data(connection_config)
|
92
|
+
|
93
|
+
# Create S3 resource for easier operations
|
94
|
+
@s3_resource = Aws::S3::Resource.new(
|
95
|
+
region: connection_config[:region],
|
96
|
+
credentials: auth_data
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
def create_connection(connection_config)
|
101
|
+
# In the case when previewing a query
|
102
|
+
@session_name = "preview-#{connection_config[:region]}-#{connection_config[:bucket]}" if @session_name.to_s.empty?
|
103
|
+
auth_data = get_auth_data(connection_config)
|
104
|
+
conn = DuckDB::Database.open.connect
|
105
|
+
# Install and/or Load the HTTPFS extension
|
106
|
+
conn.execute(INSTALL_HTTPFS_QUERY)
|
107
|
+
# Set up S3 configuration
|
108
|
+
secret_query = "
|
109
|
+
CREATE SECRET amazons3_source (
|
110
|
+
TYPE S3,
|
111
|
+
KEY_ID '#{auth_data.credentials.access_key_id}',
|
112
|
+
SECRET '#{auth_data.credentials.secret_access_key}',
|
113
|
+
REGION '#{connection_config[:region]}',
|
114
|
+
SESSION_TOKEN '#{auth_data.credentials.session_token}'
|
115
|
+
);
|
116
|
+
"
|
117
|
+
get_results(conn, secret_query)
|
118
|
+
conn
|
119
|
+
end
|
120
|
+
|
121
|
+
def build_path(connection_config)
|
122
|
+
path = connection_config[:path]
|
123
|
+
path = "#{path}/" if path.to_s.strip.empty? || path[-1] != "/"
|
124
|
+
"s3://#{connection_config[:bucket]}#{path}*.#{connection_config[:file_type]}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def get_results(conn, query)
|
128
|
+
results = conn.query(query)
|
129
|
+
hash_array_values(results)
|
130
|
+
end
|
131
|
+
|
132
|
+
def query(conn, query)
|
133
|
+
records = get_results(conn, query)
|
134
|
+
records.map do |row|
|
135
|
+
RecordMessage.new(data: row, emitted_at: Time.now.to_i).to_outhad_message
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def hash_array_values(describe)
|
140
|
+
keys = describe.columns.map(&:name)
|
141
|
+
describe.map do |row|
|
142
|
+
Hash[keys.zip(row)]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def build_discover_columns(describe_results)
|
147
|
+
describe_results.map do |row|
|
148
|
+
type = column_schema_helper(row["column_type"])
|
149
|
+
{
|
150
|
+
column_name: row["column_name"],
|
151
|
+
type: type
|
152
|
+
}
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def column_schema_helper(column_type)
|
157
|
+
case column_type
|
158
|
+
when "VARCHAR", "BIT", "DATE", "TIME", "TIMESTAMP", "UUID"
|
159
|
+
"string"
|
160
|
+
when "DOUBLE"
|
161
|
+
"number"
|
162
|
+
when "BIGINT", "HUGEINT", "INTEGER", "SMALLINT"
|
163
|
+
"integer"
|
164
|
+
when "BOOLEAN"
|
165
|
+
"boolean"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def handle_unstructured_data(sync_config)
|
170
|
+
connection_config = sync_config.source.connection_specification.with_indifferent_access
|
171
|
+
bucket_name = connection_config[:bucket]
|
172
|
+
command = sync_config.model.query.strip
|
173
|
+
create_s3_connection(connection_config)
|
174
|
+
|
175
|
+
case command
|
176
|
+
when LIST_FILES_CMD
|
177
|
+
list_files_in_folder(bucket_name, connection_config[:path] || "")
|
178
|
+
when /^#{DOWNLOAD_FILE_CMD}\s+(.+)$/
|
179
|
+
# Extract the file path and remove surrounding quotes if present
|
180
|
+
file_path = ::Regexp.last_match(1).strip
|
181
|
+
file_path = file_path.gsub(/^["']|["']$/, "") # Remove leading/trailing quotes
|
182
|
+
download_file_to_local(bucket_name, file_path, sync_config.sync_id)
|
183
|
+
else
|
184
|
+
raise "Invalid command. Supported commands: #{LIST_FILES_CMD}, #{DOWNLOAD_FILE_CMD} <file_path>"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def list_files_in_folder(bucket_name, folder_path)
|
189
|
+
folder_path = folder_path.end_with?("/") ? folder_path : "#{folder_path}/"
|
190
|
+
bucket = @s3_resource.bucket(bucket_name)
|
191
|
+
|
192
|
+
bucket.objects(prefix: folder_path).reject { |object| object.key == folder_path }.map do |object|
|
193
|
+
RecordMessage.new(
|
194
|
+
data: {
|
195
|
+
file_name: File.basename(object.key),
|
196
|
+
file_path: object.key,
|
197
|
+
size: object.content_length,
|
198
|
+
file_type: File.extname(object.key).sub(".", ""),
|
199
|
+
created_date: object.last_modified.to_s,
|
200
|
+
modified_date: object.last_modified.to_s
|
201
|
+
},
|
202
|
+
emitted_at: Time.now.to_i
|
203
|
+
).to_outhad_message
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def download_file_to_local(bucket_name, file_path, sync_id)
|
208
|
+
download_path = ENV["FILE_DOWNLOAD_PATH"]
|
209
|
+
file = if download_path
|
210
|
+
File.join(download_path, "syncs", sync_id, File.basename(file_path))
|
211
|
+
else
|
212
|
+
Tempfile.new(["s3_file", "syncs", sync_id, File.extname(file_path)]).path
|
213
|
+
end
|
214
|
+
|
215
|
+
object = @s3_resource.bucket(bucket_name).object(file_path)
|
216
|
+
object.get(response_target: file)
|
217
|
+
|
218
|
+
[RecordMessage.new(
|
219
|
+
data: {
|
220
|
+
local_path: file,
|
221
|
+
file_name: File.basename(file_path),
|
222
|
+
file_path: file_path,
|
223
|
+
size: object.content_length,
|
224
|
+
file_type: File.extname(file_path).sub(".", ""),
|
225
|
+
modified_date: object.last_modified.to_s,
|
226
|
+
created_date: object.last_modified.to_s
|
227
|
+
},
|
228
|
+
emitted_at: Time.now.to_i
|
229
|
+
).to_outhad_message]
|
230
|
+
rescue Aws::S3::Errors::NoSuchKey
|
231
|
+
raise "File not found: #{file_path}"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"data": {
|
3
|
+
"name": "AmazonS3",
|
4
|
+
"title": "Amazon S3",
|
5
|
+
"connector_type": "source",
|
6
|
+
"category": "Data Lake",
|
7
|
+
"sub_category": "Relational Database",
|
8
|
+
"documentation_url": "https://docs.squared.ai/guides/sources/data-sources/amazon_s3",
|
9
|
+
"github_issue_label": "source-amazons3",
|
10
|
+
"icon": "icon.svg",
|
11
|
+
"license": "MIT",
|
12
|
+
"release_stage": "alpha",
|
13
|
+
"support_level": "community",
|
14
|
+
"tags": ["language:ruby", "outhad"]
|
15
|
+
}
|
16
|
+
}
|