atrium-ruby 1.3.2 → 2.0.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.
Files changed (201) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +5 -2
  3. data/README.md +132 -66
  4. data/Rakefile +7 -4
  5. data/atrium-ruby.gemspec +40 -32
  6. data/docs/Account.md +35 -0
  7. data/docs/AccountNumber.md +12 -0
  8. data/docs/AccountNumbersResponseBody.md +8 -0
  9. data/docs/AccountOwner.md +18 -0
  10. data/docs/AccountOwnersResponseBody.md +8 -0
  11. data/docs/AccountResponseBody.md +8 -0
  12. data/docs/AccountsApi.md +174 -0
  13. data/docs/AccountsResponseBody.md +9 -0
  14. data/docs/Challenge.md +13 -0
  15. data/docs/ChallengeOption.md +10 -0
  16. data/docs/ChallengesResponseBody.md +8 -0
  17. data/docs/ConnectWidget.md +9 -0
  18. data/docs/ConnectWidgetApi.md +44 -0
  19. data/docs/ConnectWidgetRequestBody.md +11 -0
  20. data/docs/ConnectWidgetResponseBody.md +8 -0
  21. data/docs/CredentialOption.md +9 -0
  22. data/docs/CredentialRequest.md +9 -0
  23. data/docs/CredentialResponse.md +12 -0
  24. data/docs/CredentialsResponseBody.md +8 -0
  25. data/docs/IdentityApi.md +82 -0
  26. data/docs/Institution.md +14 -0
  27. data/docs/InstitutionResponseBody.md +8 -0
  28. data/docs/InstitutionsApi.md +120 -0
  29. data/docs/InstitutionsResponseBody.md +9 -0
  30. data/docs/Member.md +18 -0
  31. data/docs/MemberConnectionStatus.md +16 -0
  32. data/docs/MemberConnectionStatusResponseBody.md +8 -0
  33. data/docs/MemberCreateRequest.md +11 -0
  34. data/docs/MemberCreateRequestBody.md +8 -0
  35. data/docs/MemberResponseBody.md +8 -0
  36. data/docs/MemberResumeRequest.md +8 -0
  37. data/docs/MemberResumeRequestBody.md +8 -0
  38. data/docs/MemberUpdateRequest.md +10 -0
  39. data/docs/MemberUpdateRequestBody.md +8 -0
  40. data/docs/MembersApi.md +487 -0
  41. data/docs/MembersResponseBody.md +9 -0
  42. data/docs/Pagination.md +11 -0
  43. data/docs/Transaction.md +38 -0
  44. data/docs/TransactionCleanseAndCategorizeRequest.md +11 -0
  45. data/docs/TransactionCleanseAndCategorizeResponse.md +20 -0
  46. data/docs/TransactionResponseBody.md +8 -0
  47. data/docs/TransactionsApi.md +126 -0
  48. data/docs/TransactionsCleanseAndCategorizeRequestBody.md +8 -0
  49. data/docs/TransactionsCleanseAndCategorizeResponseBody.md +8 -0
  50. data/docs/TransactionsResponseBody.md +9 -0
  51. data/docs/User.md +11 -0
  52. data/docs/UserCreateRequestBody.md +8 -0
  53. data/docs/UserResponseBody.md +8 -0
  54. data/docs/UserUpdateRequestBody.md +8 -0
  55. data/docs/UsersApi.md +193 -0
  56. data/docs/UsersResponseBody.md +9 -0
  57. data/docs/VerificationApi.md +120 -0
  58. data/git_push.sh +49 -0
  59. data/lib/atrium-ruby.rb +88 -0
  60. data/lib/atrium-ruby/api/accounts_api.rb +272 -0
  61. data/lib/atrium-ruby/api/atrium_client.rb +28 -0
  62. data/lib/atrium-ruby/api/connect_widget_api.rb +82 -0
  63. data/lib/atrium-ruby/api/identity_api.rb +140 -0
  64. data/lib/atrium-ruby/api/institutions_api.rb +181 -0
  65. data/lib/atrium-ruby/api/members_api.rb +749 -0
  66. data/lib/atrium-ruby/api/transactions_api.rb +198 -0
  67. data/lib/atrium-ruby/api/users_api.rb +287 -0
  68. data/lib/atrium-ruby/api/verification_api.rb +198 -0
  69. data/lib/atrium-ruby/api_client.rb +384 -0
  70. data/lib/atrium-ruby/api_error.rb +34 -0
  71. data/lib/atrium-ruby/configuration.rb +212 -0
  72. data/lib/atrium-ruby/models/account.rb +422 -0
  73. data/lib/atrium-ruby/models/account_number.rb +215 -0
  74. data/lib/atrium-ruby/models/account_numbers_response_body.rb +181 -0
  75. data/lib/atrium-ruby/models/account_owner.rb +269 -0
  76. data/lib/atrium-ruby/models/account_owners_response_body.rb +181 -0
  77. data/lib/atrium-ruby/models/account_response_body.rb +179 -0
  78. data/lib/atrium-ruby/models/accounts_response_body.rb +190 -0
  79. data/lib/atrium-ruby/models/challenge.rb +226 -0
  80. data/lib/atrium-ruby/models/challenge_option.rb +197 -0
  81. data/lib/atrium-ruby/models/challenges_response_body.rb +181 -0
  82. data/lib/atrium-ruby/models/connect_widget.rb +188 -0
  83. data/lib/atrium-ruby/models/connect_widget_request_body.rb +206 -0
  84. data/lib/atrium-ruby/models/connect_widget_response_body.rb +179 -0
  85. data/lib/atrium-ruby/models/credential_option.rb +188 -0
  86. data/lib/atrium-ruby/models/credential_request.rb +188 -0
  87. data/lib/atrium-ruby/models/credential_response.rb +217 -0
  88. data/lib/atrium-ruby/models/credentials_response_body.rb +181 -0
  89. data/lib/atrium-ruby/models/institution.rb +233 -0
  90. data/lib/atrium-ruby/models/institution_response_body.rb +179 -0
  91. data/lib/atrium-ruby/models/institutions_response_body.rb +190 -0
  92. data/lib/atrium-ruby/models/member.rb +269 -0
  93. data/lib/atrium-ruby/models/member_connection_status.rb +253 -0
  94. data/lib/atrium-ruby/models/member_connection_status_response_body.rb +179 -0
  95. data/lib/atrium-ruby/models/member_create_request.rb +218 -0
  96. data/lib/atrium-ruby/models/member_create_request_body.rb +179 -0
  97. data/lib/atrium-ruby/models/member_response_body.rb +179 -0
  98. data/lib/atrium-ruby/models/member_resume_request.rb +181 -0
  99. data/lib/atrium-ruby/models/member_resume_request_body.rb +179 -0
  100. data/lib/atrium-ruby/models/member_update_request.rb +199 -0
  101. data/lib/atrium-ruby/models/member_update_request_body.rb +179 -0
  102. data/lib/atrium-ruby/models/members_response_body.rb +190 -0
  103. data/lib/atrium-ruby/models/pagination.rb +206 -0
  104. data/lib/atrium-ruby/models/transaction.rb +449 -0
  105. data/lib/atrium-ruby/models/transaction_cleanse_and_categorize_request.rb +206 -0
  106. data/lib/atrium-ruby/models/transaction_cleanse_and_categorize_response.rb +287 -0
  107. data/lib/atrium-ruby/models/transaction_response_body.rb +179 -0
  108. data/lib/atrium-ruby/models/transactions_cleanse_and_categorize_request_body.rb +181 -0
  109. data/lib/atrium-ruby/models/transactions_cleanse_and_categorize_response_body.rb +181 -0
  110. data/lib/atrium-ruby/models/transactions_response_body.rb +190 -0
  111. data/lib/atrium-ruby/models/user.rb +206 -0
  112. data/lib/atrium-ruby/models/user_create_request_body.rb +179 -0
  113. data/lib/atrium-ruby/models/user_response_body.rb +179 -0
  114. data/lib/atrium-ruby/models/user_update_request_body.rb +179 -0
  115. data/lib/atrium-ruby/models/users_response_body.rb +190 -0
  116. data/lib/atrium-ruby/version.rb +11 -0
  117. data/spec/api/accounts_api_spec.rb +88 -0
  118. data/spec/api/connect_widget_api_spec.rb +43 -0
  119. data/spec/api/identity_api_spec.rb +56 -0
  120. data/spec/api/institutions_api_spec.rb +68 -0
  121. data/spec/api/members_api_spec.rb +195 -0
  122. data/spec/api/transactions_api_spec.rb +71 -0
  123. data/spec/api/users_api_spec.rb +92 -0
  124. data/spec/api/verification_api_spec.rb +69 -0
  125. data/spec/api_client_spec.rb +222 -0
  126. data/spec/configuration_spec.rb +38 -0
  127. data/spec/models/account_number_spec.rb +60 -0
  128. data/spec/models/account_numbers_response_body_spec.rb +36 -0
  129. data/spec/models/account_owner_spec.rb +96 -0
  130. data/spec/models/account_owners_response_body_spec.rb +36 -0
  131. data/spec/models/account_response_body_spec.rb +36 -0
  132. data/spec/models/account_spec.rb +198 -0
  133. data/spec/models/accounts_response_body_spec.rb +42 -0
  134. data/spec/models/challenge_option_spec.rb +48 -0
  135. data/spec/models/challenge_spec.rb +66 -0
  136. data/spec/models/challenges_response_body_spec.rb +36 -0
  137. data/spec/models/connect_widget_request_body_spec.rb +54 -0
  138. data/spec/models/connect_widget_response_body_spec.rb +36 -0
  139. data/spec/models/connect_widget_spec.rb +42 -0
  140. data/spec/models/credential_option_spec.rb +42 -0
  141. data/spec/models/credential_request_spec.rb +42 -0
  142. data/spec/models/credential_response_spec.rb +60 -0
  143. data/spec/models/credentials_response_body_spec.rb +36 -0
  144. data/spec/models/institution_response_body_spec.rb +36 -0
  145. data/spec/models/institution_spec.rb +72 -0
  146. data/spec/models/institutions_response_body_spec.rb +42 -0
  147. data/spec/models/member_connection_status_response_body_spec.rb +36 -0
  148. data/spec/models/member_connection_status_spec.rb +84 -0
  149. data/spec/models/member_create_request_body_spec.rb +36 -0
  150. data/spec/models/member_create_request_spec.rb +54 -0
  151. data/spec/models/member_response_body_spec.rb +36 -0
  152. data/spec/models/member_resume_request_body_spec.rb +36 -0
  153. data/spec/models/member_resume_request_spec.rb +36 -0
  154. data/spec/models/member_spec.rb +96 -0
  155. data/spec/models/member_update_request_body_spec.rb +36 -0
  156. data/spec/models/member_update_request_spec.rb +48 -0
  157. data/spec/models/members_response_body_spec.rb +42 -0
  158. data/spec/models/pagination_spec.rb +54 -0
  159. data/spec/models/transaction_cleanse_and_categorize_request_spec.rb +54 -0
  160. data/spec/models/transaction_cleanse_and_categorize_response_spec.rb +108 -0
  161. data/spec/models/transaction_response_body_spec.rb +36 -0
  162. data/spec/models/transaction_spec.rb +216 -0
  163. data/spec/models/transactions_cleanse_and_categorize_request_body_spec.rb +36 -0
  164. data/spec/models/transactions_cleanse_and_categorize_response_body_spec.rb +36 -0
  165. data/spec/models/transactions_response_body_spec.rb +42 -0
  166. data/spec/models/user_create_request_body_spec.rb +36 -0
  167. data/spec/models/user_response_body_spec.rb +36 -0
  168. data/spec/models/user_spec.rb +54 -0
  169. data/spec/models/user_update_request_body_spec.rb +36 -0
  170. data/spec/models/users_response_body_spec.rb +42 -0
  171. data/spec/spec_helper.rb +107 -0
  172. metadata +323 -91
  173. data/.gitignore +0 -10
  174. data/.rubocop.yml +0 -12
  175. data/.travis.yml +0 -12
  176. data/bin/console +0 -14
  177. data/bin/demo +0 -49
  178. data/bin/setup +0 -8
  179. data/examples/accounts_and_transactions.rb +0 -49
  180. data/examples/all_endpoints.rb +0 -226
  181. data/examples/example_workflow.rb +0 -176
  182. data/examples/multi_factor_authentication.rb +0 -57
  183. data/examples/update_credentials.rb +0 -58
  184. data/examples/user_and_member_creation.rb +0 -53
  185. data/lib/atrium.rb +0 -40
  186. data/lib/atrium/account.rb +0 -100
  187. data/lib/atrium/account_number.rb +0 -13
  188. data/lib/atrium/account_owner.rb +0 -19
  189. data/lib/atrium/challenge.rb +0 -13
  190. data/lib/atrium/client.rb +0 -51
  191. data/lib/atrium/connect.rb +0 -34
  192. data/lib/atrium/credential.rb +0 -11
  193. data/lib/atrium/error.rb +0 -4
  194. data/lib/atrium/institution.rb +0 -38
  195. data/lib/atrium/member.rb +0 -264
  196. data/lib/atrium/pageable.rb +0 -74
  197. data/lib/atrium/paginate.rb +0 -92
  198. data/lib/atrium/ruby.rb +0 -3
  199. data/lib/atrium/transaction.rb +0 -74
  200. data/lib/atrium/user.rb +0 -150
  201. data/lib/atrium/version.rb +0 -3
@@ -0,0 +1,198 @@
1
+ =begin
2
+ #MX API
3
+
4
+ #The MX Atrium API supports over 48,000 data connections to thousands of financial institutions. It provides secure access to your users' accounts and transactions with industry-leading cleansing, categorization, and classification. Atrium is designed according to resource-oriented REST architecture and responds with JSON bodies and HTTP response codes. Use Atrium's development environment, vestibule.mx.com, to quickly get up and running. The development environment limits are 100 users, 25 members per user, and access to the top 15 institutions. Contact MX to purchase production access.
5
+
6
+
7
+ =end
8
+
9
+ require 'uri'
10
+
11
+ module Atrium
12
+ class VerificationApi
13
+ attr_accessor :api_client
14
+
15
+ def initialize(api_client = ApiClient.default)
16
+ @api_client = api_client
17
+ end
18
+ # Read account numbers
19
+ # Use this endpoint to check whether account and routing numbers are available for accounts associated with a particular member. It returns the account_numbers object, which contains account and routing number data for each account associated with the member.
20
+ # @param member_guid The unique identifier for a `member`.
21
+ # @param user_guid The unique identifier for a `user`.
22
+ # @param [Hash] opts the optional parameters
23
+ # @return [AccountNumbersResponseBody]
24
+ def list_account_numbers(member_guid, user_guid, opts = {})
25
+ data, _status_code, _headers = list_account_numbers_with_http_info(member_guid, user_guid, opts)
26
+ data
27
+ end
28
+
29
+ # Read account numbers by account GUID
30
+ # Use this endpoint to check whether account and routing numbers are available for a specific account. It returns the account_numbers object, which contains account and routing number data.
31
+ # @param account_guid The unique identifier for an `account`.
32
+ # @param user_guid The unique identifier for a `user`.
33
+ # @param [Hash] opts the optional parameters
34
+ # @return [AccountNumbersResponseBody]
35
+ def list_account_numbers_by_account(account_guid, user_guid, opts = {})
36
+ data, _status_code, _headers = list_account_numbers_by_account_with_http_info(account_guid, user_guid, opts)
37
+ data
38
+ end
39
+
40
+ # Verify
41
+ # The verify endpoint begins a verification process for a member.
42
+ # @param member_guid The unique identifier for a `member`.
43
+ # @param user_guid The unique identifier for a `user`.
44
+ # @param [Hash] opts the optional parameters
45
+ # @return [MemberResponseBody]
46
+ def verify_member(member_guid, user_guid, opts = {})
47
+ data, _status_code, _headers = verify_member_with_http_info(member_guid, user_guid, opts)
48
+ data
49
+ end
50
+
51
+
52
+ private
53
+
54
+ # Read account numbers
55
+ # Use this endpoint to check whether account and routing numbers are available for accounts associated with a particular member. It returns the account_numbers object, which contains account and routing number data for each account associated with the member.
56
+ # @param member_guid The unique identifier for a `member`.
57
+ # @param user_guid The unique identifier for a `user`.
58
+ # @param [Hash] opts the optional parameters
59
+ # @return [Array<(AccountNumbersResponseBody, Fixnum, Hash)>] AccountNumbersResponseBody data, response status code and response headers
60
+ def list_account_numbers_with_http_info(member_guid, user_guid, opts = {})
61
+ if @api_client.config.debugging
62
+ @api_client.config.logger.debug 'Calling API: VerificationApi.list_account_numbers ...'
63
+ end
64
+ # verify the required parameter 'member_guid' is set
65
+ if @api_client.config.client_side_validation && member_guid.nil?
66
+ fail ArgumentError, "Missing the required parameter 'member_guid' when calling VerificationApi.list_account_numbers"
67
+ end
68
+ # verify the required parameter 'user_guid' is set
69
+ if @api_client.config.client_side_validation && user_guid.nil?
70
+ fail ArgumentError, "Missing the required parameter 'user_guid' when calling VerificationApi.list_account_numbers"
71
+ end
72
+ # resource path
73
+ local_var_path = '/users/{user_guid}/members/{member_guid}/account_numbers'.sub('{' + 'member_guid' + '}', member_guid.to_s).sub('{' + 'user_guid' + '}', user_guid.to_s)
74
+
75
+ # query parameters
76
+ query_params = {}
77
+
78
+ # header parameters
79
+ header_params = {}
80
+ # HTTP header 'Accept' (if needed)
81
+ header_params['Accept'] = @api_client.select_header_accept(['application/vnd.mx.atrium.v1+json'])
82
+
83
+ # form parameters
84
+ form_params = {}
85
+
86
+ # http body (model)
87
+ post_body = nil
88
+ auth_names = ['apiKey', 'clientID']
89
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path,
90
+ :header_params => header_params,
91
+ :query_params => query_params,
92
+ :form_params => form_params,
93
+ :body => post_body,
94
+ :auth_names => auth_names,
95
+ :return_type => 'AccountNumbersResponseBody')
96
+ if @api_client.config.debugging
97
+ @api_client.config.logger.debug "API called: VerificationApi#list_account_numbers\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
98
+ end
99
+ return data, status_code, headers
100
+ end
101
+ # Read account numbers by account GUID
102
+ # Use this endpoint to check whether account and routing numbers are available for a specific account. It returns the account_numbers object, which contains account and routing number data.
103
+ # @param account_guid The unique identifier for an &#x60;account&#x60;.
104
+ # @param user_guid The unique identifier for a &#x60;user&#x60;.
105
+ # @param [Hash] opts the optional parameters
106
+ # @return [Array<(AccountNumbersResponseBody, Fixnum, Hash)>] AccountNumbersResponseBody data, response status code and response headers
107
+ def list_account_numbers_by_account_with_http_info(account_guid, user_guid, opts = {})
108
+ if @api_client.config.debugging
109
+ @api_client.config.logger.debug 'Calling API: VerificationApi.list_account_numbers_by_account ...'
110
+ end
111
+ # verify the required parameter 'account_guid' is set
112
+ if @api_client.config.client_side_validation && account_guid.nil?
113
+ fail ArgumentError, "Missing the required parameter 'account_guid' when calling VerificationApi.list_account_numbers_by_account"
114
+ end
115
+ # verify the required parameter 'user_guid' is set
116
+ if @api_client.config.client_side_validation && user_guid.nil?
117
+ fail ArgumentError, "Missing the required parameter 'user_guid' when calling VerificationApi.list_account_numbers_by_account"
118
+ end
119
+ # resource path
120
+ local_var_path = '/users/{user_guid}/accounts/{account_guid}/account_numbers'.sub('{' + 'account_guid' + '}', account_guid.to_s).sub('{' + 'user_guid' + '}', user_guid.to_s)
121
+
122
+ # query parameters
123
+ query_params = {}
124
+
125
+ # header parameters
126
+ header_params = {}
127
+ # HTTP header 'Accept' (if needed)
128
+ header_params['Accept'] = @api_client.select_header_accept(['application/vnd.mx.atrium.v1+json'])
129
+
130
+ # form parameters
131
+ form_params = {}
132
+
133
+ # http body (model)
134
+ post_body = nil
135
+ auth_names = ['apiKey', 'clientID']
136
+ data, status_code, headers = @api_client.call_api(:GET, local_var_path,
137
+ :header_params => header_params,
138
+ :query_params => query_params,
139
+ :form_params => form_params,
140
+ :body => post_body,
141
+ :auth_names => auth_names,
142
+ :return_type => 'AccountNumbersResponseBody')
143
+ if @api_client.config.debugging
144
+ @api_client.config.logger.debug "API called: VerificationApi#list_account_numbers_by_account\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
145
+ end
146
+ return data, status_code, headers
147
+ end
148
+ # Verify
149
+ # The verify endpoint begins a verification process for a member.
150
+ # @param member_guid The unique identifier for a &#x60;member&#x60;.
151
+ # @param user_guid The unique identifier for a &#x60;user&#x60;.
152
+ # @param [Hash] opts the optional parameters
153
+ # @return [Array<(MemberResponseBody, Fixnum, Hash)>] MemberResponseBody data, response status code and response headers
154
+ def verify_member_with_http_info(member_guid, user_guid, opts = {})
155
+ if @api_client.config.debugging
156
+ @api_client.config.logger.debug 'Calling API: VerificationApi.verify_member ...'
157
+ end
158
+ # verify the required parameter 'member_guid' is set
159
+ if @api_client.config.client_side_validation && member_guid.nil?
160
+ fail ArgumentError, "Missing the required parameter 'member_guid' when calling VerificationApi.verify_member"
161
+ end
162
+ # verify the required parameter 'user_guid' is set
163
+ if @api_client.config.client_side_validation && user_guid.nil?
164
+ fail ArgumentError, "Missing the required parameter 'user_guid' when calling VerificationApi.verify_member"
165
+ end
166
+ # resource path
167
+ local_var_path = '/users/{user_guid}/members/{member_guid}/verify'.sub('{' + 'member_guid' + '}', member_guid.to_s).sub('{' + 'user_guid' + '}', user_guid.to_s)
168
+
169
+ # query parameters
170
+ query_params = {}
171
+
172
+ # header parameters
173
+ header_params = {}
174
+ # HTTP header 'Accept' (if needed)
175
+ header_params['Accept'] = @api_client.select_header_accept(['application/vnd.mx.atrium.v1+json'])
176
+ # HTTP header 'Content-Type'
177
+ header_params['Content-Type'] = @api_client.select_header_content_type(['application/json'])
178
+
179
+ # form parameters
180
+ form_params = {}
181
+
182
+ # http body (model)
183
+ post_body = nil
184
+ auth_names = ['apiKey', 'clientID']
185
+ data, status_code, headers = @api_client.call_api(:POST, local_var_path,
186
+ :header_params => header_params,
187
+ :query_params => query_params,
188
+ :form_params => form_params,
189
+ :body => post_body,
190
+ :auth_names => auth_names,
191
+ :return_type => 'MemberResponseBody')
192
+ if @api_client.config.debugging
193
+ @api_client.config.logger.debug "API called: VerificationApi#verify_member\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
194
+ end
195
+ return data, status_code, headers
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,384 @@
1
+ =begin
2
+ #MX API
3
+
4
+ #The MX Atrium API supports over 48,000 data connections to thousands of financial institutions. It provides secure access to your users' accounts and transactions with industry-leading cleansing, categorization, and classification. Atrium is designed according to resource-oriented REST architecture and responds with JSON bodies and HTTP response codes. Use Atrium's development environment, vestibule.mx.com, to quickly get up and running. The development environment limits are 100 users, 25 members per user, and access to the top 15 institutions. Contact MX to purchase production access.
5
+
6
+
7
+ =end
8
+
9
+ require 'date'
10
+ require 'json'
11
+ require 'logger'
12
+ require 'tempfile'
13
+ require 'typhoeus'
14
+ require 'uri'
15
+
16
+ module Atrium
17
+ class ApiClient
18
+ # The Configuration object holding settings to be used in the API client.
19
+ attr_accessor :config
20
+
21
+ # Defines the headers to be used in HTTP requests of all API calls by default.
22
+ #
23
+ # @return [Hash]
24
+ attr_accessor :default_headers
25
+
26
+ # Initializes the ApiClient
27
+ # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
28
+ def initialize(config = Configuration.default)
29
+ @config = config
30
+ @user_agent = "MX-Codegen/#{VERSION}/ruby"
31
+ @default_headers = {
32
+ 'Content-Type' => 'application/json',
33
+ 'User-Agent' => @user_agent
34
+ }
35
+ end
36
+
37
+ def self.default
38
+ @@default ||= ApiClient.new
39
+ end
40
+
41
+ # Call an API with given options.
42
+ #
43
+ # @return [Array<(Object, Fixnum, Hash)>] an array of 3 elements:
44
+ # the data deserialized from response body (could be nil), response status code and response headers.
45
+ def call_api(http_method, path, opts = {})
46
+ request = build_request(http_method, path, opts)
47
+ response = request.run
48
+
49
+ if @config.debugging
50
+ @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
51
+ end
52
+
53
+ unless response.success?
54
+ if response.timed_out?
55
+ fail ApiError.new('Connection timed out')
56
+ elsif response.code == 0
57
+ # Errors from libcurl will be made visible here
58
+ fail ApiError.new(:code => 0,
59
+ :message => response.return_message)
60
+ else
61
+ fail ApiError.new(:code => response.code,
62
+ :response_headers => response.headers,
63
+ :response_body => response.body),
64
+ response.status_message
65
+ end
66
+ end
67
+
68
+ if opts[:return_type]
69
+ data = deserialize(response, opts[:return_type])
70
+ else
71
+ data = nil
72
+ end
73
+ return data, response.code, response.headers
74
+ end
75
+
76
+ # Builds the HTTP request
77
+ #
78
+ # @param [String] http_method HTTP method/verb (e.g. POST)
79
+ # @param [String] path URL path (e.g. /account/new)
80
+ # @option opts [Hash] :header_params Header parameters
81
+ # @option opts [Hash] :query_params Query parameters
82
+ # @option opts [Hash] :form_params Query parameters
83
+ # @option opts [Object] :body HTTP body (JSON/XML)
84
+ # @return [Typhoeus::Request] A Typhoeus Request
85
+ def build_request(http_method, path, opts = {})
86
+ url = build_request_url(path)
87
+ http_method = http_method.to_sym.downcase
88
+
89
+ header_params = @default_headers.merge(opts[:header_params] || {})
90
+ query_params = opts[:query_params] || {}
91
+ form_params = opts[:form_params] || {}
92
+
93
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
94
+
95
+ # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
96
+ _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
97
+
98
+ req_opts = {
99
+ :method => http_method,
100
+ :headers => header_params,
101
+ :params => query_params,
102
+ :params_encoding => @config.params_encoding,
103
+ :timeout => @config.timeout,
104
+ :ssl_verifypeer => @config.verify_ssl,
105
+ :ssl_verifyhost => _verify_ssl_host,
106
+ :sslcert => @config.cert_file,
107
+ :sslkey => @config.key_file,
108
+ :verbose => @config.debugging
109
+ }
110
+
111
+ # set custom cert, if provided
112
+ req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
113
+
114
+ if [:post, :patch, :put, :delete].include?(http_method)
115
+ req_body = build_request_body(header_params, form_params, opts[:body])
116
+ req_opts.update :body => req_body
117
+ if @config.debugging
118
+ @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
119
+ end
120
+ end
121
+
122
+ request = Typhoeus::Request.new(url, req_opts)
123
+ download_file(request) if opts[:return_type] == 'File'
124
+ request
125
+ end
126
+
127
+ # Check if the given MIME is a JSON MIME.
128
+ # JSON MIME examples:
129
+ # application/json
130
+ # application/json; charset=UTF8
131
+ # APPLICATION/JSON
132
+ # */*
133
+ # @param [String] mime MIME
134
+ # @return [Boolean] True if the MIME is application/json
135
+ def json_mime?(mime)
136
+ (mime == '*/*') || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
137
+ end
138
+
139
+ # Deserialize the response to the given return type.
140
+ #
141
+ # @param [Response] response HTTP response
142
+ # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
143
+ def deserialize(response, return_type)
144
+ body = response.body
145
+
146
+ # handle file downloading - return the File instance processed in request callbacks
147
+ # note that response body is empty when the file is written in chunks in request on_body callback
148
+ return @tempfile if return_type == 'File'
149
+
150
+ return nil if body.nil? || body.empty?
151
+
152
+ # return response body directly for String return type
153
+ return body if return_type == 'String'
154
+
155
+ # ensuring a default content type
156
+ content_type = response.headers['Content-Type'] || 'application/json'
157
+
158
+ fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
159
+
160
+ begin
161
+ data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
162
+ rescue JSON::ParserError => e
163
+ if %w(String Date DateTime).include?(return_type)
164
+ data = body
165
+ else
166
+ raise e
167
+ end
168
+ end
169
+
170
+ convert_to_type data, return_type
171
+ end
172
+
173
+ # Convert data to the given return type.
174
+ # @param [Object] data Data to be converted
175
+ # @param [String] return_type Return type
176
+ # @return [Mixed] Data in a particular type
177
+ def convert_to_type(data, return_type)
178
+ return nil if data.nil?
179
+ case return_type
180
+ when 'String'
181
+ data.to_s
182
+ when 'Integer'
183
+ data.to_i
184
+ when 'Float'
185
+ data.to_f
186
+ when 'BOOLEAN'
187
+ data == true
188
+ when 'DateTime'
189
+ # parse date time (expecting ISO 8601 format)
190
+ DateTime.parse data
191
+ when 'Date'
192
+ # parse date time (expecting ISO 8601 format)
193
+ Date.parse data
194
+ when 'Object'
195
+ # generic object (usually a Hash), return directly
196
+ data
197
+ when /\AArray<(.+)>\z/
198
+ # e.g. Array<Pet>
199
+ sub_type = $1
200
+ data.map { |item| convert_to_type(item, sub_type) }
201
+ when /\AHash\<String, (.+)\>\z/
202
+ # e.g. Hash<String, Integer>
203
+ sub_type = $1
204
+ {}.tap do |hash|
205
+ data.each { |k, v| hash[k] = convert_to_type(v, sub_type) }
206
+ end
207
+ else
208
+ # models, e.g. Pet
209
+ Atrium.const_get(return_type).new.tap do |model|
210
+ model.build_from_hash data
211
+ end
212
+ end
213
+ end
214
+
215
+ # Save response body into a file in (the defined) temporary folder, using the filename
216
+ # from the "Content-Disposition" header if provided, otherwise a random filename.
217
+ # The response body is written to the file in chunks in order to handle files which
218
+ # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby
219
+ # process can use.
220
+ #
221
+ # @see Configuration#temp_folder_path
222
+ def download_file(request)
223
+ tempfile = nil
224
+ encoding = nil
225
+ request.on_headers do |response|
226
+ content_disposition = response.headers['Content-Disposition']
227
+ if content_disposition && content_disposition =~ /filename=/i
228
+ filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
229
+ prefix = sanitize_filename(filename)
230
+ else
231
+ prefix = 'download-'
232
+ end
233
+ prefix = prefix + '-' unless prefix.end_with?('-')
234
+ encoding = response.body.encoding
235
+ tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
236
+ @tempfile = tempfile
237
+ end
238
+ request.on_body do |chunk|
239
+ chunk.force_encoding(encoding)
240
+ tempfile.write(chunk)
241
+ end
242
+ request.on_complete do |response|
243
+ tempfile.close
244
+ @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
245
+ "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
246
+ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
247
+ "explicitly with `tempfile.delete`"
248
+ end
249
+ end
250
+
251
+ # Sanitize filename by removing path.
252
+ # e.g. ../../sun.gif becomes sun.gif
253
+ #
254
+ # @param [String] filename the filename to be sanitized
255
+ # @return [String] the sanitized filename
256
+ def sanitize_filename(filename)
257
+ filename.gsub(/.*[\/\\]/, '')
258
+ end
259
+
260
+ def build_request_url(path)
261
+ # Add leading and trailing slashes to path
262
+ path = "/#{path}".gsub(/\/+/, '/')
263
+ URI.encode(@config.base_url + path)
264
+ end
265
+
266
+ # Builds the HTTP request body
267
+ #
268
+ # @param [Hash] header_params Header parameters
269
+ # @param [Hash] form_params Query parameters
270
+ # @param [Object] body HTTP body (JSON/XML)
271
+ # @return [String] HTTP body data in the form of string
272
+ def build_request_body(header_params, form_params, body)
273
+ # http form
274
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
275
+ header_params['Content-Type'] == 'multipart/form-data'
276
+ data = {}
277
+ form_params.each do |key, value|
278
+ case value
279
+ when ::File, ::Array, nil
280
+ # let typhoeus handle File, Array and nil parameters
281
+ data[key] = value
282
+ else
283
+ data[key] = value.to_s
284
+ end
285
+ end
286
+ elsif body
287
+ data = body.is_a?(String) ? body : body.to_json
288
+ else
289
+ data = nil
290
+ end
291
+ data
292
+ end
293
+
294
+ # Update hearder and query params based on authentication settings.
295
+ #
296
+ # @param [Hash] header_params Header parameters
297
+ # @param [Hash] query_params Query parameters
298
+ # @param [String] auth_names Authentication scheme name
299
+ def update_params_for_auth!(header_params, query_params, auth_names)
300
+ Array(auth_names).each do |auth_name|
301
+ auth_setting = @config.auth_settings[auth_name]
302
+ next unless auth_setting
303
+ case auth_setting[:in]
304
+ when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
305
+ when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
306
+ else fail ArgumentError, 'Authentication token must be in `query` of `header`'
307
+ end
308
+ end
309
+ end
310
+
311
+ # Sets user agent in HTTP header
312
+ #
313
+ def user_agent=(user_agent)
314
+ @user_agent = user_agent
315
+ @default_headers['User-Agent'] = @user_agent
316
+ end
317
+
318
+ # Return Accept header based on an array of accepts provided.
319
+ # @param [Array] accepts array for Accept
320
+ # @return [String] the Accept header (e.g. application/json)
321
+ def select_header_accept(accepts)
322
+ return nil if accepts.nil? || accepts.empty?
323
+ # use JSON when present, otherwise use all of the provided
324
+ json_accept = accepts.find { |s| json_mime?(s) }
325
+ json_accept || accepts.join(',')
326
+ end
327
+
328
+ # Return Content-Type header based on an array of content types provided.
329
+ # @param [Array] content_types array for Content-Type
330
+ # @return [String] the Content-Type header (e.g. application/json)
331
+ def select_header_content_type(content_types)
332
+ # use application/json by default
333
+ return 'application/json' if content_types.nil? || content_types.empty?
334
+ # use JSON when present, otherwise use the first one
335
+ json_content_type = content_types.find { |s| json_mime?(s) }
336
+ json_content_type || content_types.first
337
+ end
338
+
339
+ # Convert object (array, hash, object, etc) to JSON string.
340
+ # @param [Object] model object to be converted into JSON string
341
+ # @return [String] JSON string representation of the object
342
+ def object_to_http_body(model)
343
+ return model if model.nil? || model.is_a?(String)
344
+ local_body = nil
345
+ if model.is_a?(Array)
346
+ local_body = model.map { |m| object_to_hash(m) }
347
+ else
348
+ local_body = object_to_hash(model)
349
+ end
350
+ local_body.to_json
351
+ end
352
+
353
+ # Convert object(non-array) to hash.
354
+ # @param [Object] obj object to be converted into JSON string
355
+ # @return [String] JSON string representation of the object
356
+ def object_to_hash(obj)
357
+ if obj.respond_to?(:to_hash)
358
+ obj.to_hash
359
+ else
360
+ obj
361
+ end
362
+ end
363
+
364
+ # Build parameter value according to the given collection format.
365
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
366
+ def build_collection_param(param, collection_format)
367
+ case collection_format
368
+ when :csv
369
+ param.join(',')
370
+ when :ssv
371
+ param.join(' ')
372
+ when :tsv
373
+ param.join("\t")
374
+ when :pipes
375
+ param.join('|')
376
+ when :multi
377
+ # return the array directly as typhoeus will handle it as expected
378
+ param
379
+ else
380
+ fail "unknown collection format: #{collection_format.inspect}"
381
+ end
382
+ end
383
+ end
384
+ end