sudhanva 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -3
- data/lib/sudhanva/client.rb +44 -6
- data/lib/sudhanva/version.rb +1 -1
- metadata +33 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6efe7d85f59f7bfcb72b959ff3a183467a8803376fa3877778ce2ddd005ff33e
|
|
4
|
+
data.tar.gz: e530372b176598e5c49ad188f734d15095e3a932c414ab633f3bef1be646fa60
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 692ad73bb3d682ecc4c1a9c9c8ebe9334361f608c23ab06d488e2bd60d1c530c134121cf8fcc05839c333fee1f4aafdb482c07f058eea25ac8789e27d3b6a711
|
|
7
|
+
data.tar.gz: 6a4cafdade895142218580a49ed98324ac9d980cdc5f61a14630fee6664de2d1d599aaaec73dd9407281a1c5e3d3045e78bbf58835ebc563fa37902192121b43
|
data/README.md
CHANGED
|
@@ -9,14 +9,16 @@ The API is public and requires no credentials. Do not send private data.
|
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
12
|
+
Requires Ruby 3.3 or newer.
|
|
13
|
+
|
|
12
14
|
```bash
|
|
13
|
-
gem install sudhanva
|
|
15
|
+
gem install sudhanva --version 0.2.0
|
|
14
16
|
```
|
|
15
17
|
|
|
16
18
|
Or add it to a `Gemfile`:
|
|
17
19
|
|
|
18
20
|
```ruby
|
|
19
|
-
gem "sudhanva", "~> 0.
|
|
21
|
+
gem "sudhanva", "~> 0.2.0"
|
|
20
22
|
```
|
|
21
23
|
|
|
22
24
|
## Use
|
|
@@ -39,7 +41,9 @@ result = client.wait_for_profile_insight(job["job_id"])
|
|
|
39
41
|
```
|
|
40
42
|
|
|
41
43
|
All methods return decoded JSON hashes. Non-success responses raise `Sudhanva::APIError` with
|
|
42
|
-
`status`, `code`, and the decoded response body
|
|
44
|
+
`status`, `code`, `hint`, `docs_url`, and the decoded response body; the exception message includes
|
|
45
|
+
the API's explanation. RFC 9457 problem responses from the profile-insight endpoints map `detail`
|
|
46
|
+
(or `title`) to the message and the last segment of `type` to `code`.
|
|
43
47
|
|
|
44
48
|
## API coverage
|
|
45
49
|
|
data/lib/sudhanva/client.rb
CHANGED
|
@@ -8,14 +8,55 @@ module Sudhanva
|
|
|
8
8
|
Response = Struct.new(:status, :headers, :body, keyword_init: true)
|
|
9
9
|
|
|
10
10
|
class APIError < StandardError
|
|
11
|
-
attr_reader :status, :code, :body
|
|
11
|
+
attr_reader :status, :code, :body, :hint, :docs_url
|
|
12
12
|
|
|
13
|
-
def initialize(status:, code:, message:, body:)
|
|
13
|
+
def initialize(status:, code:, message:, body:, hint: nil, docs_url: nil)
|
|
14
14
|
super("#{status} #{code}: #{message}")
|
|
15
15
|
@status = status
|
|
16
16
|
@code = code
|
|
17
17
|
@body = body
|
|
18
|
+
@hint = hint
|
|
19
|
+
@docs_url = docs_url
|
|
18
20
|
end
|
|
21
|
+
|
|
22
|
+
# Builds an error from the standard envelope or an RFC 9457 problem.
|
|
23
|
+
def self.from_response(status, payload)
|
|
24
|
+
body = payload.is_a?(Hash) ? payload : {}
|
|
25
|
+
nested = body["error"]
|
|
26
|
+
error = nested.is_a?(Hash) ? nested : body
|
|
27
|
+
|
|
28
|
+
code = text(error["code"]) || text(body["code"])
|
|
29
|
+
message = text(error["message"]) || text(body["message"])
|
|
30
|
+
if code.nil? && message.nil?
|
|
31
|
+
title = text(body["title"])
|
|
32
|
+
code = problem_code(text(body["type"])) || title
|
|
33
|
+
message = text(body["detail"]) || title
|
|
34
|
+
end
|
|
35
|
+
message ||= nested if nested.is_a?(String) && !nested.empty?
|
|
36
|
+
|
|
37
|
+
new(
|
|
38
|
+
status: status,
|
|
39
|
+
code: code || "api_error",
|
|
40
|
+
message: message || "Request failed",
|
|
41
|
+
body: payload,
|
|
42
|
+
hint: text(error["hint"]),
|
|
43
|
+
docs_url: text(error["docs_url"])
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.text(value)
|
|
48
|
+
value if value.is_a?(String) && !value.empty?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Returns the last fragment or path segment of a problem type URI.
|
|
52
|
+
def self.problem_code(type)
|
|
53
|
+
return nil if type.nil? || type == "about:blank"
|
|
54
|
+
|
|
55
|
+
base, _, fragment = type.partition("#")
|
|
56
|
+
text(fragment) || text(base.sub(%r{/+\z}, "").split("/").last)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private_class_method :text, :problem_code
|
|
19
60
|
end
|
|
20
61
|
|
|
21
62
|
class Client
|
|
@@ -127,10 +168,7 @@ module Sudhanva
|
|
|
127
168
|
response = @transport.call(method, uri, request_headers, body, @timeout)
|
|
128
169
|
payload = response.body.to_s.empty? ? {} : JSON.parse(response.body)
|
|
129
170
|
unless response.status.between?(200, 299)
|
|
130
|
-
|
|
131
|
-
code = error.fetch("code", payload.fetch("code", "api_error"))
|
|
132
|
-
message = error.fetch("message", payload.fetch("message", "Request failed"))
|
|
133
|
-
raise APIError.new(status: response.status, code: code, message: message, body: payload)
|
|
171
|
+
raise APIError.from_response(response.status, payload)
|
|
134
172
|
end
|
|
135
173
|
|
|
136
174
|
raise APIError.new(status: response.status, code: "invalid_response", message: "API returned a non-object response", body: payload) unless payload.is_a?(Hash)
|
data/lib/sudhanva/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,42 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sudhanva
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sudhanva Narayana
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
-
dependencies:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: minitest
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '5.25'
|
|
19
|
+
type: :development
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '5.25'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rake
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '13.2'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '13.2'
|
|
13
40
|
description: A dependency-free client for published profile data, articles, search,
|
|
14
41
|
batch reads, and profile-insight jobs.
|
|
15
42
|
email:
|
|
@@ -32,7 +59,6 @@ metadata:
|
|
|
32
59
|
documentation_uri: https://sudhanva.me/developers/sdks/
|
|
33
60
|
bug_tracker_uri: https://github.com/nsudhanva/sudhanva-ruby/issues
|
|
34
61
|
rubygems_mfa_required: 'true'
|
|
35
|
-
post_install_message:
|
|
36
62
|
rdoc_options: []
|
|
37
63
|
require_paths:
|
|
38
64
|
- lib
|
|
@@ -40,15 +66,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
40
66
|
requirements:
|
|
41
67
|
- - ">="
|
|
42
68
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: '3.
|
|
69
|
+
version: '3.3'
|
|
44
70
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
71
|
requirements:
|
|
46
72
|
- - ">="
|
|
47
73
|
- !ruby/object:Gem::Version
|
|
48
74
|
version: '0'
|
|
49
75
|
requirements: []
|
|
50
|
-
rubygems_version:
|
|
51
|
-
signing_key:
|
|
76
|
+
rubygems_version: 4.0.20
|
|
52
77
|
specification_version: 4
|
|
53
78
|
summary: Minimal Ruby client for the public sudhanva.me API.
|
|
54
79
|
test_files: []
|