alma 0.2.8 → 0.3.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.
- checksums.yaml +5 -5
- data/.ruby-version +1 -1
- data/.travis.yml +10 -2
- data/Guardfile +75 -0
- data/README.md +136 -26
- data/alma.gemspec +9 -4
- data/lib/alma.rb +8 -4
- data/lib/alma/api_defaults.rb +30 -0
- data/lib/alma/availability_response.rb +1 -1
- data/lib/alma/bib.rb +4 -22
- data/lib/alma/bib_item.rb +8 -31
- data/lib/alma/bib_item_set.rb +60 -11
- data/lib/alma/bib_set.rb +7 -21
- data/lib/alma/config.rb +7 -3
- data/lib/alma/electronic.rb +167 -0
- data/lib/alma/electronic/README.md +20 -0
- data/lib/alma/electronic/batch_utils.rb +224 -0
- data/lib/alma/electronic/business.rb +29 -0
- data/lib/alma/error.rb +12 -1
- data/lib/alma/fine.rb +15 -0
- data/lib/alma/fine_set.rb +34 -23
- data/lib/alma/item_request_options.rb +22 -0
- data/lib/alma/loan.rb +18 -0
- data/lib/alma/loan_set.rb +59 -17
- data/lib/alma/renewal_response.rb +7 -3
- data/lib/alma/request.rb +165 -0
- data/lib/alma/request_options.rb +31 -18
- data/lib/alma/request_set.rb +62 -17
- data/lib/alma/response.rb +45 -0
- data/lib/alma/result_set.rb +27 -35
- data/lib/alma/user.rb +65 -57
- data/lib/alma/user_request.rb +17 -0
- data/lib/alma/user_set.rb +5 -6
- data/lib/alma/version.rb +1 -1
- data/log/.gitignore +4 -0
- metadata +75 -8
- data/lib/alma/api.rb +0 -33
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "forwardable"
|
4
|
+
|
5
|
+
module Alma
|
6
|
+
class Response
|
7
|
+
class StandardError < Alma::StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
extend ::Forwardable
|
11
|
+
|
12
|
+
attr_reader :raw_response
|
13
|
+
def_delegators :raw_response, :body, :success?, :response, :request
|
14
|
+
|
15
|
+
def initialize(response)
|
16
|
+
@raw_response = response
|
17
|
+
# We could validate and throw an error here but currently a
|
18
|
+
validate(response)
|
19
|
+
end
|
20
|
+
|
21
|
+
def loggable
|
22
|
+
{ uri: @raw_response&.request&.uri.to_s
|
23
|
+
}.select { |k, v| !(v.nil? || v.empty?) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate(response)
|
27
|
+
if errors.first&.dig("errorCode") == "401136"
|
28
|
+
message = "The requested item already exists."
|
29
|
+
log = loggable.merge(response.parsed_response)
|
30
|
+
|
31
|
+
raise Alma::BibRequest::ItemAlreadyExists.new(message, log)
|
32
|
+
end
|
33
|
+
|
34
|
+
if response.code != 200
|
35
|
+
log = loggable.merge(response.parsed_response)
|
36
|
+
raise StandardError.new("Invalid Response.", log)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns an array of errors
|
41
|
+
def errors
|
42
|
+
@raw_response.parsed_response&.dig("errorList", "error") || []
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/alma/result_set.rb
CHANGED
@@ -1,50 +1,42 @@
|
|
1
|
-
|
2
|
-
class ResultSet
|
3
|
-
extend Forwardable
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
include Alma::Error
|
3
|
+
require "forwardable"
|
7
4
|
|
8
|
-
|
5
|
+
class Alma::ResultSet
|
6
|
+
extend ::Forwardable
|
7
|
+
include Enumerable
|
8
|
+
include Alma::Error
|
9
9
|
|
10
|
-
|
11
|
-
@response = ws_response
|
12
|
-
end
|
10
|
+
attr_reader :response
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
end
|
12
|
+
def_delegators :response, :[], :fetch
|
13
|
+
def_delegators :each, :each_with_index, :size
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
def initialize(response_body_hash)
|
16
|
+
@response = response_body_hash
|
17
|
+
end
|
21
18
|
|
19
|
+
def loggable
|
20
|
+
{ uri: @response&.request&.uri&.to_s }
|
21
|
+
.select { |k, v| !(v.nil? || v.empty?) }
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def each
|
25
|
+
@results ||= @response.fetch(key, [])
|
26
|
+
.map { |item| single_record_class.new(item) }
|
27
|
+
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
def total_record_count
|
30
|
+
fetch("total_record_count", 0).to_i
|
31
|
+
end
|
32
|
+
alias :total_records :total_record_count
|
30
33
|
|
31
|
-
|
32
|
-
def
|
33
|
-
|
34
|
+
protected
|
35
|
+
def key
|
36
|
+
raise NotImplementedError "Subclasses of ResultSet need to define a response key"
|
34
37
|
end
|
35
38
|
|
36
|
-
# Subclasses Can override this to use a Custom Class for single record objects.
|
37
39
|
def single_record_class
|
38
40
|
Alma::AlmaRecord
|
39
41
|
end
|
40
|
-
|
41
|
-
def list_results
|
42
|
-
#If there is only one record in the response, HTTParty returns as a hash, not
|
43
|
-
# an array of hashes, so wrap in array to normalize.
|
44
|
-
response_array = (response_records.is_a? Array) ? response_records : [response_records]
|
45
|
-
response_array.map do |record|
|
46
|
-
single_record_class.new(record)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
42
|
end
|
data/lib/alma/user.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
module Alma
|
2
2
|
class User
|
3
|
+
class ResponseError < Alma::StandardError
|
4
|
+
end
|
3
5
|
extend Forwardable
|
6
|
+
extend Alma::ApiDefaults
|
7
|
+
|
8
|
+
def self.find(user_id, args={})
|
9
|
+
args[:expand] ||= "fees,requests,loans"
|
10
|
+
response = HTTParty.get("#{self.users_base_path}/#{user_id}", query: args, headers: headers, timeout: timeout)
|
4
11
|
|
5
|
-
|
6
|
-
response = HTTParty.get("#{self.users_base_path}/#{user_id}", headers: headers)
|
7
|
-
if response.code == 200
|
8
|
-
Alma::User.new JSON.parse(response.body)
|
9
|
-
else
|
10
|
-
raise StandardError, parse(response.body)
|
11
|
-
end
|
12
|
+
Alma::User.new response
|
12
13
|
end
|
13
14
|
|
14
15
|
# Authenticates a Alma user with their Alma Password
|
@@ -19,7 +20,7 @@ module Alma
|
|
19
20
|
def self.authenticate(args)
|
20
21
|
user_id = args.delete(:user_id) { raise ArgumentError }
|
21
22
|
args.merge!({op: 'auth'})
|
22
|
-
response = HTTParty.post("#{users_base_path}/#{user_id}", query: args, headers: headers)
|
23
|
+
response = HTTParty.post("#{users_base_path}/#{user_id}", query: args, headers: headers, timeout: timeout)
|
23
24
|
response.code == 204
|
24
25
|
end
|
25
26
|
|
@@ -27,9 +28,23 @@ module Alma
|
|
27
28
|
# The User object can respond directly to Hash like access of attributes
|
28
29
|
def_delegators :response, :[], :[]=, :has_key?, :keys, :to_json
|
29
30
|
|
30
|
-
def initialize(
|
31
|
-
@
|
32
|
-
@
|
31
|
+
def initialize(response)
|
32
|
+
@raw_response = response
|
33
|
+
@response = response.parsed_response
|
34
|
+
validate(response)
|
35
|
+
end
|
36
|
+
|
37
|
+
def loggable
|
38
|
+
{ uri: @raw_response&.request&.uri.to_s
|
39
|
+
}.select { |k, v| !(v.nil? || v.empty?) }
|
40
|
+
end
|
41
|
+
|
42
|
+
def validate(response)
|
43
|
+
if response.code != 200
|
44
|
+
log = loggable.merge(response.parsed_response)
|
45
|
+
error = "The user was not found."
|
46
|
+
raise ResponseError.new(error, log)
|
47
|
+
end
|
33
48
|
end
|
34
49
|
|
35
50
|
def response
|
@@ -40,6 +55,18 @@ module Alma
|
|
40
55
|
self['primary_id']
|
41
56
|
end
|
42
57
|
|
58
|
+
def total_fines
|
59
|
+
response.dig('fees','value') || "0"
|
60
|
+
end
|
61
|
+
|
62
|
+
def total_requests
|
63
|
+
response.dig('requests','value') || "0"
|
64
|
+
end
|
65
|
+
|
66
|
+
def total_loans
|
67
|
+
response.dig('loans','value') || "0"
|
68
|
+
end
|
69
|
+
|
43
70
|
|
44
71
|
# Access the top level JSON attributes as object methods
|
45
72
|
def method_missing(name)
|
@@ -54,35 +81,22 @@ module Alma
|
|
54
81
|
|
55
82
|
# Persist the user in it's current state back to Alma
|
56
83
|
def save!
|
57
|
-
response = HTTParty.put("#{users_base_path}/#{id}", headers: headers, body: to_json)
|
84
|
+
response = HTTParty.put("#{users_base_path}/#{id}", timeout: timeout, headers: headers, body: to_json)
|
58
85
|
get_body_from(response)
|
59
86
|
end
|
60
87
|
|
61
88
|
|
62
89
|
def fines
|
63
|
-
|
64
|
-
if response.code == 200
|
65
|
-
Alma::FineSet.new get_body_from(response)
|
66
|
-
else
|
67
|
-
raise StandardError, get_body_from(response)
|
68
|
-
end
|
90
|
+
Alma::Fine.where_user(id)
|
69
91
|
end
|
70
92
|
|
71
93
|
def requests
|
72
|
-
|
73
|
-
#TODO Handle Pagination
|
74
|
-
#TODO Handle looping through all results
|
75
|
-
response = HTTParty.get("#{users_base_path}/#{id}/requests", headers: headers)
|
76
|
-
Alma::RequestSet.new(get_body_from(response))
|
94
|
+
Alma::UserRequest.where_user(id)
|
77
95
|
end
|
78
96
|
|
79
97
|
|
80
98
|
def loans(args={})
|
81
|
-
|
82
|
-
@loans = send_loans_request(args)
|
83
|
-
@recheck_loans = false
|
84
|
-
end
|
85
|
-
@loans
|
99
|
+
@loans ||= Alma::Loan.where_user(id, args)
|
86
100
|
end
|
87
101
|
|
88
102
|
def renew_loan(loan_id)
|
@@ -97,38 +111,45 @@ module Alma
|
|
97
111
|
loan_ids.map { |id| renew_loan(id) }
|
98
112
|
end
|
99
113
|
|
100
|
-
|
101
114
|
def renew_all_loans
|
102
115
|
renew_multiple_loans(loans.map(&:loan_id))
|
103
116
|
end
|
104
117
|
|
105
|
-
|
106
|
-
def recheck_loans?
|
107
|
-
@recheck_loans
|
108
|
-
end
|
109
|
-
|
110
|
-
|
111
118
|
def preferred_email
|
112
119
|
self["contact_info"]["email"].select { |k, v| k["preferred"] }.first["email_address"]
|
113
120
|
end
|
114
121
|
|
115
|
-
|
116
122
|
def email
|
117
123
|
self["contact_info"]["email"].map { |e| e["email_address"] }
|
118
124
|
end
|
119
125
|
|
126
|
+
def preferred_first_name
|
127
|
+
pref_first = self["pref_first_name"] unless self["pref_first_name"] == ""
|
128
|
+
pref_first || self["first_name"] || ""
|
129
|
+
end
|
120
130
|
|
121
|
-
|
131
|
+
def preferred_middle_name
|
132
|
+
pref_middle = self["pref_middle_name"] unless self["pref_middle_name"] == ""
|
133
|
+
pref_middle || self["middle_name"] || ""
|
134
|
+
end
|
122
135
|
|
123
|
-
def
|
124
|
-
|
136
|
+
def preferred_last_name
|
137
|
+
pref_last = self["pref_last_name"] unless self["pref_last_name"] == ""
|
138
|
+
pref_last || self["last_name"]
|
139
|
+
end
|
140
|
+
|
141
|
+
def preferred_suffix
|
142
|
+
self["pref_name_suffix"] || ""
|
143
|
+
end
|
125
144
|
|
126
|
-
|
127
|
-
|
128
|
-
response = HTTParty.get("#{users_base_path}/#{id}/loans", query: args, headers: headers)
|
129
|
-
Alma::LoanSet.new(get_body_from(response))
|
145
|
+
def preferred_name
|
146
|
+
"#{preferred_first_name} #{preferred_middle_name} #{preferred_last_name} #{preferred_suffix}"
|
130
147
|
end
|
131
148
|
|
149
|
+
|
150
|
+
|
151
|
+
private
|
152
|
+
|
132
153
|
# Attempts to renew a single item for a user
|
133
154
|
# @param [Hash] args
|
134
155
|
# @option args [String] :user_id The unique id of the user
|
@@ -140,7 +161,7 @@ module Alma
|
|
140
161
|
user_id = args.delete(:user_id) { raise ArgumentError }
|
141
162
|
params = {op: 'renew'}
|
142
163
|
response = HTTParty.post("#{users_base_path}/#{user_id}/loans/#{loan_id}", query: params, headers: headers)
|
143
|
-
RenewalResponse.new(
|
164
|
+
RenewalResponse.new(response)
|
144
165
|
end
|
145
166
|
|
146
167
|
# Attempts to renew multiple items for a user
|
@@ -167,21 +188,8 @@ module Alma
|
|
167
188
|
self.class.users_base_path
|
168
189
|
end
|
169
190
|
|
170
|
-
def self.headers
|
171
|
-
{ "Authorization": "apikey #{self.apikey}",
|
172
|
-
"Accept": "application/json",
|
173
|
-
"Content-Type": "application/json" }
|
174
|
-
end
|
175
|
-
|
176
|
-
|
177
191
|
def headers
|
178
192
|
self.class.headers
|
179
193
|
end
|
180
|
-
|
181
|
-
|
182
|
-
def self.apikey
|
183
|
-
Alma.configuration.apikey
|
184
|
-
end
|
185
|
-
|
186
194
|
end
|
187
195
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Alma
|
2
|
+
class UserRequest < AlmaRecord
|
3
|
+
extend Alma::ApiDefaults
|
4
|
+
|
5
|
+
def self.where_user(user_id, args={})
|
6
|
+
# Default to upper limit
|
7
|
+
args[:limit] ||= 100
|
8
|
+
response = HTTParty.get(
|
9
|
+
"#{users_base_path}/#{user_id}/requests",
|
10
|
+
query: args,
|
11
|
+
headers: headers,
|
12
|
+
timeout: timeout
|
13
|
+
)
|
14
|
+
Alma::RequestSet.new(response)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/alma/user_set.rb
CHANGED
@@ -1,18 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Alma
|
2
4
|
class UserSet
|
3
|
-
|
4
5
|
def top_level_key
|
5
|
-
|
6
|
-
|
6
|
+
"users"
|
7
7
|
end
|
8
8
|
|
9
9
|
def response_records_key
|
10
|
-
|
10
|
+
"user"
|
11
11
|
end
|
12
12
|
|
13
13
|
def single_record_class
|
14
14
|
Alma::User
|
15
15
|
end
|
16
|
-
|
17
16
|
end
|
18
|
-
end
|
17
|
+
end
|
data/lib/alma/version.rb
CHANGED
data/log/.gitignore
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chad Nelson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ezwadl
|
@@ -52,34 +52,48 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
75
|
+
version: '2.0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
82
|
+
version: '2.0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rake
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
89
|
+
version: '13.0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
96
|
+
version: '13.0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: rspec
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,6 +136,48 @@ dependencies:
|
|
122
136
|
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: byebug
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: guard
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: guard-rspec
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
125
181
|
description: Client for Ex Libris Alma Web Services
|
126
182
|
email:
|
127
183
|
- chad.nelson@temple.edu
|
@@ -136,6 +192,7 @@ files:
|
|
136
192
|
- ".travis.yml"
|
137
193
|
- CODE_OF_CONDUCT.md
|
138
194
|
- Gemfile
|
195
|
+
- Guardfile
|
139
196
|
- LICENSE.txt
|
140
197
|
- README.md
|
141
198
|
- Rakefile
|
@@ -144,26 +201,36 @@ files:
|
|
144
201
|
- bin/setup
|
145
202
|
- lib/alma.rb
|
146
203
|
- lib/alma/alma_record.rb
|
147
|
-
- lib/alma/
|
204
|
+
- lib/alma/api_defaults.rb
|
148
205
|
- lib/alma/availability_response.rb
|
149
206
|
- lib/alma/bib.rb
|
150
207
|
- lib/alma/bib_item.rb
|
151
208
|
- lib/alma/bib_item_set.rb
|
152
209
|
- lib/alma/bib_set.rb
|
153
210
|
- lib/alma/config.rb
|
211
|
+
- lib/alma/electronic.rb
|
212
|
+
- lib/alma/electronic/README.md
|
213
|
+
- lib/alma/electronic/batch_utils.rb
|
214
|
+
- lib/alma/electronic/business.rb
|
154
215
|
- lib/alma/error.rb
|
216
|
+
- lib/alma/fine.rb
|
155
217
|
- lib/alma/fine_set.rb
|
218
|
+
- lib/alma/item_request_options.rb
|
156
219
|
- lib/alma/loan.rb
|
157
220
|
- lib/alma/loan_set.rb
|
158
221
|
- lib/alma/renewal_response.rb
|
222
|
+
- lib/alma/request.rb
|
159
223
|
- lib/alma/request_options.rb
|
160
224
|
- lib/alma/request_set.rb
|
225
|
+
- lib/alma/response.rb
|
161
226
|
- lib/alma/result_set.rb
|
162
227
|
- lib/alma/user.rb
|
228
|
+
- lib/alma/user_request.rb
|
163
229
|
- lib/alma/user_set.rb
|
164
230
|
- lib/alma/version.rb
|
165
231
|
- lib/alma/wadl/bib.wadl
|
166
232
|
- lib/alma/wadl/user.wadl
|
233
|
+
- log/.gitignore
|
167
234
|
homepage: https://github.com/tulibraries/alma_rb
|
168
235
|
licenses:
|
169
236
|
- MIT
|
@@ -184,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
251
|
version: '0'
|
185
252
|
requirements: []
|
186
253
|
rubyforge_project:
|
187
|
-
rubygems_version: 2.
|
254
|
+
rubygems_version: 2.7.7
|
188
255
|
signing_key:
|
189
256
|
specification_version: 4
|
190
257
|
summary: Client for Ex Libris Alma Web Services
|