nypl_sierra_api_client 1.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.
- checksums.yaml +7 -0
- data/lib/errors.rb +13 -0
- data/lib/sierra_api_client.rb +139 -0
- data/lib/sierra_api_response.rb +34 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8936adc2234429844a356e11687cb660933b0ad20f22acac447a09f9595af0d0
|
4
|
+
data.tar.gz: e14ab0690f2d3b8b9a340a1248a4746a9c9c418298c8028e9be096d380a204c5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a50a652ee9278599ca077c5fa3a197128163e0f91eb8d2bd57db3152a31bdea413004541abf49d060eb907fae2a3fd8edf0dfcf0fd0d60b893b1beb69a4600df
|
7
|
+
data.tar.gz: 7dd271f819f77d1f58cdb4aa0b12c61921cb41ec7cf29eeaf6d637444e251328a89136479f7a9f888f9d92b5758de77c8e63517db78db86671ce67371301edd1
|
data/lib/errors.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'uri'
|
4
|
+
require 'nypl_log_formatter'
|
5
|
+
|
6
|
+
require_relative 'errors'
|
7
|
+
require_relative 'sierra_api_response'
|
8
|
+
|
9
|
+
class SierraApiClient
|
10
|
+
def initialize(config = {})
|
11
|
+
@config = {
|
12
|
+
base_url: ENV['SIERRA_API_BASE_URL'],
|
13
|
+
client_id: ENV['SIERRA_OAUTH_ID'],
|
14
|
+
client_secret: ENV['SIERRA_OAUTH_SECRET'],
|
15
|
+
oauth_url: ENV['SIERRA_OAUTH_URL'],
|
16
|
+
log_level: 'info'
|
17
|
+
}.merge config
|
18
|
+
|
19
|
+
raise SierraApiClientError.new 'Missing config: neither config.base_url nor ENV.SIERRA_API_BASE_URL are set' unless @config[:base_url]
|
20
|
+
raise SierraApiClientError.new 'Missing config: neither config.client_id nor ENV.SIERRA_OAUTH_ID are set' unless @config[:client_id]
|
21
|
+
raise SierraApiClientError.new 'Missing config: neither config.client_secret nor ENV.SIERRA_OAUTH_SECRET are set ' unless @config[:client_secret]
|
22
|
+
raise SierraApiClientError.new 'Missing config: neither config.oauth_url nor ENV.SIERRA_OAUTH_URL are set ' unless @config[:oauth_url]
|
23
|
+
end
|
24
|
+
|
25
|
+
def get (path, options = {})
|
26
|
+
options = parse_http_options options
|
27
|
+
|
28
|
+
do_request 'get', path, options
|
29
|
+
end
|
30
|
+
|
31
|
+
def post (path, body, options = {})
|
32
|
+
options = parse_http_options options
|
33
|
+
|
34
|
+
# Default to POSTing JSON unless explicitly stated otherwise
|
35
|
+
options[:headers]['Content-Type'] = 'application/json' unless options[:headers]['Content-Type']
|
36
|
+
|
37
|
+
do_request 'post', path, options do |request|
|
38
|
+
request.body = body
|
39
|
+
request.body = request.body.to_json unless options[:headers]['Content-Type'] != 'application/json'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def do_request (method, path, options = {})
|
46
|
+
# For now, these are the methods we support:
|
47
|
+
raise SierraApiClientError, "Unsupported method: #{method}" unless ['get', 'post'].include? method.downcase
|
48
|
+
|
49
|
+
authenticate! if options[:authenticated]
|
50
|
+
|
51
|
+
uri = URI.parse("#{@config[:base_url]}#{path}")
|
52
|
+
|
53
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
54
|
+
http.use_ssl = uri.scheme === 'https'
|
55
|
+
|
56
|
+
# Build request headers:
|
57
|
+
request_headers = {}
|
58
|
+
request_headers['Content-Type'] = options[:headers]['Content-Type'] unless options.dig(:headers, 'Content-Type').nil?
|
59
|
+
|
60
|
+
# Create HTTP::Get or HTTP::Post
|
61
|
+
request = Net::HTTP.const_get(method.capitalize).new(uri.path, request_headers)
|
62
|
+
|
63
|
+
# Add bearer token header
|
64
|
+
request['Authorization'] = "Bearer #{@access_token}" if options[:authenticated]
|
65
|
+
|
66
|
+
# Allow caller to modify the request before we send it off:
|
67
|
+
yield request if block_given?
|
68
|
+
|
69
|
+
logger.debug "SierraApiClient: #{method} to Sierra api", { uri: uri, body: request.body }
|
70
|
+
|
71
|
+
begin
|
72
|
+
# Execute request:
|
73
|
+
response = http.request(request)
|
74
|
+
rescue => e
|
75
|
+
raise SierraApiClientError.new(e), "Failed to #{method} to #{path}: #{e.message}"
|
76
|
+
end
|
77
|
+
|
78
|
+
logger.debug "SierraApiClient: Got Sierra api response", { code: response.code, body: response.body }
|
79
|
+
|
80
|
+
parse_response response
|
81
|
+
end
|
82
|
+
|
83
|
+
def parse_response (response)
|
84
|
+
if response.code == "401"
|
85
|
+
# Likely an expired access-token; Wipe it for next run
|
86
|
+
# TODO: Implement token refresh
|
87
|
+
@access_token = nil
|
88
|
+
raise SierraApiClientTokenError.new("Got a 401: #{response.body}")
|
89
|
+
end
|
90
|
+
|
91
|
+
SierraApiResponse.new(response)
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse_http_options (_options)
|
95
|
+
options = {
|
96
|
+
authenticated: true
|
97
|
+
}.merge _options
|
98
|
+
|
99
|
+
options[:headers] = {
|
100
|
+
}.merge(_options[:headers] || {})
|
101
|
+
.transform_keys(&:to_s)
|
102
|
+
|
103
|
+
options
|
104
|
+
end
|
105
|
+
|
106
|
+
# Authorizes the request.
|
107
|
+
def authenticate!
|
108
|
+
# NOOP if we've already authenticated
|
109
|
+
return nil if ! @access_token.nil?
|
110
|
+
|
111
|
+
logger.debug "SierraApiClient: Authenticating with client_id #{@config[:client_id]}"
|
112
|
+
|
113
|
+
uri = URI.parse("#{@config[:oauth_url]}")
|
114
|
+
request = Net::HTTP::Post.new(uri)
|
115
|
+
request.basic_auth(@config[:client_id], @config[:client_secret])
|
116
|
+
request.set_form_data(
|
117
|
+
"grant_type" => "client_credentials"
|
118
|
+
)
|
119
|
+
|
120
|
+
req_options = {
|
121
|
+
use_ssl: uri.scheme == "https",
|
122
|
+
request_timeout: 500
|
123
|
+
}
|
124
|
+
|
125
|
+
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
|
126
|
+
http.request(request)
|
127
|
+
end
|
128
|
+
|
129
|
+
if response.code == '200'
|
130
|
+
@access_token = JSON.parse(response.body)["access_token"]
|
131
|
+
else
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def logger
|
137
|
+
@logger ||= NyplLogFormatter.new(STDOUT, level: @config[:log_level])
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class SierraApiResponse
|
2
|
+
attr_accessor :response
|
3
|
+
|
4
|
+
def initialize(response)
|
5
|
+
@response = response
|
6
|
+
end
|
7
|
+
|
8
|
+
def code
|
9
|
+
@response.code.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def error?
|
13
|
+
code >= 400
|
14
|
+
end
|
15
|
+
|
16
|
+
def success?
|
17
|
+
(200...300).include? code
|
18
|
+
end
|
19
|
+
|
20
|
+
def body
|
21
|
+
return @response.body if @response.code == '204'
|
22
|
+
|
23
|
+
# If response Content-Type indicates body is json
|
24
|
+
if /^application\/json/ =~ @response['Content-Type']
|
25
|
+
begin
|
26
|
+
JSON.parse(@response.body)
|
27
|
+
rescue => e
|
28
|
+
raise SierraApiResponseError.new(response), "Error parsing response (#{response.code}): #{response.body}"
|
29
|
+
end
|
30
|
+
else
|
31
|
+
@response.body
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nypl_sierra_api_client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- nonword
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-04-21 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Client for querying Sierra API
|
14
|
+
email: paulbeaudoin@nypl.org
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/errors.rb
|
20
|
+
- lib/sierra_api_client.rb
|
21
|
+
- lib/sierra_api_response.rb
|
22
|
+
homepage: https://github.com/NYPL/ruby-sierra-api-client
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubygems_version: 3.0.8
|
42
|
+
signing_key:
|
43
|
+
specification_version: 4
|
44
|
+
summary: NYPL Sierra API client
|
45
|
+
test_files: []
|