multiwoven-integrations 0.1.63 → 0.1.65

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d27c9915ed80faa33f88467a0dddfaeda4c5c91560ca7b94ba9970ece2430bb5
4
- data.tar.gz: abefc5bb7771864fe8d1e4b6aee4810fa4f36e8db507c634f99d2546cae46df1
3
+ metadata.gz: 11fafa89e8f7adc1648906c3fa57fecb422d64a502d829e5fd437f7ed48169a2
4
+ data.tar.gz: fc3646918312c3293349d47598f1067f17a8614b0f6dc926c05f581642098d30
5
5
  SHA512:
6
- metadata.gz: e39874d8fce8e065b862a460b84e7e35ca8cef3c1a897a507c6590feb39d45c4ec5a1b4c4ee206f9b7ce8e5763a5cfe77ea4b60ed4861e9f97b83c75ce40f37d
7
- data.tar.gz: 251d70c151bc3bcb39bc5d3e20464dbc351353dd814b370f45631b3f58ae586ba1e21ab277d67b89943ad5905623a1aa0eb64629ebd0049ec6a774374fe55d41
6
+ metadata.gz: e885c02a7fce0cd2032b2874a4ca0c0967f358e4a45ebf7b70d2c0211f75772e76432c9b8d9968d0bcd46d5d00c466d920043660ac3d9ce9db6f35722d9b4d23
7
+ data.tar.gz: af7ef1ee3ab3c78c2378a0635d35acaaed0a0cbaa36a146391844bb1ca1fd436a0494ea0a96178b57cb03ee3bcc6ca377a4698ee85b29de222a14473c9db5890
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Multiwoven
4
+ module Integrations
5
+ module Destination
6
+ module Http
7
+ include Multiwoven::Integrations::Core
8
+ class Client < DestinationConnector
9
+ MAX_CHUNK_SIZE = 10
10
+ def check_connection(connection_config)
11
+ connection_config = connection_config.with_indifferent_access
12
+ destination_url = connection_config[:destination_url]
13
+ headers = connection_config[:headers]
14
+ request = Multiwoven::Integrations::Core::HttpClient.request(
15
+ destination_url,
16
+ HTTP_POST,
17
+ payload: {},
18
+ headers: headers
19
+ )
20
+ if success?(request)
21
+ success_status
22
+ else
23
+ failure_status(nil)
24
+ end
25
+ rescue StandardError => e
26
+ handle_exception("HTTP:CHECK_CONNECTION:EXCEPTION", "error", e)
27
+ failure_status(e)
28
+ end
29
+
30
+ def discover(_connection_config = nil)
31
+ catalog_json = read_json(CATALOG_SPEC_PATH)
32
+ catalog = build_catalog(catalog_json)
33
+ catalog.to_multiwoven_message
34
+ rescue StandardError => e
35
+ handle_exception(
36
+ "HTTP:DISCOVER:EXCEPTION",
37
+ "error",
38
+ e
39
+ )
40
+ end
41
+
42
+ def write(sync_config, records, _action = "create")
43
+ connection_config = sync_config.destination.connection_specification.with_indifferent_access
44
+ url = connection_config[:destination_url]
45
+ headers = connection_config[:headers]
46
+ write_success = 0
47
+ write_failure = 0
48
+ records.each_slice(MAX_CHUNK_SIZE) do |chunk|
49
+ payload = create_payload(chunk)
50
+ response = Multiwoven::Integrations::Core::HttpClient.request(
51
+ url,
52
+ sync_config.stream.request_method,
53
+ payload: payload,
54
+ headers: headers
55
+ )
56
+ if success?(response)
57
+ write_success += chunk.size
58
+ else
59
+ write_failure += chunk.size
60
+ end
61
+ rescue StandardError => e
62
+ handle_exception("HTTP:RECORD:WRITE:EXCEPTION", "error", e)
63
+ write_failure += chunk.size
64
+ end
65
+
66
+ tracker = Multiwoven::Integrations::Protocol::TrackingMessage.new(
67
+ success: write_success,
68
+ failed: write_failure
69
+ )
70
+ tracker.to_multiwoven_message
71
+ rescue StandardError => e
72
+ handle_exception("HTTP:WRITE:EXCEPTION", "error", e)
73
+ end
74
+
75
+ private
76
+
77
+ def create_payload(records)
78
+ {
79
+ "records" => records.map do |record|
80
+ {
81
+ "fields" => record
82
+ }
83
+ end
84
+ }
85
+ end
86
+
87
+ def extract_body(response)
88
+ response_body = response.body
89
+ JSON.parse(response_body) if response_body
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,16 @@
1
+ {
2
+ "request_rate_limit": 600,
3
+ "request_rate_limit_unit": "minute",
4
+ "request_rate_concurrency": 10,
5
+ "schema_mode": "schemaless",
6
+ "streams": [
7
+ {
8
+ "name": "http",
9
+ "batch_support": false,
10
+ "action": "create",
11
+ "method": "POST",
12
+ "json_schema": {},
13
+ "supported_sync_modes": ["incremental"]
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "data": {
3
+ "name": "Http",
4
+ "title": "http",
5
+ "connector_type": "destination",
6
+ "category": "Http",
7
+ "documentation_url": "https://docs.multiwoven.com/destinations/http",
8
+ "github_issue_label": "destination-http",
9
+ "icon": "icon.svg",
10
+ "license": "MIT",
11
+ "release_stage": "alpha",
12
+ "support_level": "community",
13
+ "tags": ["language:ruby", "multiwoven"]
14
+ }
15
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "documentation_url": "https://docs.multiwoven.com/integrations/destination/http",
3
+ "stream_type": "static",
4
+ "connection_specification": {
5
+ "$schema": "http://json-schema.org/draft-07/schema#",
6
+ "title": "Http",
7
+ "type": "object",
8
+ "required": ["destination_url"],
9
+ "properties": {
10
+ "destination_url": {
11
+ "type": "string",
12
+ "title": "Destination url",
13
+ "order": 0
14
+ },
15
+ "headers": {
16
+ "title": "Http Headers",
17
+ "order": 1,
18
+ "additionalProperties": {
19
+ "type": "string"
20
+ }
21
+ }
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+
3
+ <svg width="800px" height="800px" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none">
4
+
5
+
6
+
7
+
8
+
9
+
@@ -39,27 +39,58 @@ module Multiwoven::Integrations::Destination
39
39
  file_path = generate_file_path(sync_config)
40
40
  local_file_name = generate_local_file_name(sync_config)
41
41
  csv_content = generate_csv_content(records)
42
+ records_size = records.size
42
43
  write_success = 0
43
- write_failure = 0
44
44
 
45
+ case connection_config[:format][:compression_type]
46
+ when CompressionType.enum("zip")
47
+ write_success = write_compressed_data(connection_config, file_path, local_file_name, csv_content, records_size)
48
+ when CompressionType.enum("un_compressed")
49
+ write_success = write_uncompressed_data(connection_config, file_path, local_file_name, csv_content, records_size)
50
+ else
51
+ raise ArgumentError, "Unsupported compression type: #{connection_config[:format][:compression_type]}"
52
+ end
53
+ write_failure = records.size - write_success
54
+ tracking_message(write_success, write_failure)
55
+ rescue StandardError => e
56
+ handle_exception(
57
+ "SFTP:WRITE:EXCEPTION",
58
+ "error",
59
+ e
60
+ )
61
+ end
62
+
63
+ def write_compressed_data(connection_config, file_path, local_file_name, csv_content, records_size)
64
+ write_success = 0
65
+ Tempfile.create([local_file_name, ".zip"]) do |tempfile|
66
+ Zip::File.open(tempfile.path, Zip::File::CREATE) do |zipfile|
67
+ zipfile.get_output_stream("#{local_file_name}.csv") { |f| f.write(csv_content) }
68
+ end
69
+ with_sftp_client(connection_config) do |sftp|
70
+ sftp.upload!(tempfile.path, file_path)
71
+ write_success = records_size
72
+ rescue StandardError => e
73
+ handle_exception("SFTP:RECORD:WRITE:EXCEPTION", "error", e)
74
+ write_success = 0
75
+ end
76
+ end
77
+ write_success
78
+ end
79
+
80
+ def write_uncompressed_data(connection_config, file_path, local_file_name, csv_content, records_size)
81
+ write_success = 0
45
82
  Tempfile.create([local_file_name, ".csv"]) do |tempfile|
46
83
  tempfile.write(csv_content)
47
84
  tempfile.close
48
85
  with_sftp_client(connection_config) do |sftp|
49
86
  sftp.upload!(tempfile.path, file_path)
50
- write_success += records.size
87
+ write_success = records_size
51
88
  rescue StandardError => e
52
89
  handle_exception("SFTP:RECORD:WRITE:EXCEPTION", "error", e)
53
- write_failure += records.size
90
+ write_success = 0
54
91
  end
55
92
  end
56
- tracking_message(write_success, write_failure)
57
- rescue StandardError => e
58
- handle_exception(
59
- "SFTP:WRITE:EXCEPTION",
60
- "error",
61
- e
62
- )
93
+ write_success
63
94
  end
64
95
 
65
96
  def clear_all_records(sync_config)
@@ -82,7 +113,13 @@ module Multiwoven::Integrations::Destination
82
113
  def generate_file_path(sync_config)
83
114
  connection_specification = sync_config.destination.connection_specification.with_indifferent_access
84
115
  timestamp = Time.now.strftime("%Y%m%d-%H%M%S")
85
- file_name = "#{connection_specification[:file_name]}_#{timestamp}.csv"
116
+ format = connection_specification[:format]
117
+ extension = if format[:compression_type] == "un_compressed"
118
+ format[:format_type]
119
+ else
120
+ format[:compression_type]
121
+ end
122
+ file_name = "#{connection_specification[:file_name]}_#{timestamp}.#{extension}"
86
123
  File.join(connection_specification[:destination_path], file_name)
87
124
  end
88
125
 
@@ -1,10 +1,10 @@
1
1
  {
2
- "documentation_url": "https://docs.multiwoven.com/integrations/destination/klaviyo",
2
+ "documentation_url": "https://docs.multiwoven.com/destinations/file-storage/sftp",
3
3
  "stream_type": "static",
4
4
  "connection_specification": {
5
5
  "$schema": "http://json-schema.org/draft-07/schema#",
6
6
  "title": "SFTP",
7
- "required": ["host", "username", "password", "destination_path"],
7
+ "required": ["host", "username", "password", "destination_path", "format" ],
8
8
  "properties": {
9
9
  "host": {
10
10
  "title": "Host",
@@ -45,7 +45,29 @@
45
45
  "type": "string",
46
46
  "description": "Name of the file to be written.",
47
47
  "order": 5
48
+ },
49
+ "format": {
50
+ "title": "Output Format",
51
+ "type": "object",
52
+ "description": "Format of the data output.",
53
+ "order": 6,
54
+ "required": ["format_type"],
55
+ "properties": {
56
+ "format_type": {
57
+ "title": "File Format Type",
58
+ "type": "string",
59
+ "enum": ["csv"],
60
+ "default": "csv"
61
+ },
62
+ "compression_type": {
63
+ "title": "Compression Type",
64
+ "description": "Whether the output files should be compressed.",
65
+ "type": "string",
66
+ "enum": ["un_compressed", "zip"],
67
+ "default": "un_compressed"
68
+ }
69
+ }
48
70
  }
49
71
  }
50
72
  }
51
- }
73
+ }
@@ -26,6 +26,8 @@ module Multiwoven
26
26
  LogLevel = Types::String.enum("fatal", "error", "warn", "info", "debug", "trace")
27
27
  RequestRateLimitingUnit = Types::String.default("minute").enum("minute", "hour", "day")
28
28
  SchemaMode = Types::String.enum("schema", "schemaless")
29
+ FileFormatType = Types::String.enum("csv")
30
+ CompressionType = Types::String.enum("un_compressed", "zip")
29
31
 
30
32
  class ProtocolModel < Dry::Struct
31
33
  extend Multiwoven::Integrations::Core::Utils
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Multiwoven
4
4
  module Integrations
5
- VERSION = "0.1.63"
5
+ VERSION = "0.1.65"
6
6
 
7
7
  ENABLED_SOURCES = %w[
8
8
  Snowflake
@@ -25,6 +25,7 @@ module Multiwoven
25
25
  SalesforceConsumerGoodsCloud
26
26
  Sftp
27
27
  Postgresql
28
+ Http
28
29
  ].freeze
29
30
  end
30
31
  end
@@ -22,6 +22,7 @@ require "stripe"
22
22
  require "net/sftp"
23
23
  require "csv"
24
24
  require "securerandom"
25
+ require "zip"
25
26
 
26
27
  # Service
27
28
  require_relative "integrations/config"
@@ -60,6 +61,7 @@ require_relative "integrations/destination/stripe/client"
60
61
  require_relative "integrations/destination/salesforce_consumer_goods_cloud/client"
61
62
  require_relative "integrations/destination/sftp/client"
62
63
  require_relative "integrations/destination/postgresql/client"
64
+ require_relative "integrations/destination/http/client"
63
65
 
64
66
  module Multiwoven
65
67
  module Integrations
@@ -49,6 +49,7 @@ Gem::Specification.new do |spec|
49
49
  spec.add_runtime_dependency "restforce"
50
50
  spec.add_runtime_dependency "ruby-limiter"
51
51
  spec.add_runtime_dependency "ruby-odbc"
52
+ spec.add_runtime_dependency "rubyzip"
52
53
  spec.add_runtime_dependency "sequel"
53
54
  spec.add_runtime_dependency "slack-ruby-client"
54
55
  spec.add_runtime_dependency "stripe"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multiwoven-integrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.63
4
+ version: 0.1.65
5
5
  platform: ruby
6
6
  authors:
7
7
  - Subin T P
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-30 00:00:00.000000000 Z
11
+ date: 2024-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -234,6 +234,20 @@ dependencies:
234
234
  - - ">="
235
235
  - !ruby/object:Gem::Version
236
236
  version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: rubyzip
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
237
251
  - !ruby/object:Gem::Dependency
238
252
  name: sequel
239
253
  requirement: !ruby/object:Gem::Requirement
@@ -404,6 +418,11 @@ files:
404
418
  - lib/multiwoven/integrations/destination/google_sheets/config/meta.json
405
419
  - lib/multiwoven/integrations/destination/google_sheets/config/spec.json
406
420
  - lib/multiwoven/integrations/destination/google_sheets/icon.svg
421
+ - lib/multiwoven/integrations/destination/http/client.rb
422
+ - lib/multiwoven/integrations/destination/http/config/catalog.json
423
+ - lib/multiwoven/integrations/destination/http/config/meta.json
424
+ - lib/multiwoven/integrations/destination/http/config/spec.json
425
+ - lib/multiwoven/integrations/destination/http/icon.svg
407
426
  - lib/multiwoven/integrations/destination/hubspot/client.rb
408
427
  - lib/multiwoven/integrations/destination/hubspot/config/catalog.json
409
428
  - lib/multiwoven/integrations/destination/hubspot/config/meta.json