europeana-api 0.5.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +4 -2
- data/Gemfile +1 -8
- data/README.md +103 -21
- data/Rakefile +2 -1
- data/bin/console +21 -0
- data/europeana-api.gemspec +12 -1
- data/lib/europeana/api.rb +44 -68
- data/lib/europeana/api/annotation.rb +20 -0
- data/lib/europeana/api/client.rb +51 -0
- data/lib/europeana/api/entity.rb +16 -0
- data/lib/europeana/api/errors.rb +25 -41
- data/lib/europeana/api/faraday_middleware.rb +26 -0
- data/lib/europeana/api/faraday_middleware/request/authenticated_request.rb +25 -0
- data/lib/europeana/api/faraday_middleware/request/parameter_repetition.rb +25 -0
- data/lib/europeana/api/faraday_middleware/response/handle_text.rb +19 -0
- data/lib/europeana/api/faraday_middleware/response/parse_json_to_various.rb +52 -0
- data/lib/europeana/api/logger.rb +10 -0
- data/lib/europeana/api/queue.rb +47 -0
- data/lib/europeana/api/record.rb +29 -83
- data/lib/europeana/api/request.rb +77 -38
- data/lib/europeana/api/resource.rb +30 -0
- data/lib/europeana/api/response.rb +47 -0
- data/lib/europeana/api/version.rb +2 -1
- data/spec/europeana/api/annotation_spec.rb +77 -0
- data/spec/europeana/api/client_spec.rb +46 -0
- data/spec/europeana/api/entity_spec.rb +6 -0
- data/spec/europeana/api/faraday_middleware/request/authenticated_request_spec.rb +22 -0
- data/spec/europeana/api/queue_spec.rb +4 -0
- data/spec/europeana/api/record_spec.rb +54 -104
- data/spec/europeana/api/request_spec.rb +3 -0
- data/spec/europeana/api/resource_spec.rb +47 -0
- data/spec/europeana/api/response_spec.rb +10 -0
- data/spec/europeana/api_spec.rb +34 -84
- data/spec/spec_helper.rb +8 -0
- data/spec/support/shared_examples/resource_endpoint.rb +11 -0
- metadata +158 -34
- data/lib/europeana/api/record/hierarchy.rb +0 -48
- data/lib/europeana/api/record/hierarchy/ancestor_self_siblings.rb +0 -12
- data/lib/europeana/api/record/hierarchy/base.rb +0 -30
- data/lib/europeana/api/record/hierarchy/children.rb +0 -12
- data/lib/europeana/api/record/hierarchy/following_siblings.rb +0 -12
- data/lib/europeana/api/record/hierarchy/parent.rb +0 -12
- data/lib/europeana/api/record/hierarchy/preceding_siblings.rb +0 -15
- data/lib/europeana/api/record/hierarchy/self.rb +0 -12
- data/lib/europeana/api/requestable.rb +0 -118
- data/lib/europeana/api/search.rb +0 -64
- data/lib/europeana/api/search/fields.rb +0 -112
- data/spec/europeana/api/errors_spec.rb +0 -23
- data/spec/europeana/api/record/hierarchy_spec.rb +0 -15
- data/spec/europeana/api/search_spec.rb +0 -97
- data/spec/support/shared_examples/api_request.rb +0 -65
- data/spec/support/shared_examples/record_request.rb +0 -26
- data/spec/support/shared_examples/search_request.rb +0 -42
- data/spec/support/webmock.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0b2c092e5307dddee16a30424d9f095d1881006
|
4
|
+
data.tar.gz: 9e55b99b93b151cf461c3ddf297329c163a7a3df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57332276a79ed9680b91d31ed8439c67adef397fea3377062eb48797118796722d40e5506dd5fc829e13ea5e375ad81b0460495d1c8c125f3b0d1659756b003f
|
7
|
+
data.tar.gz: bfa182f373f3df742b5db95b3bb14ed9014b0c8ea99545e69ae5c37e1f52a02a9ef14c1104bd76f42e74185ef69a2f96e51cb174dfc74030335828b821eb43ee
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,12 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
source 'https://rubygems.org'
|
2
3
|
|
3
4
|
# Specify your gem's dependencies in europeana.gemspec
|
4
5
|
gemspec
|
5
|
-
|
6
|
-
group :test do
|
7
|
-
gem 'coveralls', require: false
|
8
|
-
end
|
9
|
-
|
10
|
-
group :test, :develop do
|
11
|
-
gem 'rubocop', '0.39.0', require: false # only update when Hound does
|
12
|
-
end
|
data/README.md
CHANGED
@@ -1,15 +1,13 @@
|
|
1
|
-
# Europeana
|
1
|
+
# Europeana API
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/europeana/europeana-api-client-ruby.svg?branch=
|
3
|
+
[![Build Status](https://travis-ci.org/europeana/europeana-api-client-ruby.svg?branch=develop)](https://travis-ci.org/europeana/europeana-api-client-ruby) [![Coverage Status](https://coveralls.io/repos/europeana/europeana-api-client-ruby/badge.svg?branch=develop&service=github)](https://coveralls.io/github/europeana/europeana-api-client-ruby?branch=develop) [![security](https://hakiri.io/github/europeana/europeana-api-client-ruby/develop.svg)](https://hakiri.io/github/europeana/europeana-api-client-ruby/develop) [![Dependency Status](https://gemnasium.com/europeana/europeana-api-client-ruby.svg)](https://gemnasium.com/europeana/europeana-api-client-ruby)
|
4
4
|
|
5
5
|
Ruby client library for the search and retrieval of records from the [Europeana
|
6
6
|
REST API](http://labs.europeana.eu/api/introduction/).
|
7
7
|
|
8
|
-
##
|
9
|
-
|
10
|
-
Licensed under the EUPL V.1.1.
|
8
|
+
## Requirements
|
11
9
|
|
12
|
-
|
10
|
+
* Ruby >= 2.2.2
|
13
11
|
|
14
12
|
## Installation
|
15
13
|
|
@@ -21,19 +19,21 @@ gem 'europeana-api'
|
|
21
19
|
|
22
20
|
And then execute:
|
23
21
|
|
24
|
-
|
22
|
+
```
|
23
|
+
bundle
|
24
|
+
```
|
25
25
|
|
26
26
|
Or install it yourself as:
|
27
27
|
|
28
|
-
|
28
|
+
```
|
29
|
+
gem install europeana-api
|
30
|
+
```
|
29
31
|
|
30
32
|
## Usage
|
31
33
|
|
32
34
|
### Authentication
|
33
35
|
|
34
|
-
Authentication is *required* for all requests to the Europeana API.
|
35
|
-
|
36
|
-
Only Basic Authentication (by API key) is supported.
|
36
|
+
Authentication by API key is *required* for all requests to the Europeana API.
|
37
37
|
|
38
38
|
Sign up for an API key at: http://labs.europeana.eu/api/registration/
|
39
39
|
|
@@ -41,26 +41,108 @@ Configure your application with the API key:
|
|
41
41
|
|
42
42
|
```ruby
|
43
43
|
require 'europeana/api'
|
44
|
-
Europeana::API.
|
44
|
+
Europeana::API.key = 'xyz'
|
45
|
+
```
|
46
|
+
|
47
|
+
### Response format
|
48
|
+
|
49
|
+
Responses from the API methods described below will by default be hashes with
|
50
|
+
indifferent access, i.e. values can be retrieved by string or symbol keys.
|
51
|
+
|
52
|
+
To have API methods return objects instead:
|
53
|
+
```ruby
|
54
|
+
Europeana::API.configure do |config|
|
55
|
+
config.parse_json_to = OpenStruct
|
56
|
+
end
|
45
57
|
```
|
46
58
|
|
47
|
-
###
|
59
|
+
### Records
|
60
|
+
|
61
|
+
#### Search
|
48
62
|
|
49
63
|
```ruby
|
50
|
-
search = Europeana::API.search(query: '"first world war"')
|
51
|
-
search[
|
52
|
-
search[
|
64
|
+
search = Europeana::API.record.search(query: '"first world war"')
|
65
|
+
search[:items] # => [ item1, item2, ... ]
|
66
|
+
search[:totalResults] # => 81530
|
53
67
|
```
|
54
68
|
|
55
|
-
See http://labs.europeana.eu/api/search/ for details of the
|
56
|
-
the search response.
|
69
|
+
See http://labs.europeana.eu/api/search/ for details of the available request
|
70
|
+
parameters, and of the data returned in the search response.
|
57
71
|
|
58
|
-
|
72
|
+
#### Fetch
|
59
73
|
|
60
74
|
```ruby
|
61
|
-
record = Europeana::API.record('/
|
62
|
-
record[
|
75
|
+
record = Europeana::API.record.fetch(id: '/92070/BibliographicResource_1000126223918')
|
76
|
+
record[:object][:title] # => ["Panorama des Schafberges in Ober-Österreich. Blatt 1"]
|
77
|
+
record[:object][:proxies].first[:dcCreator][:def] # => ["Simony, Friedrich"]
|
63
78
|
```
|
64
79
|
|
65
80
|
See http://labs.europeana.eu/api/record/ for details of the data returned in
|
66
81
|
the record response.
|
82
|
+
|
83
|
+
#### Hierarchies
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
hierarchy = Europeana::API.record.parent(id: '/2048604/data_item_onb_abo__2BZ17084070X')
|
87
|
+
hierarchy[:parent][:id] # => "/2048604/data_item_onb_abo_AC10352829"
|
88
|
+
```
|
89
|
+
|
90
|
+
Methods available for hierarchy retrieval:
|
91
|
+
```ruby
|
92
|
+
Europeana::API.record.self
|
93
|
+
Europeana::API.record.parent
|
94
|
+
Europeana::API.record.children
|
95
|
+
Europeana::API.record.preceding_siblings
|
96
|
+
Europeana::API.record.following_siblings
|
97
|
+
Europeana::API.record.ancestor_self_siblings
|
98
|
+
```
|
99
|
+
|
100
|
+
See http://labs.europeana.eu/api/hierarchical-records for details of the various
|
101
|
+
hierarchy methods and their responses.
|
102
|
+
|
103
|
+
### Annotations
|
104
|
+
|
105
|
+
See http://labs.europeana.eu/api/annotations-methods for details of the responses
|
106
|
+
received from the Annotations API methods.
|
107
|
+
|
108
|
+
#### Search
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
search = Europeana::API.annotation.search(query: 'music')
|
112
|
+
search[:items].first # => "http://data.europeana.eu/annotation/collections/8"
|
113
|
+
```
|
114
|
+
|
115
|
+
#### Fetch
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
annotation = Europeana::API.annotation.fetch(provider: 'collections', id: 8)
|
119
|
+
annotation[:body] # => "Sheet music"
|
120
|
+
```
|
121
|
+
|
122
|
+
#### Create
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
body = { bodyValue: 'Trombones', motivation: 'tagging', target: 'http://data.europeana.eu/item/09102/_UEDIN_214' }
|
126
|
+
annotation = Europeana::API.annotation.create(userToken: 'secret-token', body: body.to_json)
|
127
|
+
annotation[:id] # => "http://www.europeana.eu/api/annotations/myname/1234"
|
128
|
+
```
|
129
|
+
|
130
|
+
#### Update
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
body = { bodyValue: 'Trombones', motivation: 'tagging' }
|
134
|
+
annotation = Europeana::API.annotation.update(provider: 'myname', id: '1234', userToken: 'secret-token', body: body.to_json)
|
135
|
+
annotation[:body][:value] # => "Trombones"
|
136
|
+
```
|
137
|
+
|
138
|
+
#### Delete
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
Europeana::API.annotation.delete(provider: 'myname', id: '1234', userToken: 'secret-token') # => ""
|
142
|
+
```
|
143
|
+
|
144
|
+
## License
|
145
|
+
|
146
|
+
Licensed under the EUPL V.1.1.
|
147
|
+
|
148
|
+
For full details, see [LICENSE.md](LICENSE.md).
|
data/Rakefile
CHANGED
data/bin/console
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'dotenv'
|
5
|
+
Dotenv.load
|
6
|
+
|
7
|
+
require 'bundler/setup'
|
8
|
+
require 'europeana/api'
|
9
|
+
|
10
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
11
|
+
# with your gem easier. You can also use a different console, if you like.
|
12
|
+
|
13
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
14
|
+
# require 'pry'
|
15
|
+
# Pry.start
|
16
|
+
|
17
|
+
Europeana::API.key = ENV['EUROPEANA_API_KEY']
|
18
|
+
Europeana::API.url = ENV['EUROPEANA_API_URL'] if ENV['EUROPEANA_API_URL']
|
19
|
+
|
20
|
+
require 'irb'
|
21
|
+
IRB.start
|
data/europeana-api.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
2
3
|
lib = File.expand_path('../lib', __FILE__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
5
|
require 'europeana/api/version'
|
@@ -20,11 +21,21 @@ Gem::Specification.new do |spec|
|
|
20
21
|
|
21
22
|
spec.required_ruby_version = '>= 2.0.0'
|
22
23
|
|
23
|
-
spec.add_dependency 'activesupport', '>=
|
24
|
+
spec.add_dependency 'activesupport', '>= 4.2', '< 6.0'
|
25
|
+
# Locked to < v0.12.2 due to incompatibility with v0.12.2
|
26
|
+
# TODO: resolve incompatibility and unlock
|
27
|
+
spec.add_dependency 'faraday', '~> 0.9', '< 0.12.2'
|
28
|
+
spec.add_dependency 'faraday_middleware'
|
24
29
|
spec.add_dependency 'multi_json', '~> 1.0'
|
30
|
+
spec.add_dependency 'rack', '> 1.6.2'
|
31
|
+
spec.add_dependency 'typhoeus', '~> 1.1'
|
25
32
|
|
26
33
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
34
|
+
spec.add_development_dependency 'coveralls'
|
35
|
+
spec.add_development_dependency 'dotenv'
|
27
36
|
spec.add_development_dependency 'rake'
|
28
37
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
38
|
+
spec.add_development_dependency 'rubocop', '0.39.0' # only update when Hound does
|
39
|
+
spec.add_development_dependency 'shoulda-matchers', '~> 3.1'
|
29
40
|
spec.add_development_dependency 'webmock', '~> 1.18.0'
|
30
41
|
end
|
data/lib/europeana/api.rb
CHANGED
@@ -1,112 +1,88 @@
|
|
1
|
-
|
2
|
-
require 'active_support/
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_support/concern'
|
3
|
+
require 'active_support/core_ext/class/attribute'
|
3
4
|
require 'active_support/core_ext/hash/indifferent_access'
|
4
5
|
require 'active_support/core_ext/hash/slice'
|
6
|
+
require 'active_support/core_ext/module/delegation'
|
7
|
+
require 'active_support/core_ext/object'
|
5
8
|
require 'active_support/hash_with_indifferent_access'
|
6
9
|
require 'active_support/inflector/methods'
|
10
|
+
require 'active_support/json'
|
7
11
|
require 'europeana/api/version'
|
12
|
+
require 'europeana/api/logger'
|
8
13
|
require 'logger'
|
9
14
|
require 'uri'
|
10
15
|
|
11
16
|
module Europeana
|
12
17
|
##
|
13
|
-
# Europeana
|
18
|
+
# Interface to Europeana's RESTful API(s)
|
14
19
|
module API
|
20
|
+
autoload :Annotation, 'europeana/api/annotation'
|
21
|
+
autoload :Client, 'europeana/api/client'
|
22
|
+
autoload :Entity, 'europeana/api/entity'
|
15
23
|
autoload :Errors, 'europeana/api/errors'
|
24
|
+
autoload :FaradayMiddleware, 'europeana/api/faraday_middleware'
|
25
|
+
autoload :Queue, 'europeana/api/queue'
|
16
26
|
autoload :Record, 'europeana/api/record'
|
17
27
|
autoload :Request, 'europeana/api/request'
|
18
|
-
autoload :
|
19
|
-
autoload :
|
28
|
+
autoload :Resource, 'europeana/api/resource'
|
29
|
+
autoload :Response, 'europeana/api/response'
|
30
|
+
|
31
|
+
@url = 'https://www.europeana.eu/api'
|
20
32
|
|
21
33
|
class << self
|
22
34
|
##
|
23
35
|
# The Europeana API key, required for authentication
|
24
36
|
#
|
25
37
|
# @return [String]
|
26
|
-
attr_accessor :
|
38
|
+
attr_accessor :key
|
27
39
|
|
28
40
|
##
|
29
41
|
# The API's base URL
|
30
42
|
#
|
31
43
|
# @return [String]
|
32
44
|
attr_accessor :url
|
33
|
-
|
34
|
-
##
|
35
|
-
# The maximum number of retries permitted
|
36
|
-
#
|
37
|
-
# Retries occur when a network request to the API fails. The default is 5
|
38
|
-
# retries before giving up.
|
39
|
-
#
|
40
|
-
# @return [Integer]
|
41
|
-
attr_accessor :max_retries
|
42
|
-
|
43
|
-
##
|
44
|
-
# The number of seconds to wait between retries
|
45
|
-
#
|
46
|
-
# The default is 10 seconds.
|
47
|
-
#
|
48
|
-
# @return [Integer]
|
49
|
-
attr_accessor :retry_delay
|
50
45
|
|
51
46
|
# @return [Logger]
|
52
47
|
attr_writer :logger
|
53
48
|
|
54
|
-
|
49
|
+
def configuration
|
50
|
+
@configuration ||= Configuration.new
|
51
|
+
end
|
55
52
|
|
56
|
-
|
53
|
+
def logger
|
54
|
+
@logger ||= defined?(Rails) && Rails.logger ? Rails.logger : Logger.new(STDOUT)
|
55
|
+
end
|
57
56
|
|
58
|
-
|
59
|
-
|
60
|
-
def defaults!
|
61
|
-
self.url = 'https://www.europeana.eu/api/v2'
|
62
|
-
self.max_retries = 5
|
63
|
-
self.retry_delay = 10
|
64
|
-
self.cache_store = ActiveSupport::Cache::NullStore.new
|
65
|
-
self.cache_expires_in = 24.hours
|
57
|
+
def configure
|
58
|
+
yield(configuration)
|
66
59
|
end
|
67
60
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
# search = Europeana::API::Search.new(params)
|
73
|
-
# search.execute
|
74
|
-
#
|
75
|
-
# @param [Hash] params Query parameters
|
76
|
-
# @return [Hash] search response
|
77
|
-
# @see Europeana::API::Search#execute
|
78
|
-
def search(params = {})
|
79
|
-
Search.new(params).execute
|
61
|
+
def in_parallel(&block)
|
62
|
+
client = Client.new
|
63
|
+
yield client.queue
|
64
|
+
client.queue.run
|
80
65
|
end
|
81
66
|
|
82
|
-
|
83
|
-
|
84
|
-
#
|
85
|
-
# Equivalent to:
|
86
|
-
# record = Europeana::API::Record.new(record_id, params)
|
87
|
-
# record.get(options)
|
88
|
-
#
|
89
|
-
# @param [String] Record ID
|
90
|
-
# @param [Hash] params Query parameters
|
91
|
-
# @param [Hash] options (see Europeana::API::Record#get)
|
92
|
-
# @return [Hash] search response
|
93
|
-
# @see Europeana::API::Record#get
|
94
|
-
def record(record_id, params = {}, options = {})
|
95
|
-
Record.new(record_id, params).get(options)
|
67
|
+
def annotation
|
68
|
+
Annotation
|
96
69
|
end
|
97
70
|
|
98
|
-
def
|
99
|
-
|
71
|
+
def record
|
72
|
+
Record
|
73
|
+
end
|
100
74
|
|
101
|
-
|
102
|
-
|
103
|
-
Rails.logger
|
104
|
-
else
|
105
|
-
Logger.new(STDOUT)
|
106
|
-
end
|
75
|
+
def entity
|
76
|
+
Entity
|
107
77
|
end
|
108
78
|
end
|
109
79
|
|
110
|
-
|
80
|
+
class Configuration
|
81
|
+
attr_accessor :parse_json_to
|
82
|
+
|
83
|
+
def initialize
|
84
|
+
@parse_json_to = Hash
|
85
|
+
end
|
86
|
+
end
|
111
87
|
end
|
112
88
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Europeana
|
3
|
+
module API
|
4
|
+
##
|
5
|
+
# An annotation of a Europeana object
|
6
|
+
#
|
7
|
+
# @see http://labs.europeana.eu/api/annotations
|
8
|
+
class Annotation
|
9
|
+
include Resource
|
10
|
+
|
11
|
+
has_api_endpoint :search, method: :get, path: '/annotations/search'
|
12
|
+
has_api_endpoint :fetch, method: :get, path: '/annotations/%{provider}/%{id}'
|
13
|
+
has_api_endpoint :create, method: :post, path: '/annotations/',
|
14
|
+
headers: { 'Content-Type' => 'application/ld+json' }
|
15
|
+
has_api_endpoint :update, method: :put, path: '/annotations/%{provider}/%{id}',
|
16
|
+
headers: { 'Content-Type' => 'application/ld+json' }
|
17
|
+
has_api_endpoint :delete, method: :delete, path: '/annotations/%{provider}/%{id}'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|