folio_client 0.8.0 → 0.10.0

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: 726191de10d2f5974ac8294f2c4f93a75146631dd2c86200d2de53f9c72cd76f
4
- data.tar.gz: 2ec95c6e87c4541fb1b2b7050c2bd84d5bd3a46f948b0b711b8f042f58ddf6e5
3
+ metadata.gz: ad8e1c9733f1bba9dc63d5f8c19edb7f4b40a7c16084c3f434175582d466d70a
4
+ data.tar.gz: 32beb6817690d4e95a7ce741fbde1466ccc75b7a13489230b0f1d859af6b7baa
5
5
  SHA512:
6
- metadata.gz: ce0de774a34bbc7eda7a97d26e9ac12d49297a804994425045fe7a8b85017401f54dd11fd43952e4f75e799e232979475f3881eb6f9a211e6f4e32df48168424
7
- data.tar.gz: eb31f66db330ab973060794cfcfb30471c02d21529c5242f62fc11a5d97542f1ce13587af5f8d6b2057d5b709951f9c49690725937e39f3d84236df144da3b73
6
+ metadata.gz: c49e0286404a94fc67bc973b40501885410e5b560e24a922664c2d8e9031766fdfb85af55896cadf21ea8eb91fe85eea6829fa35f7a0645d6a543055c63ef44b
7
+ data.tar.gz: 6f1deeee160c8625a5c84c68c57cfb35e3d28d16af0b08c4423478dc8026ebc8a637dcda752b21b814169c49970c0d399511d9c79020ead609470c90ecb150f8
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.8.0)
4
+ folio_client (0.10.0)
5
5
  activesupport (>= 4.2, < 8)
6
6
  dry-monads
7
7
  faraday
@@ -11,7 +11,7 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activesupport (7.0.4.2)
14
+ activesupport (7.0.4.3)
15
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
16
16
  i18n (>= 1.6, < 2)
17
17
  minitest (>= 5.1)
@@ -67,21 +67,21 @@ GEM
67
67
  diff-lcs (>= 1.2.0, < 2.0)
68
68
  rspec-support (~> 3.12.0)
69
69
  rspec-support (3.12.0)
70
- rubocop (1.44.1)
70
+ rubocop (1.48.1)
71
71
  json (~> 2.3)
72
72
  parallel (~> 1.10)
73
73
  parser (>= 3.2.0.0)
74
74
  rainbow (>= 2.2.2, < 4.0)
75
75
  regexp_parser (>= 1.8, < 3.0)
76
76
  rexml (>= 3.2.5, < 4.0)
77
- rubocop-ast (>= 1.24.1, < 2.0)
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)
84
- rubocop-performance (1.15.2)
84
+ rubocop-performance (1.16.0)
85
85
  rubocop (>= 1.7.0, < 2.0)
86
86
  rubocop-ast (>= 0.4.0)
87
87
  rubocop-rspec (2.19.0)
@@ -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.24.3)
99
+ standard (1.25.3)
100
100
  language_server-protocol (~> 3.17.0.2)
101
- rubocop (= 1.44.1)
102
- rubocop-performance (= 1.15.2)
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)
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
@@ -65,13 +65,13 @@ client.fetch_hrid(barcode: "12345")
65
65
  => "a7927874"
66
66
 
67
67
  # Request a MARC record given an instance hrid
68
- # returns a hash if found; raises FolioClient::UnexpectedResponse::ResourceNotFound if instance_hrid not found
68
+ # returns a hash if found; raises FolioClient::ResourceNotFound if instance_hrid not found
69
69
  client.fetch_marc_hash(instance_hrid: "a7927874")
70
70
  => {"fields"=>
71
71
  [{"003"=>"FOLIO"}....]
72
72
  }
73
73
 
74
- # Import a MARC record
74
+ # Import a MARC record into FOLIO
75
75
  data_importer = client.data_import(marc: my_marc, job_profile_id: '4ba4f4ab', job_profile_name: 'ETDs')
76
76
  # If called too quickly, might get Failure(:not_found)
77
77
  data_importer.status
@@ -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
@@ -10,8 +10,9 @@ class FolioClient
10
10
  @client = client
11
11
  end
12
12
 
13
- # @param barcode [String] barcode to search by to fetch the HRID
14
- # @return [String,nil] HRID if present, otherwise nil.
13
+ # get instance HRID from barcode
14
+ # @param barcode [String] barcode
15
+ # @return [String,nil] instance HRID if present, otherwise nil.
15
16
  def fetch_hrid(barcode:)
16
17
  # find the instance UUID for this barcode
17
18
  instance = client.get("/search/instances", {query: "items.barcode==#{barcode}"})
@@ -24,8 +25,9 @@ class FolioClient
24
25
  result.dig("hrid")
25
26
  end
26
27
 
27
- # @param hrid [String] HRID to search by to fetch the external ID
28
- # @return [String,nil] external ID if present, otherwise nil.
28
+ # get instance external ID from HRID
29
+ # @param hrid [String] instance HRID
30
+ # @return [String,nil] instance external ID if present, otherwise nil.
29
31
  # @raise [ResourceNotFound, MultipleResourcesFound] if search does not return exactly 1 result
30
32
  def fetch_external_id(hrid:)
31
33
  instance_response = client.get("/search/instances", {query: "hrid==#{hrid}"})
@@ -36,11 +38,11 @@ class FolioClient
36
38
  instance_response.dig("instances", 0, "id")
37
39
  end
38
40
 
39
- # Retrieve basic information about a record. Example usage: get the external ID and _version for update using
41
+ # Retrieve basic information about a instance record. Example usage: get the external ID and _version for update using
40
42
  # optimistic locking when the HRID is available: `fetch_instance_info(hrid: 'a1234').slice('id', '_version')`
41
43
  # (or vice versa if the external ID is available).
42
- # @param external_id [String] an external ID for looking up info about the record
43
- # @param hrid [String] an HRID for looking up info about the record
44
+ # @param external_id [String] an external ID for the desired instance record
45
+ # @param hrid [String] an instance HRID for the desired instance record
44
46
  # @return [Hash] information about the record.
45
47
  # @raise [ArgumentError] if the caller does not provide exactly one of external_id or hrid
46
48
  def fetch_instance_info(external_id: nil, hrid: nil)
@@ -51,9 +53,10 @@ class FolioClient
51
53
  client.get("/inventory/instances/#{external_id}")
52
54
  end
53
55
 
54
- # @param hrid [String] folio instance HRID
56
+ # @param hrid [String] instance HRID
55
57
  # @param status_id [String] uuid for an instance status code
56
- # @raise [ResourceNotFound] if search by hrid returns 0 results
58
+ # @return true if instance status matches the uuid param, false otherwise
59
+ # @raise [ResourceNotFound] if search by instance HRID returns 0 results
57
60
  def has_instance_status?(hrid:, status_id:)
58
61
  # get the instance record and its statusId
59
62
  instance = client.get("/inventory/instances", {query: "hrid==#{hrid}"})
@@ -87,7 +87,7 @@ class FolioClient
87
87
  def check_not_found(result, index)
88
88
  return unless result.failure? && result.failure == :not_found && index > 2
89
89
 
90
- raise ResourceNotFound, "Job not found"
90
+ raise ResourceNotFound, "Job #{job_execution_id} not found after #{index} retries"
91
91
  end
92
92
  end
93
93
  end
@@ -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
@@ -10,6 +10,7 @@ class FolioClient
10
10
  @client = client
11
11
  end
12
12
 
13
+ # get marc bib data from folio given an instance HRID
13
14
  # @param instance_hrid [String] the key to use for MARC lookup
14
15
  # @return [Hash] hash representation of the MARC. should be usable by MARC::Record.new_from_hash (from ruby-marc gem)
15
16
  # @raises NotFound, MultipleRecordsForIdentifier
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class FolioClient
4
- VERSION = "0.8.0"
4
+ VERSION = "0.10.0"
5
5
  end
data/lib/folio_client.rb CHANGED
@@ -53,7 +53,8 @@ class FolioClient
53
53
  end
54
54
 
55
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
56
+ delegate :fetch_hrid, :fetch_external_id, :fetch_instance_info, :fetch_marc_hash, :has_instance_status?, :data_import, :edit_marc_json,
57
+ :organizations, :organization_interfaces, :interface_details, to: :instance
57
58
  end
58
59
 
59
60
  attr_accessor :config
@@ -124,50 +125,71 @@ class FolioClient
124
125
  end
125
126
 
126
127
  # Public methods available on the FolioClient below
128
+
129
+ # @see Inventory#fetch_hrid
127
130
  def fetch_hrid(...)
128
131
  Inventory
129
132
  .new(self)
130
133
  .fetch_hrid(...)
131
134
  end
132
135
 
136
+ # @see Inventory#fetch_external_id
133
137
  def fetch_external_id(...)
134
138
  Inventory
135
139
  .new(self)
136
140
  .fetch_external_id(...)
137
141
  end
138
142
 
143
+ # @see Inventory#fetch_instance_info
139
144
  def fetch_instance_info(...)
140
145
  Inventory
141
146
  .new(self)
142
147
  .fetch_instance_info(...)
143
148
  end
144
149
 
150
+ # @see SourceStorage#fetch_marc_hash
145
151
  def fetch_marc_hash(...)
146
152
  SourceStorage
147
153
  .new(self)
148
154
  .fetch_marc_hash(...)
149
155
  end
150
156
 
157
+ # @see Inventory#has_instance_status?
151
158
  def has_instance_status?(...)
152
159
  Inventory
153
160
  .new(self)
154
161
  .has_instance_status?(...)
155
162
  end
156
163
 
164
+ # @ see DataImport#import
157
165
  def data_import(...)
158
166
  DataImport
159
167
  .new(self)
160
168
  .import(...)
161
169
  end
162
170
 
163
- def holdings(...)
164
- Holdings
165
- .new(self, ...)
166
- end
167
-
171
+ # @see RecordsEditor.edit_marc_json
168
172
  def edit_marc_json(...)
169
173
  RecordsEditor
170
174
  .new(self)
171
175
  .edit_marc_json(...)
172
176
  end
177
+
178
+ def organizations(...)
179
+ Organizations
180
+ .new(self)
181
+ .fetch_list(...)
182
+ end
183
+
184
+ def organization_interfaces(...)
185
+ Organizations
186
+ .new(self)
187
+ .fetch_interface_list(...)
188
+ end
189
+
190
+ def interface_details(...)
191
+ Organizations
192
+ .new(self)
193
+ .fetch_interface_details(...)
194
+ end
173
195
  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.8.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Mangiafico
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-03-17 00:00:00.000000000 Z
11
+ date: 2023-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -180,7 +180,6 @@ files:
180
180
  - ".rspec"
181
181
  - ".rubocop.yml"
182
182
  - ".rubocop/custom.yml"
183
- - ".rubocop_todo.yml"
184
183
  - ".standard.yml"
185
184
  - Gemfile
186
185
  - Gemfile.lock
@@ -191,9 +190,9 @@ files:
191
190
  - lib/folio_client.rb
192
191
  - lib/folio_client/authenticator.rb
193
192
  - lib/folio_client/data_import.rb
194
- - lib/folio_client/holdings.rb
195
193
  - lib/folio_client/inventory.rb
196
194
  - lib/folio_client/job_status.rb
195
+ - lib/folio_client/organizations.rb
197
196
  - lib/folio_client/records_editor.rb
198
197
  - lib/folio_client/source_storage.rb
199
198
  - lib/folio_client/token_wrapper.rb
@@ -221,7 +220,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
220
  - !ruby/object:Gem::Version
222
221
  version: '0'
223
222
  requirements: []
224
- rubygems_version: 3.3.7
223
+ rubygems_version: 3.4.5
225
224
  signing_key:
226
225
  specification_version: 4
227
226
  summary: Interface for interacting with the Folio ILS API.
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,25 +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 records belongs
10
- def initialize(client, instance_id:)
11
- @client = client
12
- @instance_id = instance_id
13
- end
14
-
15
- # @param permanent_location_id [String] the UUID of the permanent location
16
- # @param holdings_type_id [String] the UUID of the holdings type
17
- def create(holdings_type_id:, permanent_location_id:)
18
- client.post("/holdings-storage/holdings", {
19
- instanceId: instance_id,
20
- permanentLocationId: permanent_location_id,
21
- holdingsTypeId: holdings_type_id
22
- })
23
- end
24
- end
25
- end