attio 0.1.1

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.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.codecov.yml +52 -0
  3. data/.github/CODEOWNERS +28 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +28 -0
  6. data/.github/dependabot.yml +54 -0
  7. data/.github/pull_request_template.md +40 -0
  8. data/.github/workflows/ci.yml +112 -0
  9. data/.github/workflows/dependabot-auto-merge.yml +45 -0
  10. data/.github/workflows/pr_checks.yml +145 -0
  11. data/.github/workflows/release.yml +147 -0
  12. data/.gitignore +10 -0
  13. data/.rspec +4 -0
  14. data/.rubocop.yml +133 -0
  15. data/.yardopts +18 -0
  16. data/CHANGELOG.md +34 -0
  17. data/CODE_OF_CONDUCT.md +37 -0
  18. data/CONTRIBUTING.md +280 -0
  19. data/Gemfile +17 -0
  20. data/Gemfile.lock +127 -0
  21. data/LICENSE.txt +21 -0
  22. data/README.md +292 -0
  23. data/Rakefile +57 -0
  24. data/SECURITY.md +59 -0
  25. data/attio.gemspec +34 -0
  26. data/bin/console +14 -0
  27. data/bin/setup +8 -0
  28. data/danger/Dangerfile +121 -0
  29. data/docs/.nojekyll +0 -0
  30. data/docs/Attio/AuthenticationError.html +152 -0
  31. data/docs/Attio/Client.html +1373 -0
  32. data/docs/Attio/ConnectionPool/TimeoutError.html +148 -0
  33. data/docs/Attio/ConnectionPool.html +944 -0
  34. data/docs/Attio/Error.html +152 -0
  35. data/docs/Attio/HttpClient/ConnectionError.html +152 -0
  36. data/docs/Attio/HttpClient/TimeoutError.html +152 -0
  37. data/docs/Attio/HttpClient.html +1329 -0
  38. data/docs/Attio/Logger.html +747 -0
  39. data/docs/Attio/NotFoundError.html +152 -0
  40. data/docs/Attio/RateLimitError.html +152 -0
  41. data/docs/Attio/RequestLogger.html +780 -0
  42. data/docs/Attio/Resources/Attributes.html +508 -0
  43. data/docs/Attio/Resources/Base.html +624 -0
  44. data/docs/Attio/Resources/Lists.html +1002 -0
  45. data/docs/Attio/Resources/Objects.html +415 -0
  46. data/docs/Attio/Resources/Records.html +1465 -0
  47. data/docs/Attio/Resources/Users.html +415 -0
  48. data/docs/Attio/Resources/Workspaces.html +324 -0
  49. data/docs/Attio/Resources.html +141 -0
  50. data/docs/Attio/RetryHandler.html +1023 -0
  51. data/docs/Attio/ServerError.html +152 -0
  52. data/docs/Attio/ValidationError.html +152 -0
  53. data/docs/Attio.html +397 -0
  54. data/docs/SETUP.md +117 -0
  55. data/docs/_index.html +378 -0
  56. data/docs/class_list.html +54 -0
  57. data/docs/css/common.css +1 -0
  58. data/docs/css/full_list.css +58 -0
  59. data/docs/css/style.css +503 -0
  60. data/docs/example.rb +119 -0
  61. data/docs/file.CHANGELOG.html +124 -0
  62. data/docs/file.README.html +371 -0
  63. data/docs/file_list.html +64 -0
  64. data/docs/frames.html +22 -0
  65. data/docs/index.html +371 -0
  66. data/docs/js/app.js +344 -0
  67. data/docs/js/full_list.js +242 -0
  68. data/docs/js/jquery.js +4 -0
  69. data/docs/method_list.html +750 -0
  70. data/docs/top-level-namespace.html +110 -0
  71. data/lib/attio/client.rb +118 -0
  72. data/lib/attio/connection_pool.rb +69 -0
  73. data/lib/attio/errors.rb +9 -0
  74. data/lib/attio/http_client.rb +100 -0
  75. data/lib/attio/logger.rb +110 -0
  76. data/lib/attio/resources/attributes.rb +26 -0
  77. data/lib/attio/resources/base.rb +55 -0
  78. data/lib/attio/resources/lists.rb +56 -0
  79. data/lib/attio/resources/objects.rb +20 -0
  80. data/lib/attio/resources/records.rb +158 -0
  81. data/lib/attio/resources/users.rb +20 -0
  82. data/lib/attio/resources/workspaces.rb +13 -0
  83. data/lib/attio/retry_handler.rb +70 -0
  84. data/lib/attio/version.rb +3 -0
  85. data/lib/attio.rb +60 -0
  86. data/run_tests.rb +52 -0
  87. data/test_basic.rb +51 -0
  88. data/test_typhoeus.rb +31 -0
  89. metadata +160 -0
@@ -0,0 +1,158 @@
1
+ module Attio
2
+ module Resources
3
+ # Handles all record-related API operations.
4
+ #
5
+ # Records are the main data entities in Attio, representing things like
6
+ # people, companies, deals, etc. This class provides methods to create,
7
+ # read, update, delete, and query records.
8
+ #
9
+ # @example List records
10
+ # records = client.records.list(object: 'people', filters: { name: 'John' })
11
+ #
12
+ # @example Create a record
13
+ # record = client.records.create(
14
+ # object: 'people',
15
+ # data: { name: 'Jane Doe', email: 'jane@example.com' }
16
+ # )
17
+ #
18
+ # @author Ernest Sim
19
+ # @since 1.0.0
20
+ class Records < Base
21
+ # Query and list records for a specific object type.
22
+ #
23
+ # This method allows you to retrieve records with optional filtering,
24
+ # sorting, and pagination parameters.
25
+ #
26
+ # @param object [String] The object type to query (e.g., 'people', 'companies')
27
+ # @param params [Hash] Query parameters including filters, sorts, and pagination
28
+ # @option params [Hash] :filters Filtering criteria
29
+ # @option params [Array] :sorts Sorting options
30
+ # @option params [Integer] :limit Number of records to return
31
+ # @option params [String] :cursor Pagination cursor for next page
32
+ #
33
+ # @return [Hash] API response containing records and pagination info
34
+ # @raise [ArgumentError] if object is nil or empty
35
+ #
36
+ # @example Basic listing
37
+ # records = client.records.list(object: 'people')
38
+ #
39
+ # @example With filters
40
+ # records = client.records.list(
41
+ # object: 'people',
42
+ # filters: { name: { contains: 'John' } },
43
+ # limit: 50
44
+ # )
45
+ def list(object:, **params)
46
+ validate_object!(object)
47
+ request(:post, "objects/#{object}/records/query", params)
48
+ end
49
+
50
+ # Retrieve a specific record by ID.
51
+ #
52
+ # @param object [String] The object type (e.g., 'people', 'companies')
53
+ # @param id [String] The record ID
54
+ #
55
+ # @return [Hash] The record data
56
+ # @raise [ArgumentError] if object or id is nil or empty
57
+ #
58
+ # @example
59
+ # record = client.records.get(object: 'people', id: 'abc123')
60
+ def get(object:, id:)
61
+ validate_object!(object)
62
+ validate_id!(id)
63
+ request(:get, "objects/#{object}/records/#{id}")
64
+ end
65
+
66
+ # Create a new record.
67
+ #
68
+ # @param object [String] The object type to create the record in
69
+ # @param data [Hash] The record data to create
70
+ #
71
+ # @return [Hash] The created record data
72
+ # @raise [ArgumentError] if object is nil/empty or data is invalid
73
+ #
74
+ # @example Create a person
75
+ # record = client.records.create(
76
+ # object: 'people',
77
+ # data: {
78
+ # name: 'Jane Doe',
79
+ # email: 'jane@example.com',
80
+ # company: { target_object: 'companies', target_record_id: 'company123' }
81
+ # }
82
+ # )
83
+ def create(object:, data:)
84
+ validate_object!(object)
85
+ validate_data!(data)
86
+ request(:post, "objects/#{object}/records", data)
87
+ end
88
+
89
+ # Update an existing record.
90
+ #
91
+ # @param object [String] The object type
92
+ # @param id [String] The record ID to update
93
+ # @param data [Hash] The updated record data
94
+ #
95
+ # @return [Hash] The updated record data
96
+ # @raise [ArgumentError] if object, id, or data is invalid
97
+ #
98
+ # @example Update a person's name
99
+ # record = client.records.update(
100
+ # object: 'people',
101
+ # id: 'abc123',
102
+ # data: { name: 'Jane Smith' }
103
+ # )
104
+ def update(object:, id:, data:)
105
+ validate_object!(object)
106
+ validate_id!(id)
107
+ validate_data!(data)
108
+ request(:patch, "objects/#{object}/records/#{id}", data)
109
+ end
110
+
111
+ # Delete a record.
112
+ #
113
+ # @param object [String] The object type
114
+ # @param id [String] The record ID to delete
115
+ #
116
+ # @return [Hash] Deletion confirmation
117
+ # @raise [ArgumentError] if object or id is nil or empty
118
+ #
119
+ # @example
120
+ # client.records.delete(object: 'people', id: 'abc123')
121
+ def delete(object:, id:)
122
+ validate_object!(object)
123
+ validate_id!(id)
124
+ request(:delete, "objects/#{object}/records/#{id}")
125
+ end
126
+
127
+ private
128
+
129
+ # Validates that the object parameter is present and not empty.
130
+ #
131
+ # @param object [String, nil] The object type to validate
132
+ # @raise [ArgumentError] if object is nil or empty
133
+ # @api private
134
+ def validate_object!(object)
135
+ raise ArgumentError, "Object type is required" if object.nil? || object.to_s.strip.empty?
136
+ end
137
+
138
+ # Validates that the ID parameter is present and not empty.
139
+ #
140
+ # @param id [String, nil] The record ID to validate
141
+ # @raise [ArgumentError] if id is nil or empty
142
+ # @api private
143
+ def validate_id!(id)
144
+ raise ArgumentError, "Record ID is required" if id.nil? || id.to_s.strip.empty?
145
+ end
146
+
147
+ # Validates that the data parameter is present and is a hash.
148
+ #
149
+ # @param data [Hash, nil] The data to validate
150
+ # @raise [ArgumentError] if data is nil or not a hash
151
+ # @api private
152
+ def validate_data!(data)
153
+ raise ArgumentError, "Data is required" if data.nil?
154
+ raise ArgumentError, "Data must be a hash" unless data.is_a?(Hash)
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,20 @@
1
+ module Attio
2
+ module Resources
3
+ class Users < Base
4
+ def list(**params)
5
+ request(:get, "users", params)
6
+ end
7
+
8
+ def get(id:)
9
+ validate_id!(id)
10
+ request(:get, "users/#{id}")
11
+ end
12
+
13
+ private
14
+
15
+ def validate_id!(id)
16
+ raise ArgumentError, "User ID is required" if id.nil? || id.to_s.strip.empty?
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module Attio
2
+ module Resources
3
+ class Workspaces < Base
4
+ def get
5
+ request(:get, "workspace")
6
+ end
7
+
8
+ def members(**params)
9
+ request(:get, "workspace/members", params)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,70 @@
1
+ module Attio
2
+ class RetryHandler
3
+ DEFAULT_MAX_RETRIES = 3
4
+ DEFAULT_RETRY_DELAY = 1 # seconds
5
+ DEFAULT_BACKOFF_FACTOR = 2
6
+ RETRIABLE_ERRORS = [
7
+ HttpClient::TimeoutError,
8
+ HttpClient::ConnectionError,
9
+ ServerError,
10
+ RateLimitError
11
+ ].freeze
12
+
13
+ attr_reader :max_retries, :retry_delay, :backoff_factor, :logger
14
+
15
+ def initialize(max_retries: DEFAULT_MAX_RETRIES,
16
+ retry_delay: DEFAULT_RETRY_DELAY,
17
+ backoff_factor: DEFAULT_BACKOFF_FACTOR,
18
+ logger: nil)
19
+ @max_retries = max_retries
20
+ @retry_delay = retry_delay
21
+ @backoff_factor = backoff_factor
22
+ @logger = logger
23
+ end
24
+
25
+ def with_retry(&block)
26
+ retries = 0
27
+ delay = retry_delay
28
+
29
+ begin
30
+ yield
31
+ rescue *RETRIABLE_ERRORS => e
32
+ retries += 1
33
+
34
+ if retries <= max_retries
35
+ log_retry(e, retries, delay)
36
+ sleep(delay)
37
+ delay *= backoff_factor
38
+ retry
39
+ else
40
+ log_failure(e, retries)
41
+ raise
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def log_retry(error, attempt, delay)
49
+ return unless logger
50
+
51
+ logger.warn(
52
+ "Retry attempt #{attempt}/#{max_retries}",
53
+ error: error.class.name,
54
+ message: error.message,
55
+ delay: delay
56
+ )
57
+ end
58
+
59
+ def log_failure(error, attempts)
60
+ return unless logger
61
+
62
+ logger.error(
63
+ "Max retries exceeded",
64
+ error: error.class.name,
65
+ message: error.message,
66
+ attempts: attempts
67
+ )
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ module Attio
2
+ VERSION = "0.1.1"
3
+ end
data/lib/attio.rb ADDED
@@ -0,0 +1,60 @@
1
+ require "typhoeus"
2
+
3
+ require "attio/version"
4
+ require "attio/errors"
5
+ require "attio/http_client"
6
+ require "attio/client"
7
+
8
+ require "attio/resources/base"
9
+ require "attio/resources/records"
10
+ require "attio/resources/objects"
11
+ require "attio/resources/lists"
12
+ require "attio/resources/workspaces"
13
+ require "attio/resources/attributes"
14
+ require "attio/resources/users"
15
+
16
+ # The main Attio module provides access to the Attio API client.
17
+ #
18
+ # This is the primary entry point for interacting with the Attio API.
19
+ #
20
+ # @example Basic usage
21
+ # client = Attio.client(api_key: 'your-api-key')
22
+ #
23
+ # @example Working with records
24
+ # # List records for a specific object type
25
+ # records = client.records.list(object: 'people', filters: { name: 'John' })
26
+ #
27
+ # # Create a new record
28
+ # new_record = client.records.create(
29
+ # object: 'people',
30
+ # data: { name: 'Jane Doe', email: 'jane@example.com' }
31
+ # )
32
+ #
33
+ # # Get a specific record
34
+ # record = client.records.get(object: 'people', id: 'record-id')
35
+ #
36
+ # # Update a record
37
+ # updated = client.records.update(
38
+ # object: 'people',
39
+ # id: 'record-id',
40
+ # data: { name: 'Jane Smith' }
41
+ # )
42
+ #
43
+ # # Delete a record
44
+ # client.records.delete(object: 'people', id: 'record-id')
45
+ #
46
+ # @author Ernest Sim
47
+ # @since 1.0.0
48
+ module Attio
49
+ # Creates a new Attio API client instance.
50
+ #
51
+ # @param api_key [String] Your Attio API key
52
+ # @return [Client] A new client instance configured with the provided API key
53
+ # @raise [ArgumentError] if api_key is nil or empty
54
+ #
55
+ # @example Create a client
56
+ # client = Attio.client(api_key: 'your-api-key-here')
57
+ def self.client(api_key:)
58
+ Client.new(api_key: api_key)
59
+ end
60
+ end
data/run_tests.rb ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Add lib to load path
4
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
5
+
6
+ # Load the gem
7
+ require 'attio'
8
+
9
+ # Basic smoke test
10
+ begin
11
+ puts "Testing Attio gem..."
12
+ puts "Version: #{Attio::VERSION}"
13
+
14
+ # Test client initialization
15
+ begin
16
+ Attio::Client.new(api_key: nil)
17
+ puts "ERROR: Should have raised error for nil API key"
18
+ rescue ArgumentError => e
19
+ puts "✓ Client validation works: #{e.message}"
20
+ end
21
+
22
+ # Test client creation
23
+ client = Attio::Client.new(api_key: "test_key")
24
+ puts "✓ Client created successfully"
25
+
26
+ # Test resource access
27
+ puts "✓ Records resource available: #{client.records.class}"
28
+ puts "✓ Objects resource available: #{client.objects.class}"
29
+ puts "✓ Lists resource available: #{client.lists.class}"
30
+ puts "✓ Workspaces resource available: #{client.workspaces.class}"
31
+ puts "✓ Attributes resource available: #{client.attributes.class}"
32
+ puts "✓ Users resource available: #{client.users.class}"
33
+
34
+ # Test error classes
35
+ [
36
+ Attio::Error,
37
+ Attio::AuthenticationError,
38
+ Attio::NotFoundError,
39
+ Attio::ValidationError,
40
+ Attio::RateLimitError,
41
+ Attio::ServerError
42
+ ].each do |error_class|
43
+ puts "✓ #{error_class} is defined"
44
+ end
45
+
46
+ puts "\nAll basic tests passed!"
47
+
48
+ rescue StandardError => e
49
+ puts "ERROR: #{e.message}"
50
+ puts e.backtrace
51
+ exit 1
52
+ end
data/test_basic.rb ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Test without loading external dependencies
4
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
5
+
6
+ puts "Testing Attio gem structure..."
7
+
8
+ # Test version file
9
+ require 'attio/version'
10
+ puts "✓ Version loaded: #{Attio::VERSION}"
11
+
12
+ # Test error definitions
13
+ require 'attio/errors'
14
+ [
15
+ Attio::Error,
16
+ Attio::AuthenticationError,
17
+ Attio::NotFoundError,
18
+ Attio::ValidationError,
19
+ Attio::RateLimitError,
20
+ Attio::ServerError
21
+ ].each do |error_class|
22
+ puts "✓ #{error_class} is defined"
23
+ end
24
+
25
+ # Test that all files exist
26
+ files_to_check = [
27
+ 'lib/attio.rb',
28
+ 'lib/attio/client.rb',
29
+ 'lib/attio/resources/base.rb',
30
+ 'lib/attio/resources/records.rb',
31
+ 'lib/attio/resources/objects.rb',
32
+ 'lib/attio/resources/lists.rb',
33
+ 'lib/attio/resources/workspaces.rb',
34
+ 'lib/attio/resources/attributes.rb',
35
+ 'lib/attio/resources/users.rb'
36
+ ]
37
+
38
+ files_to_check.each do |file|
39
+ if File.exist?(file)
40
+ puts "✓ #{file} exists"
41
+ else
42
+ puts "✗ #{file} is missing!"
43
+ end
44
+ end
45
+
46
+ # Test spec files exist
47
+ spec_files = Dir.glob('spec/**/*_spec.rb')
48
+ puts "\nFound #{spec_files.length} spec files:"
49
+ spec_files.each { |f| puts " - #{f}" }
50
+
51
+ puts "\nBasic structure test completed!"
data/test_typhoeus.rb ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative 'lib/attio'
4
+
5
+ # Test the gem with Typhoeus
6
+ puts "=== Testing Attio Ruby Gem with Typhoeus ==="
7
+ puts "Version: #{Attio::VERSION}"
8
+
9
+ # Initialize client
10
+ API_KEY = '5472096a0d3ad936523a7a9101807bb3155616a3e04a7649ad41cd5a0261dddd'
11
+ client = Attio.client(api_key: API_KEY)
12
+ puts "✓ Client initialized"
13
+
14
+ # Test listing people
15
+ puts "\nListing people..."
16
+ begin
17
+ result = client.records.list(object: "people", sorts: [], limit: 5)
18
+ records = result["data"]
19
+ puts "✓ Found #{records.length} records"
20
+
21
+ records.each do |record|
22
+ name = record["values"]["name"][0]["full_name"] rescue "Unknown"
23
+ email = record["values"]["email_addresses"][0]["email_address"] rescue "No email"
24
+ puts " - #{name} (#{email})"
25
+ end
26
+ rescue => e
27
+ puts "✗ Failed to list records: #{e.message}"
28
+ puts e.backtrace
29
+ end
30
+
31
+ puts "\n✨ Test complete!"
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: attio
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Ernest Sim
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: typhoeus
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.4'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.4'
26
+ - !ruby/object:Gem::Dependency
27
+ name: yard
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.9'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.9'
40
+ description: A Ruby library for interacting with the Attio API, providing easy access
41
+ to CRM functionality
42
+ email:
43
+ - ernest.codes@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".codecov.yml"
49
+ - ".github/CODEOWNERS"
50
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
51
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
52
+ - ".github/dependabot.yml"
53
+ - ".github/pull_request_template.md"
54
+ - ".github/workflows/ci.yml"
55
+ - ".github/workflows/dependabot-auto-merge.yml"
56
+ - ".github/workflows/pr_checks.yml"
57
+ - ".github/workflows/release.yml"
58
+ - ".gitignore"
59
+ - ".rspec"
60
+ - ".rubocop.yml"
61
+ - ".yardopts"
62
+ - CHANGELOG.md
63
+ - CODE_OF_CONDUCT.md
64
+ - CONTRIBUTING.md
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - SECURITY.md
71
+ - attio.gemspec
72
+ - bin/console
73
+ - bin/setup
74
+ - danger/Dangerfile
75
+ - docs/.nojekyll
76
+ - docs/Attio.html
77
+ - docs/Attio/AuthenticationError.html
78
+ - docs/Attio/Client.html
79
+ - docs/Attio/ConnectionPool.html
80
+ - docs/Attio/ConnectionPool/TimeoutError.html
81
+ - docs/Attio/Error.html
82
+ - docs/Attio/HttpClient.html
83
+ - docs/Attio/HttpClient/ConnectionError.html
84
+ - docs/Attio/HttpClient/TimeoutError.html
85
+ - docs/Attio/Logger.html
86
+ - docs/Attio/NotFoundError.html
87
+ - docs/Attio/RateLimitError.html
88
+ - docs/Attio/RequestLogger.html
89
+ - docs/Attio/Resources.html
90
+ - docs/Attio/Resources/Attributes.html
91
+ - docs/Attio/Resources/Base.html
92
+ - docs/Attio/Resources/Lists.html
93
+ - docs/Attio/Resources/Objects.html
94
+ - docs/Attio/Resources/Records.html
95
+ - docs/Attio/Resources/Users.html
96
+ - docs/Attio/Resources/Workspaces.html
97
+ - docs/Attio/RetryHandler.html
98
+ - docs/Attio/ServerError.html
99
+ - docs/Attio/ValidationError.html
100
+ - docs/SETUP.md
101
+ - docs/_index.html
102
+ - docs/class_list.html
103
+ - docs/css/common.css
104
+ - docs/css/full_list.css
105
+ - docs/css/style.css
106
+ - docs/example.rb
107
+ - docs/file.CHANGELOG.html
108
+ - docs/file.README.html
109
+ - docs/file_list.html
110
+ - docs/frames.html
111
+ - docs/index.html
112
+ - docs/js/app.js
113
+ - docs/js/full_list.js
114
+ - docs/js/jquery.js
115
+ - docs/method_list.html
116
+ - docs/top-level-namespace.html
117
+ - lib/attio.rb
118
+ - lib/attio/client.rb
119
+ - lib/attio/connection_pool.rb
120
+ - lib/attio/errors.rb
121
+ - lib/attio/http_client.rb
122
+ - lib/attio/logger.rb
123
+ - lib/attio/resources/attributes.rb
124
+ - lib/attio/resources/base.rb
125
+ - lib/attio/resources/lists.rb
126
+ - lib/attio/resources/objects.rb
127
+ - lib/attio/resources/records.rb
128
+ - lib/attio/resources/users.rb
129
+ - lib/attio/resources/workspaces.rb
130
+ - lib/attio/retry_handler.rb
131
+ - lib/attio/version.rb
132
+ - run_tests.rb
133
+ - test_basic.rb
134
+ - test_typhoeus.rb
135
+ homepage: https://github.com/idl3/attio
136
+ licenses:
137
+ - MIT
138
+ metadata:
139
+ allowed_push_host: https://rubygems.org
140
+ homepage_uri: https://github.com/idl3/attio
141
+ source_code_uri: https://github.com/idl3/attio
142
+ changelog_uri: https://github.com/idl3/attio/blob/master/CHANGELOG.md
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: 3.0.0
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubygems_version: 3.6.9
158
+ specification_version: 4
159
+ summary: Ruby client for the Attio API
160
+ test_files: []