folio_client 0.9.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f400cbad25cc1f7a7a4af985a510c597af5dea7b18cf636d5e6cb8196b4ef059
4
- data.tar.gz: 26d9485bebd8780fafe498b15827575703316c229ed8c35e361aee3246ee70fd
3
+ metadata.gz: 49b7e49d6350ec5da1e3d1b86df567520dbe89c9eed80fb42b8c158c79c3f426
4
+ data.tar.gz: f957345b73f2071fee40ffbe6f6e4f8082468f383bc7848ff9953ac017917c4b
5
5
  SHA512:
6
- metadata.gz: 472ca9f6c928aa3353b8f928cce63030329e62a7c26655700aaaef6c835e777f58d0771c8b58d8bfd50ee59a7c2c1724063246884ab529556b7cd92ee2065dfd
7
- data.tar.gz: 2add95c0f3492db0c80f1770c40576d7bbac019a31674a9b0124a47706b065e1b02e67735519dddc2cf4f832216d453ddb3126906a4c89f4d4eac1f59c70fd6d
6
+ metadata.gz: c775d4984eab9d5a89d310da0983dbde38824af07498ed4504cb9b9d0614c4a12c3328dde4c59d96aede407672529d39ebabeb227fe01a6b0380de716704f109
7
+ data.tar.gz: bc70a108d1a3d70131db2eed2e20343f5c0462c00a2dab65a1484456dfe7e2e19b4b6d616e628531cf664348c9bf85fc88eda94874cdbc859ae614e2a21bbde6
@@ -0,0 +1,19 @@
1
+ #!/bin/bash --login
2
+
3
+ # This script is called by our weekly dependency update job in Jenkins after updating Ruby and other deps
4
+
5
+ # Switch to Ruby 3.1 for FolioClient (3.0 is default in Jenkinsfile)
6
+ rvm use 3.1.2@folio_client --create &&
7
+ gem install bundler &&
8
+ bundle install --gemfile Gemfile
9
+
10
+ standardrb --fix > folio_client_standard.txt
11
+
12
+ retVal=$?
13
+
14
+ git commit -am "Update to latest standard style guide"
15
+
16
+ if [ $retVal -ne 0 ]; then
17
+ echo "ERROR UPDATING RUBY TO STANDARD STYLE (folio_client)"
18
+ cat folio_client_standard.txt
19
+ fi
data/.rubocop/custom.yml CHANGED
@@ -11,6 +11,8 @@ RSpec/MultipleMemoizedHelpers:
11
11
  Enabled: false
12
12
  RSpec/MultipleExpectations:
13
13
  Max: 3
14
+ RSpec/ExampleLength:
15
+ Max: 15
14
16
 
15
17
  RSpec/BeEq: # new in 2.9.0
16
18
  Enabled: true
@@ -60,3 +62,9 @@ RSpec/FactoryBot/FactoryNameStyle: # new in 2.16
60
62
  Enabled: true
61
63
  RSpec/Rails/MinitestAssertions: # new in 2.17
62
64
  Enabled: true
65
+ RSpec/RedundantAround: # new in 2.19
66
+ Enabled: true
67
+ RSpec/SkipBlockInsideExample: # new in 2.19
68
+ Enabled: true
69
+ RSpec/Rails/TravelAround: # new in 2.19
70
+ Enabled: true
data/.rubocop.yml CHANGED
@@ -12,4 +12,3 @@ inherit_gem:
12
12
 
13
13
  inherit_from:
14
14
  - .rubocop/custom.yml
15
- - .rubocop_todo.yml
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- folio_client (0.9.0)
4
+ folio_client (0.10.1)
5
5
  activesupport (>= 4.2, < 8)
6
6
  dry-monads
7
7
  faraday
@@ -77,7 +77,7 @@ GEM
77
77
  rubocop-ast (>= 1.26.0, < 2.0)
78
78
  ruby-progressbar (~> 1.7)
79
79
  unicode-display_width (>= 2.4.0, < 3.0)
80
- rubocop-ast (1.27.0)
80
+ rubocop-ast (1.28.0)
81
81
  parser (>= 3.2.1.0)
82
82
  rubocop-capybara (2.17.1)
83
83
  rubocop (~> 1.41)
@@ -96,10 +96,10 @@ GEM
96
96
  simplecov_json_formatter (~> 0.1)
97
97
  simplecov-html (0.12.3)
98
98
  simplecov_json_formatter (0.1.4)
99
- standard (1.25.2)
99
+ standard (1.25.3)
100
100
  language_server-protocol (~> 3.17.0.2)
101
- rubocop (= 1.48.1)
102
- rubocop-performance (= 1.16.0)
101
+ rubocop (~> 1.48.1)
102
+ rubocop-performance (~> 1.16.0)
103
103
  tzinfo (2.0.6)
104
104
  concurrent-ruby (~> 1.0)
105
105
  unf (0.1.4)
@@ -116,6 +116,7 @@ PLATFORMS
116
116
  x86_64-darwin-19
117
117
  x86_64-darwin-20
118
118
  x86_64-darwin-21
119
+ x86_64-darwin-22
119
120
  x86_64-linux
120
121
 
121
122
  DEPENDENCIES
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  # FolioClient
7
7
 
8
- FolioClient is a Ruby gem that acts as a client to the RESTful HTTP APIs provided by the Folio ILS API. It requires ruby 3.0 or better.
8
+ FolioClient is a Ruby gem that acts as a client to the RESTful HTTP APIs provided by the Folio ILS API. It requires ruby 3.0 or better.
9
9
 
10
10
  ## Installation
11
11
 
@@ -48,7 +48,7 @@ client = FolioClient.configure(
48
48
  )
49
49
  ```
50
50
 
51
- The client is smart enough to automatically request a new token if it detects the one it is using has expired. If for some reason, you want to immediately request a new token, you can do this:
51
+ The client is smart enough to automatically request a new token if it detects the one it is using has expired. If for some reason, you want to immediately request a new token, you can do this:
52
52
 
53
53
  ```ruby
54
54
  client.config.token = FolioClient::Authenticator.token(client.config.login_params, client.connection)
@@ -56,7 +56,7 @@ client.config.token = FolioClient::Authenticator.token(client.config.login_param
56
56
 
57
57
  ## API Coverage
58
58
 
59
- FolioClient provides a number of methods to simplify connecting to the RESTful HTTP API of the Folio API. In this section we list all of the available methods, reflecting how much of the API the client covers. Note that this assumes the client has already been configured, as described above. See dor-services-app for an example of configuration and usage.
59
+ FolioClient provides a number of methods to simplify connecting to the RESTful HTTP API of the Folio API. In this section we list all of the available methods, reflecting how much of the API the client covers. Note that this assumes the client has already been configured, as described above. See dor-services-app for an example of configuration and usage.
60
60
 
61
61
  ```ruby
62
62
  # Lookup an instance hrid given a barcode
@@ -81,16 +81,48 @@ data_importer.wait_until_complete
81
81
  data_importer.instance_hrid
82
82
  => Success("in00000000010")
83
83
 
84
- # Create a Holdings record
85
- holdings_client = client.holdings(instance_id: "99a6d818-d523-42f3-9844-81cf3187dbad")
86
- holdings_client.create(permanent_location_id: "1b14e21c-8d47-45c7-bc49-456a0086422b", holdings_type_id: "996f93e2-5b5e-4cf2-9168-33ced1f95eed")
87
- => {
88
- "id" => "581f6289-001f-49d1-bab7-035f4d878cbd",
89
- "_version" => 1,
90
- "hrid" => "ho00000000065",
91
- "holdingsTypeId" => "996f93e2-5b5e-4cf2-9168-33ced1f95eed"
92
- ...
93
- }
84
+ # Get list of organizations (filtered with an optional query)
85
+ # see https://s3.amazonaws.com/foliodocs/api/mod-organizations/p/organizations.html#organizations_organizations_get
86
+ client.organizations
87
+ => {"organizations"=>[
88
+ {"id"=>"4b1a42f9-b310-492c-a71d-b8edcd30ac0c",
89
+ "name"=>"Seventh Art Releasing",
90
+ "code"=>"7ART-SUL",
91
+ "exportToAccounting"=>true,
92
+ "status"=>"Active",
93
+ "organizationTypes"=>[],
94
+ "aliases"=>[],
95
+ "addresses"=>],.....
96
+ "totalRecords"=>100}
97
+
98
+ client.organizations(query: 'name="Seventh"')
99
+ => {"organizations"=>[....
100
+
101
+ # Get list of organization interface items (filtered with an optional query)
102
+ # see https://s3.amazonaws.com/foliodocs/api/mod-organizations-storage/p/interface.html#organizations_storage_interfaces_get
103
+ client.organization_interfaces
104
+ => {"interfaces"=>
105
+ [{"id"=>"c6f7470e-6229-45ce-b3f9-32006e9affcf",
106
+ "name"=>"tes",
107
+ "type"=>["Invoices"],
108
+ .....],....
109
+ "totalRecords"=>100}
110
+
111
+ client.organization_interfaces(query: 'name="tes"')
112
+ => {"interfaces"=>....
113
+
114
+ # Get details for a specific organization interface
115
+ # see https://s3.amazonaws.com/foliodocs/api/mod-organizations-storage/p/interface.html#organizations_storage_interfaces__id__get
116
+ client.interface_details(id: 'c6f7470e-6229-45ce-b3f9-32006e9affcf')
117
+ =>
118
+ {"id"=>"c6f7470e-6229-45ce-b3f9-32006e9affcf",
119
+ "name"=>"tes",
120
+ "type"=>["Invoices"],
121
+ "metadata"=>
122
+ {"createdDate"=>"2023-02-16T22:27:51.515+00:00",
123
+ "createdByUserId"=>"38524916-598d-4edf-a2ef-04bba7e78ad6",
124
+ "updatedDate"=>"2023-02-16T22:27:51.515+00:00",
125
+ "updatedByUserId"=>"38524916-598d-4edf-a2ef-04bba7e78ad6"}}
94
126
  ```
95
127
 
96
128
  ## Development
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FolioClient
4
+ # Query organization records in Folio; see
5
+ # https://s3.amazonaws.com/foliodocs/api/mod-organizations/p/organizations.html
6
+ # https://s3.amazonaws.com/foliodocs/api/mod-organizations-storage/p/interface.html
7
+ class Organizations
8
+ attr_accessor :client
9
+
10
+ # @param client [FolioClient] the configured client
11
+ def initialize(client)
12
+ @client = client
13
+ end
14
+
15
+ # @param query [String] an optional query to limit the number of organizations returned
16
+ # @param limit [Integer] the number of results to return (defaults to 10,000)
17
+ # @param offset [Integer] the offset for results returned (defaults to 0)
18
+ # @param lang [String] language code for returned results (defaults to 'en')
19
+ def fetch_list(query: nil, limit: 10000, offset: 0, lang: "en")
20
+ params = {limit: limit, offset: offset, lang: lang}
21
+ params[:query] = query if query
22
+ client.get("/organizations/organizations", params)
23
+ end
24
+
25
+ # @param query [String] an optional query to limit the number of organization interfaces returned
26
+ # @param limit [Integer] the number of results to return (defaults to 10,000)
27
+ # @param offset [Integer] the offset for results returned (defaults to 0)
28
+ # @param lang [String] language code for returned results (defaults to 'en')
29
+ def fetch_interface_list(query: nil, limit: 10000, offset: 0, lang: "en")
30
+ params = {limit: limit, offset: offset, lang: lang}
31
+ params[:query] = query if query
32
+ client.get("/organizations-storage/interfaces", params)
33
+ end
34
+
35
+ # @param id [String] id for requested storage interface
36
+ # @param lang [String] language code for returned result (defaults to 'en')
37
+ def fetch_interface_details(id:, lang: "en")
38
+ client.get("/organizations-storage/interfaces/#{id}", {
39
+ lang: lang
40
+ })
41
+ end
42
+ end
43
+ end
@@ -13,7 +13,8 @@ class FolioClient
13
13
  # get marc bib data from folio given an instance HRID
14
14
  # @param instance_hrid [String] the key to use for MARC lookup
15
15
  # @return [Hash] hash representation of the MARC. should be usable by MARC::Record.new_from_hash (from ruby-marc gem)
16
- # @raises NotFound, MultipleRecordsForIdentifier
16
+ # @raise [ResourceNotFound]
17
+ # @raise [MultipleResourcesFound]
17
18
  def fetch_marc_hash(instance_hrid:)
18
19
  response_hash = client.get("/source-storage/source-records", {instanceHrid: instance_hrid})
19
20
 
@@ -12,10 +12,12 @@ class FolioClient
12
12
  raise ForbiddenError, "The operation requires privileges which the client does not have: #{response.body}"
13
13
  when 404
14
14
  raise ResourceNotFound, "Endpoint not found or resource does not exist: #{response.body}"
15
+ when 409
16
+ raise ConflictError, "Resource cannot be updated: #{response.body}"
15
17
  when 422
16
- raise ValidationError, "There was a validation problem with the request: #{response.body} "
18
+ raise ValidationError, "There was a validation problem with the request: #{response.body}"
17
19
  when 500
18
- raise ServiceUnavailable, "The remote server returned an internal server error."
20
+ raise ServiceUnavailable, "The remote server returned an internal server error: #{response.body}"
19
21
  else
20
22
  raise StandardError, "Unexpected response: #{response.status} #{response.body}"
21
23
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class FolioClient
4
- VERSION = "0.9.0"
4
+ VERSION = "0.10.1"
5
5
  end
data/lib/folio_client.rb CHANGED
@@ -35,6 +35,9 @@ class FolioClient
35
35
  # Error raised when the Folio API returns a 422 Unprocessable Entity
36
36
  class ValidationError < Error; end
37
37
 
38
+ # Error raised when the Folio API returns a 409 Conflict
39
+ class ConflictError < Error; end
40
+
38
41
  DEFAULT_HEADERS = {
39
42
  accept: "application/json, text/plain",
40
43
  content_type: "application/json"
@@ -44,23 +47,24 @@ class FolioClient
44
47
  # @param url [String] the folio API URL
45
48
  # @param login_params [Hash] the folio client login params (username:, password:)
46
49
  # @param okapi_headers [Hash] the okapi specific headers to add (X-Okapi-Tenant:, User-Agent:)
47
- def configure(url:, login_params:, okapi_headers:)
48
- instance.config = OpenStruct.new(url: url, login_params: login_params, okapi_headers: okapi_headers, token: nil)
50
+ def configure(url:, login_params:, okapi_headers:, timeout: default_timeout)
51
+ instance.config = OpenStruct.new(url: url, login_params: login_params, okapi_headers: okapi_headers, token: nil, timeout: timeout)
49
52
 
50
53
  instance.config.token = Authenticator.token(login_params, connection)
51
54
 
52
55
  self
53
56
  end
54
57
 
55
- delegate :config, :connection, :get, :post, :put, to: :instance
56
- delegate :fetch_hrid, :fetch_external_id, :fetch_instance_info, :fetch_marc_hash, :has_instance_status?, :data_import, :holdings, :edit_marc_json, to: :instance
58
+ delegate :config, :connection, :get, :post, :put, :default_timeout, to: :instance
59
+ delegate :fetch_hrid, :fetch_external_id, :fetch_instance_info, :fetch_marc_hash, :has_instance_status?, :data_import, :edit_marc_json,
60
+ :organizations, :organization_interfaces, :interface_details, to: :instance
57
61
  end
58
62
 
59
63
  attr_accessor :config
60
64
 
61
65
  # Send an authenticated get request
62
66
  # @param path [String] the path to the Folio API request
63
- # @param request [Hash] params to get to the API
67
+ # @param params [Hash] params to get to the API
64
68
  def get(path, params = {})
65
69
  response = TokenWrapper.refresh(config, connection) do
66
70
  connection.get(path, params, {"x-okapi-token": config.token})
@@ -119,55 +123,81 @@ class FolioClient
119
123
  def connection
120
124
  @connection ||= Faraday.new(
121
125
  url: config.url,
122
- headers: DEFAULT_HEADERS.merge(config.okapi_headers || {})
126
+ headers: DEFAULT_HEADERS.merge(config.okapi_headers || {}),
127
+ request: {timeout: config.timeout}
123
128
  )
124
129
  end
125
130
 
126
131
  # Public methods available on the FolioClient below
132
+
133
+ # @see Inventory#fetch_hrid
127
134
  def fetch_hrid(...)
128
135
  Inventory
129
136
  .new(self)
130
137
  .fetch_hrid(...)
131
138
  end
132
139
 
140
+ # @see Inventory#fetch_external_id
133
141
  def fetch_external_id(...)
134
142
  Inventory
135
143
  .new(self)
136
144
  .fetch_external_id(...)
137
145
  end
138
146
 
147
+ # @see Inventory#fetch_instance_info
139
148
  def fetch_instance_info(...)
140
149
  Inventory
141
150
  .new(self)
142
151
  .fetch_instance_info(...)
143
152
  end
144
153
 
154
+ # @see SourceStorage#fetch_marc_hash
145
155
  def fetch_marc_hash(...)
146
156
  SourceStorage
147
157
  .new(self)
148
158
  .fetch_marc_hash(...)
149
159
  end
150
160
 
161
+ # @see Inventory#has_instance_status?
151
162
  def has_instance_status?(...)
152
163
  Inventory
153
164
  .new(self)
154
165
  .has_instance_status?(...)
155
166
  end
156
167
 
168
+ # @ see DataImport#import
157
169
  def data_import(...)
158
170
  DataImport
159
171
  .new(self)
160
172
  .import(...)
161
173
  end
162
174
 
163
- def holdings(...)
164
- Holdings
165
- .new(self, ...)
166
- end
167
-
175
+ # @see RecordsEditor.edit_marc_json
168
176
  def edit_marc_json(...)
169
177
  RecordsEditor
170
178
  .new(self)
171
179
  .edit_marc_json(...)
172
180
  end
181
+
182
+ def organizations(...)
183
+ Organizations
184
+ .new(self)
185
+ .fetch_list(...)
186
+ end
187
+
188
+ def organization_interfaces(...)
189
+ Organizations
190
+ .new(self)
191
+ .fetch_interface_list(...)
192
+ end
193
+
194
+ def interface_details(...)
195
+ Organizations
196
+ .new(self)
197
+ .fetch_interface_details(...)
198
+ end
199
+
200
+ def default_timeout
201
+ 120
202
+ end
173
203
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: folio_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Mangiafico
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-22 00:00:00.000000000 Z
11
+ date: 2023-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -177,10 +177,10 @@ executables: []
177
177
  extensions: []
178
178
  extra_rdoc_files: []
179
179
  files:
180
+ - ".autoupdate/postupdate"
180
181
  - ".rspec"
181
182
  - ".rubocop.yml"
182
183
  - ".rubocop/custom.yml"
183
- - ".rubocop_todo.yml"
184
184
  - ".standard.yml"
185
185
  - Gemfile
186
186
  - Gemfile.lock
@@ -191,9 +191,9 @@ files:
191
191
  - lib/folio_client.rb
192
192
  - lib/folio_client/authenticator.rb
193
193
  - lib/folio_client/data_import.rb
194
- - lib/folio_client/holdings.rb
195
194
  - lib/folio_client/inventory.rb
196
195
  - lib/folio_client/job_status.rb
196
+ - lib/folio_client/organizations.rb
197
197
  - lib/folio_client/records_editor.rb
198
198
  - lib/folio_client/source_storage.rb
199
199
  - lib/folio_client/token_wrapper.rb
@@ -206,7 +206,7 @@ metadata:
206
206
  source_code_uri: https://github.com/sul-dlss/folio_client
207
207
  changelog_uri: https://github.com/sul-dlss/folio_client/releases
208
208
  rubygems_mfa_required: 'true'
209
- post_install_message:
209
+ post_install_message:
210
210
  rdoc_options: []
211
211
  require_paths:
212
212
  - lib
@@ -221,8 +221,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  requirements: []
224
- rubygems_version: 3.3.7
225
- signing_key:
224
+ rubygems_version: 3.3.3
225
+ signing_key:
226
226
  specification_version: 4
227
227
  summary: Interface for interacting with the Folio ILS API.
228
228
  test_files: []
data/.rubocop_todo.yml DELETED
@@ -1,7 +0,0 @@
1
- # This configuration was generated by
2
- # `rubocop --auto-gen-config`
3
- # on 2023-03-03 17:57:09 UTC using RuboCop version 1.44.1.
4
- # The point is for the user to remove these configuration records
5
- # one by one as the offenses are removed from the code base.
6
- # Note that changes in the inspected code, or installation of new
7
- # versions of RuboCop, may require this file to be generated again.
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FolioClient
4
- # Manage holdings records in the Folio inventory
5
- class Holdings
6
- attr_accessor :client, :instance_id
7
-
8
- # @param client [FolioClient] the configured client
9
- # @param instance_id [String] the UUID of the instance to which the holdings record belongs
10
- def initialize(client, instance_id:)
11
- @client = client
12
- @instance_id = instance_id
13
- end
14
-
15
- # create a holdings record for the instance
16
- # @param permanent_location_id [String] the UUID of the permanent location
17
- # @param holdings_type_id [String] the UUID of the holdings type
18
- def create(holdings_type_id:, permanent_location_id:)
19
- client.post("/holdings-storage/holdings", {
20
- instanceId: instance_id,
21
- permanentLocationId: permanent_location_id,
22
- holdingsTypeId: holdings_type_id
23
- })
24
- end
25
- end
26
- end