dexa-ai-sdk 0.3.5

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 (91) hide show
  1. checksums.yaml +7 -0
  2. data/.fernignore +5 -0
  3. data/.rubocop.yml +107 -0
  4. data/CONTRIBUTING.md +120 -0
  5. data/README.md +199 -0
  6. data/Rakefile +20 -0
  7. data/custom.gemspec.rb +23 -0
  8. data/lib/dexa-ai-sdk/client.rb +26 -0
  9. data/lib/dexa-ai-sdk/environment.rb +7 -0
  10. data/lib/dexa-ai-sdk/errors/api_error.rb +8 -0
  11. data/lib/dexa-ai-sdk/errors/client_error.rb +17 -0
  12. data/lib/dexa-ai-sdk/errors/connection_error.rb +11 -0
  13. data/lib/dexa-ai-sdk/errors/redirect_error.rb +8 -0
  14. data/lib/dexa-ai-sdk/errors/response_error.rb +63 -0
  15. data/lib/dexa-ai-sdk/errors/server_error.rb +11 -0
  16. data/lib/dexa-ai-sdk/errors/timeout_error.rb +8 -0
  17. data/lib/dexa-ai-sdk/internal/errors/constraint_error.rb +10 -0
  18. data/lib/dexa-ai-sdk/internal/errors/type_error.rb +10 -0
  19. data/lib/dexa-ai-sdk/internal/http/base_request.rb +81 -0
  20. data/lib/dexa-ai-sdk/internal/http/raw_client.rb +295 -0
  21. data/lib/dexa-ai-sdk/internal/iterators/cursor_item_iterator.rb +33 -0
  22. data/lib/dexa-ai-sdk/internal/iterators/cursor_page_iterator.rb +117 -0
  23. data/lib/dexa-ai-sdk/internal/iterators/item_iterator.rb +111 -0
  24. data/lib/dexa-ai-sdk/internal/iterators/offset_item_iterator.rb +35 -0
  25. data/lib/dexa-ai-sdk/internal/iterators/offset_page_iterator.rb +151 -0
  26. data/lib/dexa-ai-sdk/internal/json/request.rb +50 -0
  27. data/lib/dexa-ai-sdk/internal/json/serializable.rb +25 -0
  28. data/lib/dexa-ai-sdk/internal/multipart/multipart_encoder.rb +141 -0
  29. data/lib/dexa-ai-sdk/internal/multipart/multipart_form_data.rb +83 -0
  30. data/lib/dexa-ai-sdk/internal/multipart/multipart_form_data_part.rb +51 -0
  31. data/lib/dexa-ai-sdk/internal/multipart/multipart_request.rb +41 -0
  32. data/lib/dexa-ai-sdk/internal/types/array.rb +47 -0
  33. data/lib/dexa-ai-sdk/internal/types/boolean.rb +34 -0
  34. data/lib/dexa-ai-sdk/internal/types/enum.rb +56 -0
  35. data/lib/dexa-ai-sdk/internal/types/hash.rb +36 -0
  36. data/lib/dexa-ai-sdk/internal/types/model/field.rb +38 -0
  37. data/lib/dexa-ai-sdk/internal/types/model.rb +220 -0
  38. data/lib/dexa-ai-sdk/internal/types/type.rb +35 -0
  39. data/lib/dexa-ai-sdk/internal/types/union.rb +161 -0
  40. data/lib/dexa-ai-sdk/internal/types/unknown.rb +15 -0
  41. data/lib/dexa-ai-sdk/internal/types/utils.rb +123 -0
  42. data/lib/dexa-ai-sdk/tasks/client.rb +190 -0
  43. data/lib/dexa-ai-sdk/tasks/types/decide_request.rb +37 -0
  44. data/lib/dexa-ai-sdk/tasks/types/decide_request_output_language.rb +32 -0
  45. data/lib/dexa-ai-sdk/tasks/types/decide_request_response_format.rb +11 -0
  46. data/lib/dexa-ai-sdk/tasks/types/decide_request_response_format_type.rb +13 -0
  47. data/lib/dexa-ai-sdk/tasks/types/decide_request_target_language.rb +32 -0
  48. data/lib/dexa-ai-sdk/tasks/types/extract_request.rb +37 -0
  49. data/lib/dexa-ai-sdk/tasks/types/extract_request_output_language.rb +32 -0
  50. data/lib/dexa-ai-sdk/tasks/types/extract_request_response_format.rb +11 -0
  51. data/lib/dexa-ai-sdk/tasks/types/extract_request_response_format_type.rb +13 -0
  52. data/lib/dexa-ai-sdk/tasks/types/extract_request_target_language.rb +32 -0
  53. data/lib/dexa-ai-sdk/types/audio_input.rb +15 -0
  54. data/lib/dexa-ai-sdk/types/audio_input_type.rb +12 -0
  55. data/lib/dexa-ai-sdk/types/choice.rb +11 -0
  56. data/lib/dexa-ai-sdk/types/choice_finish_reason.rb +13 -0
  57. data/lib/dexa-ai-sdk/types/content_part.rb +21 -0
  58. data/lib/dexa-ai-sdk/types/content_part_language.rb +30 -0
  59. data/lib/dexa-ai-sdk/types/content_part_type.rb +15 -0
  60. data/lib/dexa-ai-sdk/types/decide_response.rb +21 -0
  61. data/lib/dexa-ai-sdk/types/decide_result.rb +11 -0
  62. data/lib/dexa-ai-sdk/types/decide_task.rb +21 -0
  63. data/lib/dexa-ai-sdk/types/decide_task_target_language.rb +30 -0
  64. data/lib/dexa-ai-sdk/types/error_response.rb +9 -0
  65. data/lib/dexa-ai-sdk/types/error_response_error.rb +15 -0
  66. data/lib/dexa-ai-sdk/types/extract_response.rb +19 -0
  67. data/lib/dexa-ai-sdk/types/extract_task.rb +21 -0
  68. data/lib/dexa-ai-sdk/types/extract_task_target_language.rb +30 -0
  69. data/lib/dexa-ai-sdk/types/image_input.rb +15 -0
  70. data/lib/dexa-ai-sdk/types/image_input_type.rb +12 -0
  71. data/lib/dexa-ai-sdk/types/image_url.rb +11 -0
  72. data/lib/dexa-ai-sdk/types/image_url_detail.rb +13 -0
  73. data/lib/dexa-ai-sdk/types/message.rb +13 -0
  74. data/lib/dexa-ai-sdk/types/message_content.rb +13 -0
  75. data/lib/dexa-ai-sdk/types/message_language.rb +30 -0
  76. data/lib/dexa-ai-sdk/types/message_role.rb +13 -0
  77. data/lib/dexa-ai-sdk/types/response_message.rb +13 -0
  78. data/lib/dexa-ai-sdk/types/response_message_language.rb +30 -0
  79. data/lib/dexa-ai-sdk/types/response_message_role.rb +11 -0
  80. data/lib/dexa-ai-sdk/types/run_tasks_request.rb +29 -0
  81. data/lib/dexa-ai-sdk/types/run_tasks_request_output_language.rb +30 -0
  82. data/lib/dexa-ai-sdk/types/run_tasks_request_response_format.rb +9 -0
  83. data/lib/dexa-ai-sdk/types/run_tasks_request_response_format_type.rb +11 -0
  84. data/lib/dexa-ai-sdk/types/run_tasks_request_target_language.rb +30 -0
  85. data/lib/dexa-ai-sdk/types/run_tasks_response.rb +19 -0
  86. data/lib/dexa-ai-sdk/types/task.rb +15 -0
  87. data/lib/dexa-ai-sdk/types/usage.rb +13 -0
  88. data/lib/dexa-ai-sdk/version.rb +5 -0
  89. data/lib/dexa-ai-sdk.rb +86 -0
  90. data/reference.md +414 -0
  91. metadata +139 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 89029c150650fa7fadcc17e73039f62f2215b503299399d85532bb1e738e3243
4
+ data.tar.gz: aa5c528001b1869d3f3bb6ed704a4c168c27cc4df713b12adfbbd2ae61fc1f80
5
+ SHA512:
6
+ metadata.gz: 0aafbd9558802782b5b369d3da7c92f4bf4f70f660fd42a42a6d81aad2100f12da61ed4e23be39d45cbb568f505ba71cc46cfcdf806faf9b617598cae45f4fa7
7
+ data.tar.gz: 6baceb703451c8988b4808fcd4c5fadd44303e5b6c7c0c87c2c691e7a45c8126df867782113f49ac5a0da0a61c0afd7e6b1135ed08e2f57586e785a4f20d09ac
data/.fernignore ADDED
@@ -0,0 +1,5 @@
1
+ # Fern overwrites these on every generation, which would undo the gem's identity.
2
+ # custom.gemspec.rb is the documented hook for setting the gem name, authors,
3
+ # licence and links, because the Fern API has no name of its own and the
4
+ # generator otherwise falls back to the organization name.
5
+ custom.gemspec.rb
data/.rubocop.yml ADDED
@@ -0,0 +1,107 @@
1
+ plugins:
2
+ - rubocop-minitest
3
+
4
+ AllCops:
5
+ TargetRubyVersion: 3.3
6
+ NewCops: enable
7
+
8
+ Style/StringLiterals:
9
+ EnforcedStyle: double_quotes
10
+
11
+ Style/StringLiteralsInInterpolation:
12
+ EnforcedStyle: double_quotes
13
+
14
+ Style/AccessModifierDeclarations:
15
+ Enabled: false
16
+
17
+ Lint/ConstantDefinitionInBlock:
18
+ Enabled: false
19
+
20
+ Metrics/AbcSize:
21
+ Enabled: false
22
+
23
+ Metrics/BlockLength:
24
+ Enabled: false
25
+
26
+ Metrics/ClassLength:
27
+ Enabled: false
28
+
29
+ Metrics/MethodLength:
30
+ Enabled: false
31
+
32
+ Metrics/ParameterLists:
33
+ Enabled: false
34
+
35
+ Metrics/PerceivedComplexity:
36
+ Enabled: false
37
+
38
+ Metrics/CyclomaticComplexity:
39
+ Enabled: false
40
+
41
+ Metrics/ModuleLength:
42
+ Enabled: false
43
+
44
+ Layout/LineLength:
45
+ Enabled: false
46
+
47
+ Naming/VariableNumber:
48
+ EnforcedStyle: normalcase
49
+ Severity: warning
50
+
51
+ Style/Documentation:
52
+ Enabled: false
53
+
54
+ Style/Lambda:
55
+ EnforcedStyle: literal
56
+
57
+ # Docstrings come from API definitions and often start with words like "Note:".
58
+ Style/CommentAnnotation:
59
+ Enabled: false
60
+
61
+ Minitest/MultipleAssertions:
62
+ Enabled: false
63
+
64
+ Minitest/UselessAssertion:
65
+ Enabled: false
66
+
67
+ # Dynamic snippets are code samples for documentation, not standalone Ruby files.
68
+ Style/FrozenStringLiteralComment:
69
+ Exclude:
70
+ - "dynamic-snippets/**/*"
71
+
72
+ # Indent hash elements 2 spaces from the start of the enclosing line rather than
73
+ # aligning with the preceding paren or bracket. Generated code nests hashes inside
74
+ # arrays and method calls; the "consistent" style is more readable there.
75
+ Layout/FirstHashElementIndentation:
76
+ EnforcedStyle: consistent
77
+ Exclude:
78
+ - "dynamic-snippets/**/*"
79
+
80
+ # Match Layout/FirstHashElementIndentation: indent the first argument 2 spaces
81
+ # from the start of the method call's line, regardless of parenthesis position.
82
+ # Dynamic snippets are code samples, not standalone Ruby files; exclude them to
83
+ # keep this config symmetric with Layout/FirstHashElementIndentation above.
84
+ Layout/FirstArgumentIndentation:
85
+ EnforcedStyle: consistent
86
+ Exclude:
87
+ - "dynamic-snippets/**/*"
88
+
89
+ # The generator emits non-idiomatic class names (e.g. Get_With_Query, JSON_)
90
+ # derived from IR type names whose wire form contains underscores or digits.
91
+ # Rubocop never auto-corrected these (naming cops have no autocorrecter), so
92
+ # disabling the cop keeps CI green without changing customer output. Fixing at
93
+ # source would rename public types across every existing SDK and therefore
94
+ # requires a ruby-v2 major-version bump with a generator migration.
95
+ Naming/ClassAndModuleCamelCase:
96
+ Enabled: false
97
+
98
+ # Integer literals are emitted unformatted (e.g. 1000000, not 1_000_000).
99
+ # Rubocop has an autocorrecter for this cop, but the only caller of integer
100
+ # emission is the dynamic-snippets path, which feeds customer-facing surfaces:
101
+ # (1) snippet markdown in reference docs, (2) dynamic-snippets/*.rb sample
102
+ # files. Neither is rubocop-gated (markdown isn't Ruby, dynamic-snippets/**/*
103
+ # is excluded above), so formatting integers there would change docs/dashboard
104
+ # output without any rubocop benefit. Disabling the cop keeps integers raw
105
+ # everywhere and avoids customer-visible diffs.
106
+ Style/NumericLiterals:
107
+ Enabled: false
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,120 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in contributing to this SDK! This document provides guidelines for contributing to the project.
4
+
5
+ ## Getting Started
6
+
7
+ ### Prerequisites
8
+
9
+ - Ruby 3.0+
10
+ - Bundler
11
+
12
+ ### Installation
13
+
14
+ Install the project dependencies:
15
+
16
+ ```bash
17
+ bundle install
18
+ ```
19
+
20
+ ### Building
21
+
22
+ Build the gem:
23
+
24
+ ```bash
25
+ gem build *.gemspec
26
+ ```
27
+
28
+ ### Testing
29
+
30
+ Run the test suite:
31
+
32
+ ```bash
33
+ bundle exec rspec
34
+ ```
35
+
36
+ ### Linting and Formatting
37
+
38
+ Check code style:
39
+
40
+ ```bash
41
+ bundle exec rubocop
42
+ ```
43
+
44
+ Fix code style issues:
45
+
46
+ ```bash
47
+ bundle exec rubocop -a
48
+ ```
49
+
50
+ ## About Generated Code
51
+
52
+ **Important**: Most files in this SDK are automatically generated by [Fern](https://buildwithfern.com) from the API definition. Direct modifications to generated files will be overwritten the next time the SDK is generated.
53
+
54
+ ### Generated Files
55
+
56
+ The following directories contain generated code:
57
+ - `lib/` - API client classes and types
58
+ - Most Ruby files in the project
59
+
60
+ ### How to Customize
61
+
62
+ If you need to customize the SDK, you have two options:
63
+
64
+ #### Option 1: Use `.fernignore`
65
+
66
+ For custom code that should persist across SDK regenerations:
67
+
68
+ 1. Create a `.fernignore` file in the project root
69
+ 2. Add file patterns for files you want to preserve (similar to `.gitignore` syntax)
70
+ 3. Add your custom code to those files
71
+
72
+ Files listed in `.fernignore` will not be overwritten when the SDK is regenerated.
73
+
74
+ For more information, see the [Fern documentation on custom code](https://buildwithfern.com/learn/sdks/overview/custom-code).
75
+
76
+ #### Option 2: Contribute to the Generator
77
+
78
+ If you want to change how code is generated for all users of this SDK:
79
+
80
+ 1. The Ruby SDK generator lives in the [Fern repository](https://github.com/fern-api/fern)
81
+ 2. Generator code is located at `generators/ruby-v2/`
82
+ 3. Follow the [Fern contributing guidelines](https://github.com/fern-api/fern/blob/main/CONTRIBUTING.md)
83
+ 4. Submit a pull request with your changes to the generator
84
+
85
+ This approach is best for:
86
+ - Bug fixes in generated code
87
+ - New features that would benefit all users
88
+ - Improvements to code generation patterns
89
+
90
+ ## Making Changes
91
+
92
+ ### Workflow
93
+
94
+ 1. Create a new branch for your changes
95
+ 2. Make your modifications
96
+ 3. Run tests to ensure nothing breaks: `bundle exec rspec`
97
+ 4. Run linting: `bundle exec rubocop`
98
+ 5. Build the gem: `gem build *.gemspec`
99
+ 6. Commit your changes with a clear commit message
100
+ 7. Push your branch and create a pull request
101
+
102
+ ### Commit Messages
103
+
104
+ Write clear, descriptive commit messages that explain what changed and why.
105
+
106
+ ### Code Style
107
+
108
+ This project uses RuboCop for code formatting. Run `bundle exec rubocop` before committing to ensure your code meets the project's style guidelines.
109
+
110
+ ## Questions or Issues?
111
+
112
+ If you have questions or run into issues:
113
+
114
+ 1. Check the [Fern documentation](https://buildwithfern.com)
115
+ 2. Search existing [GitHub issues](https://github.com/fern-api/fern/issues)
116
+ 3. Open a new issue if your question hasn't been addressed
117
+
118
+ ## License
119
+
120
+ By contributing to this project, you agree that your contributions will be licensed under the same license as the project.
data/README.md ADDED
@@ -0,0 +1,199 @@
1
+ # DexaAiSdk Ruby Library
2
+
3
+ [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=DexaAiSdk%2FRuby)
4
+
5
+ The DexaAiSdk Ruby library provides convenient access to the DexaAiSdk APIs from Ruby.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Reference](#reference)
10
+ - [Usage](#usage)
11
+ - [Environments](#environments)
12
+ - [Errors](#errors)
13
+ - [Advanced](#advanced)
14
+ - [Retries](#retries)
15
+ - [Timeouts](#timeouts)
16
+ - [Additional Headers](#additional-headers)
17
+ - [Additional Query Parameters](#additional-query-parameters)
18
+ - [Additional Body Properties](#additional-body-properties)
19
+ - [Contributing](#contributing)
20
+
21
+ ## Reference
22
+
23
+ A full reference for this library is available [here](./reference.md).
24
+
25
+ ## Usage
26
+
27
+ Instantiate and use the client with the following:
28
+
29
+ ```ruby
30
+ require "dexa-ai-sdk"
31
+
32
+ client = DexaAiSdk::Client.new
33
+
34
+ client.tasks.run_tasks(
35
+ model: "model",
36
+ tasks: []
37
+ )
38
+ ```
39
+
40
+ ## Environments
41
+
42
+ This SDK allows you to configure different environments or custom URLs for API requests. You can either use the predefined environments or specify your own custom URL.
43
+ ### Environments
44
+ ```ruby
45
+ require "dexa-ai-sdk"
46
+
47
+ dexa-ai-sdk = DexaAiSdk::Client.new(
48
+ base_url: DexaAiSdk::Environment::DEFAULT
49
+ )
50
+ ```
51
+
52
+ ### Custom URL
53
+ ```ruby
54
+ require "dexa-ai-sdk"
55
+
56
+ client = DexaAiSdk::Client.new(
57
+ base_url: "https://example.com"
58
+ )
59
+ ```
60
+
61
+ ## Errors
62
+
63
+ Failed API calls will raise errors that can be rescued from granularly.
64
+
65
+ ```ruby
66
+ require "dexa-ai-sdk"
67
+
68
+ client = DexaAiSdk::Client.new(
69
+ base_url: "https://example.com"
70
+ )
71
+
72
+ begin
73
+ result = client.tasks.run_tasks
74
+ rescue DexaAiSdk::Errors::TimeoutError
75
+ puts "API didn't respond before our timeout elapsed"
76
+ rescue DexaAiSdk::Errors::ConnectionError => e
77
+ puts "Could not reach the API (connection refused, reset, DNS or TLS failure): #{e.message}"
78
+ rescue DexaAiSdk::Errors::ServiceUnavailableError
79
+ puts "API returned status 503, is probably overloaded, try again later"
80
+ rescue DexaAiSdk::Errors::ServerError
81
+ puts "API returned some other 5xx status, this is probably a bug"
82
+ rescue DexaAiSdk::Errors::ResponseError => e
83
+ puts "API returned an unexpected status other than 5xx: #{e.code} #{e.message}"
84
+ rescue DexaAiSdk::Errors::ApiError => e
85
+ puts "Some other error occurred when calling the API: #{e.message}"
86
+ end
87
+ ```
88
+
89
+ ## Advanced
90
+
91
+ ### Retries
92
+
93
+ The SDK is instrumented with automatic retries. A request will be retried as long as the request is deemed
94
+ retryable and the number of retry attempts has not grown larger than the configured retry limit (default: 2).
95
+
96
+ A request is deemed retryable when any of the following HTTP status codes is returned:
97
+
98
+ - [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout)
99
+ - [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests)
100
+ - [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#server_error_responses) (Internal Server Error)
101
+
102
+ The `retryStatusCodes` configuration controls which [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#server_error_responses) status codes are retried:
103
+
104
+ - `legacy` (default): Retries `408`, `429`, `500`, `502`, `503`, `504`, `521`, `522`, `524`
105
+ - `recommended`: Retries `408`, `429`, `502`, `503`, `504` only (excludes `500 Internal Server Error` to avoid retrying non-idempotent failures)
106
+
107
+ Use the `max_retries` option to configure this behavior.
108
+
109
+ ```ruby
110
+ require "dexa-ai-sdk"
111
+
112
+ client = DexaAiSdk::Client.new(
113
+ base_url: "https://example.com",
114
+ max_retries: 3 # Configure max retries (default is 2)
115
+ )
116
+ ```
117
+
118
+ ### Timeouts
119
+
120
+ The SDK defaults to a 60 second timeout. Use the `timeout` option to configure this behavior.
121
+
122
+ ```ruby
123
+ require "dexa-ai-sdk"
124
+
125
+ # Set the default timeout (in seconds) for every request made by the client.
126
+ client = DexaAiSdk::Client.new(
127
+ base_url: "https://example.com",
128
+ timeout: 30
129
+ )
130
+
131
+ # Override the timeout for an individual request.
132
+ response = client.tasks.run_tasks(
133
+ ...,
134
+ request_options: { timeout_in_seconds: 10 }
135
+ )
136
+ ```
137
+
138
+ ### Additional Headers
139
+
140
+ If you would like to send additional headers as part of the request, use the `additional_headers` request option.
141
+
142
+ ```ruby
143
+ require "dexa-ai-sdk"
144
+
145
+ response = client.tasks.run_tasks(
146
+ ...,
147
+ request_options: {
148
+ additional_headers: {
149
+ "X-Custom-Header" => "custom-value"
150
+ }
151
+ }
152
+ )
153
+ ```
154
+
155
+ ### Additional Query Parameters
156
+
157
+ If you would like to send additional query parameters as part of the request, use the `additional_query_parameters` request option.
158
+
159
+ ```ruby
160
+ require "dexa-ai-sdk"
161
+
162
+ response = client.tasks.run_tasks(
163
+ ...,
164
+ request_options: {
165
+ additional_query_parameters: {
166
+ "custom_param" => "custom-value"
167
+ }
168
+ }
169
+ )
170
+ ```
171
+
172
+ ### Additional Body Properties
173
+
174
+ If you would like to send additional body properties as part of the request, use the `additional_body_parameters` request option.
175
+ Properties are merged into the serialized request body using their API (wire-format) names and override any field the SDK sets with the same name. If the endpoint has no body, one is created from these properties, except for GET and HEAD requests, which are always sent without a body (the properties are ignored).
176
+ This applies to JSON and form-urlencoded requests; it is not applied to multipart (file upload) requests.
177
+
178
+ ```ruby
179
+ require "dexa-ai-sdk"
180
+
181
+ response = client.tasks.run_tasks(
182
+ ...,
183
+ request_options: {
184
+ additional_body_parameters: {
185
+ "custom_field" => "custom-value"
186
+ }
187
+ }
188
+ )
189
+ ```
190
+
191
+ ## Contributing
192
+
193
+ While we value open-source contributions to this SDK, this library is generated programmatically.
194
+ Additions made directly to this library would have to be moved over to our generation code,
195
+ otherwise they would be overwritten upon the next generated release. Feel free to open a PR as
196
+ a proof of concept, but know that we will not be able to merge it as-is. We suggest opening
197
+ an issue first to discuss with us!
198
+
199
+ On the other hand, contributions to the README are always very welcome!
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "minitest/test_task"
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[test]
13
+
14
+ task lint: %i[rubocop]
15
+
16
+ # Run only the custom test file
17
+ Minitest::TestTask.create(:customtest) do |t|
18
+ t.libs << "test"
19
+ t.test_globs = ["test/custom.test.rb"]
20
+ end
data/custom.gemspec.rb ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Custom gemspec configuration, loaded by the generated gemspec through the 'spec'
4
+ # variable. Kept out of regeneration with .fernignore so these values survive.
5
+ #
6
+ # Fern has no API name to work from here, so the generated symbols are rewritten to
7
+ # dexa-ai-sdk after generation. Set the published identity here.
8
+
9
+ def add_custom_gemspec_data(spec)
10
+ spec.name = "dexa-ai-sdk"
11
+ spec.authors = ["Durga Sai"]
12
+ spec.email = ["dexa-ai-sdk.20.12.24@kgpian.iitkgp.ac.in"]
13
+ spec.homepage = "https://github.com/dsainvg/decide-extract-sdk"
14
+ spec.license = "Apache-2.0"
15
+ spec.summary = "Dexa is the Ruby client for the Decide + Extract API"
16
+ spec.description = "Dexa runs decide and extract tasks against one context in a single request, from Ruby."
17
+
18
+ spec.metadata["homepage_uri"] = spec.homepage
19
+ spec.metadata["source_code_uri"] = spec.homepage
20
+ spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
21
+ spec.metadata["documentation_uri"] = "#{spec.homepage}#readme"
22
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
23
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ class Client
5
+ # @param base_url [String, nil]
6
+ # @param max_retries [Integer]
7
+ # @param timeout [Numeric]
8
+ #
9
+ # @return [void]
10
+ def initialize(base_url: nil, max_retries: 2, timeout: 60)
11
+ @raw_client = DexaAiSdk::Internal::Http::RawClient.new(
12
+ base_url: base_url || DexaAiSdk::Environment::DEFAULT,
13
+ headers: {
14
+ "X-Fern-Language" => "Ruby"
15
+ },
16
+ max_retries: max_retries,
17
+ timeout: timeout
18
+ )
19
+ end
20
+
21
+ # @return [DexaAiSdk::Tasks::Client]
22
+ def tasks
23
+ @tasks ||= DexaAiSdk::Tasks::Client.new(client: @raw_client)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ class Environment
5
+ DEFAULT = "http://localhost:8080"
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Errors
5
+ class ApiError < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Errors
5
+ class ClientError < ResponseError
6
+ end
7
+
8
+ class UnauthorizedError < ClientError
9
+ end
10
+
11
+ class ForbiddenError < ClientError
12
+ end
13
+
14
+ class NotFoundError < ClientError
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Errors
5
+ # Raised when the request fails before a response is received: the connection is refused,
6
+ # reset or closed early, the host name cannot be resolved, or the TLS handshake fails.
7
+ # The original exception is available as `cause`.
8
+ class ConnectionError < ApiError
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Errors
5
+ class RedirectError < ResponseError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Errors
5
+ class ResponseError < ApiError
6
+ attr_reader :code, :body
7
+
8
+ # @param msg [String] The raw response body.
9
+ # @param code [Integer] The HTTP status code.
10
+ # @param body [Object, nil] The response body parsed into the endpoint's declared error type, if any.
11
+ def initialize(msg, code:, body: nil)
12
+ @code = code
13
+ @body = body
14
+ super(msg)
15
+ end
16
+
17
+ def inspect
18
+ "#<#{self.class.name} @code=#{code} @body=#{message}>"
19
+ end
20
+
21
+ # Parses a raw error response body into the type declared for its status code.
22
+ #
23
+ # @param code [Integer]
24
+ # @param raw_body [String, nil]
25
+ # @param types [Hash{Integer, Range => Class}] Matchers in priority order.
26
+ # @return [Object, nil] nil when no type matches or the body cannot be parsed.
27
+ def self.load_error_body(code, raw_body, types)
28
+ type = types.find { |matcher, _| matcher.is_a?(::Range) ? matcher.cover?(code) : matcher == code }&.last
29
+ return nil if type.nil? || raw_body.to_s.empty?
30
+
31
+ begin
32
+ type.load(raw_body)
33
+ rescue StandardError
34
+ nil
35
+ end
36
+ end
37
+
38
+ # Returns the most appropriate error class for the given code.
39
+ #
40
+ # @return [Class]
41
+ def self.subclass_for_code(code)
42
+ case code
43
+ when 300..399
44
+ RedirectError
45
+ when 401
46
+ UnauthorizedError
47
+ when 403
48
+ ForbiddenError
49
+ when 404
50
+ NotFoundError
51
+ when 400..499
52
+ ClientError
53
+ when 503
54
+ ServiceUnavailableError
55
+ when 500..599
56
+ ServerError
57
+ else
58
+ ResponseError
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Errors
5
+ class ServerError < ResponseError
6
+ end
7
+
8
+ class ServiceUnavailableError < ResponseError
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Errors
5
+ class TimeoutError < ApiError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Internal
5
+ module Errors
6
+ class ConstraintError < StandardError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DexaAiSdk
4
+ module Internal
5
+ module Errors
6
+ class TypeError < StandardError
7
+ end
8
+ end
9
+ end
10
+ end