wikidata_adaptor 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/.env.test +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +45 -0
- data/.yardopts +10 -0
- data/CHANGELOG.md +106 -0
- data/CLAUDE.md +200 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/COVERAGE.md +77 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +124 -0
- data/LICENSE.txt +21 -0
- data/README.md +269 -0
- data/Rakefile +18 -0
- data/integration/.env.example +20 -0
- data/integration/README.md +58 -0
- data/integration/config/99_IntegrationTesting.php +3 -0
- data/integration/config/wikibase-php.ini +15 -0
- data/integration/docker-compose.yml +98 -0
- data/lib/wikidata_adaptor/rest_api/aliases.rb +88 -0
- data/lib/wikidata_adaptor/rest_api/descriptions.rb +138 -0
- data/lib/wikidata_adaptor/rest_api/items.rb +36 -0
- data/lib/wikidata_adaptor/rest_api/labels.rb +138 -0
- data/lib/wikidata_adaptor/rest_api/open_api_document.rb +15 -0
- data/lib/wikidata_adaptor/rest_api/properties.rb +36 -0
- data/lib/wikidata_adaptor/rest_api/property_data_types.rb +15 -0
- data/lib/wikidata_adaptor/rest_api/search_item.rb +44 -0
- data/lib/wikidata_adaptor/rest_api/search_property.rb +44 -0
- data/lib/wikidata_adaptor/rest_api/sitelinks.rb +59 -0
- data/lib/wikidata_adaptor/rest_api/statements.rb +153 -0
- data/lib/wikidata_adaptor/rest_api.rb +32 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/aliases.rb +229 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/descriptions.rb +308 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/items.rb +213 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/labels.rb +302 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/open_api_document.rb +29 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/properties.rb +233 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/property_data_types.rb +23 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/search_item.rb +118 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/search_property.rb +118 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/sitelinks.rb +143 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/statements.rb +475 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api/support/support.rb +310 -0
- data/lib/wikidata_adaptor/test_helpers/rest_api.rb +89 -0
- data/lib/wikidata_adaptor/version.rb +6 -0
- data/lib/wikidata_adaptor.rb +28 -0
- data/sig/wikidata_adaptor.rbs +4 -0
- metadata +106 -0
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
wikidata_adaptor (1.0.0)
|
|
5
|
+
api_adaptor (>= 1.0.0)
|
|
6
|
+
|
|
7
|
+
GEM
|
|
8
|
+
remote: https://rubygems.org/
|
|
9
|
+
specs:
|
|
10
|
+
addressable (2.8.8)
|
|
11
|
+
public_suffix (>= 2.0.2, < 8.0)
|
|
12
|
+
api_adaptor (1.0.0)
|
|
13
|
+
addressable (~> 2.8)
|
|
14
|
+
base64 (~> 0.3)
|
|
15
|
+
bigdecimal (>= 3.3, < 5.0)
|
|
16
|
+
link_header (~> 0.0.8)
|
|
17
|
+
logger (>= 1.6, < 2.0)
|
|
18
|
+
rest-client (~> 2.1)
|
|
19
|
+
ast (2.4.3)
|
|
20
|
+
base64 (0.3.0)
|
|
21
|
+
bigdecimal (3.3.1)
|
|
22
|
+
crack (1.0.1)
|
|
23
|
+
bigdecimal
|
|
24
|
+
rexml
|
|
25
|
+
diff-lcs (1.6.2)
|
|
26
|
+
domain_name (0.6.20240107)
|
|
27
|
+
dotenv (3.2.0)
|
|
28
|
+
hashdiff (1.2.1)
|
|
29
|
+
http-accept (1.7.0)
|
|
30
|
+
http-cookie (1.1.0)
|
|
31
|
+
domain_name (~> 0.5)
|
|
32
|
+
json (2.18.1)
|
|
33
|
+
language_server-protocol (3.17.0.5)
|
|
34
|
+
link_header (0.0.8)
|
|
35
|
+
lint_roller (1.1.0)
|
|
36
|
+
logger (1.7.0)
|
|
37
|
+
mime-types (3.7.0)
|
|
38
|
+
logger
|
|
39
|
+
mime-types-data (~> 3.2025, >= 3.2025.0507)
|
|
40
|
+
mime-types-data (3.2026.0127)
|
|
41
|
+
netrc (0.11.0)
|
|
42
|
+
parallel (1.27.0)
|
|
43
|
+
parser (3.3.10.1)
|
|
44
|
+
ast (~> 2.4.1)
|
|
45
|
+
racc
|
|
46
|
+
prism (1.9.0)
|
|
47
|
+
public_suffix (6.0.2)
|
|
48
|
+
racc (1.8.1)
|
|
49
|
+
rainbow (3.1.1)
|
|
50
|
+
rake (13.3.1)
|
|
51
|
+
redcarpet (3.6.1)
|
|
52
|
+
regexp_parser (2.11.3)
|
|
53
|
+
rest-client (2.1.0)
|
|
54
|
+
http-accept (>= 1.7.0, < 2.0)
|
|
55
|
+
http-cookie (>= 1.0.2, < 2.0)
|
|
56
|
+
mime-types (>= 1.16, < 4.0)
|
|
57
|
+
netrc (~> 0.8)
|
|
58
|
+
rexml (3.4.4)
|
|
59
|
+
rspec (3.13.2)
|
|
60
|
+
rspec-core (~> 3.13.0)
|
|
61
|
+
rspec-expectations (~> 3.13.0)
|
|
62
|
+
rspec-mocks (~> 3.13.0)
|
|
63
|
+
rspec-core (3.13.6)
|
|
64
|
+
rspec-support (~> 3.13.0)
|
|
65
|
+
rspec-expectations (3.13.5)
|
|
66
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
67
|
+
rspec-support (~> 3.13.0)
|
|
68
|
+
rspec-mocks (3.13.7)
|
|
69
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
70
|
+
rspec-support (~> 3.13.0)
|
|
71
|
+
rspec-support (3.13.6)
|
|
72
|
+
rubocop (1.84.2)
|
|
73
|
+
json (~> 2.3)
|
|
74
|
+
language_server-protocol (~> 3.17.0.2)
|
|
75
|
+
lint_roller (~> 1.1.0)
|
|
76
|
+
parallel (~> 1.10)
|
|
77
|
+
parser (>= 3.3.0.2)
|
|
78
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
79
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
80
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
81
|
+
ruby-progressbar (~> 1.7)
|
|
82
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
83
|
+
rubocop-ast (1.49.0)
|
|
84
|
+
parser (>= 3.3.7.2)
|
|
85
|
+
prism (~> 1.7)
|
|
86
|
+
rubocop-rake (0.7.1)
|
|
87
|
+
lint_roller (~> 1.1)
|
|
88
|
+
rubocop (>= 1.72.1)
|
|
89
|
+
rubocop-rspec (3.9.0)
|
|
90
|
+
lint_roller (~> 1.1)
|
|
91
|
+
rubocop (~> 1.81)
|
|
92
|
+
rubocop-yard (1.1.0)
|
|
93
|
+
lint_roller
|
|
94
|
+
rubocop (~> 1.72)
|
|
95
|
+
yard
|
|
96
|
+
ruby-progressbar (1.13.0)
|
|
97
|
+
unicode-display_width (3.2.0)
|
|
98
|
+
unicode-emoji (~> 4.1)
|
|
99
|
+
unicode-emoji (4.2.0)
|
|
100
|
+
webmock (3.26.1)
|
|
101
|
+
addressable (>= 2.8.0)
|
|
102
|
+
crack (>= 0.3.2)
|
|
103
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
|
104
|
+
yard (0.9.38)
|
|
105
|
+
|
|
106
|
+
PLATFORMS
|
|
107
|
+
ruby
|
|
108
|
+
x86_64-linux
|
|
109
|
+
|
|
110
|
+
DEPENDENCIES
|
|
111
|
+
dotenv (= 3.2.0)
|
|
112
|
+
rake (~> 13.0)
|
|
113
|
+
redcarpet (~> 3.6)
|
|
114
|
+
rspec (~> 3.0)
|
|
115
|
+
rubocop (~> 1.84)
|
|
116
|
+
rubocop-rake
|
|
117
|
+
rubocop-rspec
|
|
118
|
+
rubocop-yard
|
|
119
|
+
webmock (~> 3.17)
|
|
120
|
+
wikidata_adaptor!
|
|
121
|
+
yard (~> 0.9)
|
|
122
|
+
|
|
123
|
+
BUNDLED WITH
|
|
124
|
+
2.5.4
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Huw Diprose
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# WikidataAdaptor
|
|
2
|
+
|
|
3
|
+
[](https://github.com/huwd/wikidata_adaptor/actions/workflows/quality-checks.yml)
|
|
4
|
+
[](https://github.com/huwd/wikidata_adaptor/actions/workflows/docs.yml)
|
|
5
|
+
|
|
6
|
+
A Ruby gem providing a clean, well-documented interface to the [Wikibase REST API](https://doc.wikimedia.org/Wikibase/master/js/rest-api/). Interact with Wikidata and other Wikibase instances to read and write structured data.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **100% API coverage** - All 65 endpoints from Wikibase REST API v1.4
|
|
11
|
+
- **Fully documented** - 100% YARD documentation coverage
|
|
12
|
+
- **Well-tested** - Comprehensive unit and integration test suites
|
|
13
|
+
- **Structured JSON responses** - Consistent response shapes from the API
|
|
14
|
+
- **Test helpers included** - WebMock stubs for easy testing in your applications
|
|
15
|
+
|
|
16
|
+
Supported operations:
|
|
17
|
+
- **Items & Properties** - Create, read, update (GET, POST, PATCH)
|
|
18
|
+
- **Labels** - Multi-language labels with fallback support (GET, PUT, PATCH, DELETE)
|
|
19
|
+
- **Descriptions** - Multi-language descriptions (GET, PUT, PATCH, DELETE)
|
|
20
|
+
- **Aliases** - Alternative names in multiple languages (GET, POST, PATCH)
|
|
21
|
+
- **Statements** - Claims and references (GET, POST, PUT, PATCH, DELETE)
|
|
22
|
+
- **Sitelinks** - Links to related wiki pages (GET, PUT, PATCH, DELETE)
|
|
23
|
+
- **Search** - Full-text search and autocomplete suggestions
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
Add this line to your application's Gemfile:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
gem "wikidata_adaptor"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Then execute:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
bundle install
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or install directly:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
gem install wikidata_adaptor
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Quick Start
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
require "wikidata_adaptor"
|
|
49
|
+
|
|
50
|
+
# Create a client
|
|
51
|
+
client = WikidataAdaptor.rest_api
|
|
52
|
+
|
|
53
|
+
# Get an item (Douglas Adams - Q42)
|
|
54
|
+
item = client.get_item("Q42")
|
|
55
|
+
puts item["labels"]["en"] # => "Douglas Adams"
|
|
56
|
+
|
|
57
|
+
# Get labels in a specific language
|
|
58
|
+
labels = client.get_item_labels("Q42")
|
|
59
|
+
puts labels["en"] # => "Douglas Adams"
|
|
60
|
+
puts labels["fr"] # => "Douglas Adams"
|
|
61
|
+
|
|
62
|
+
# Search for items
|
|
63
|
+
results = client.search_items("Douglas Adams")
|
|
64
|
+
results.each do |result|
|
|
65
|
+
puts "#{result['id']}: #{result['label']}"
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Documentation
|
|
70
|
+
|
|
71
|
+
- **[API Documentation](https://huwd.github.io/wikidata_adaptor/)** - Full YARD documentation
|
|
72
|
+
- **[Wikibase REST API Reference](https://doc.wikimedia.org/Wikibase/master/js/rest-api/)** - Official API docs
|
|
73
|
+
- **[CHANGELOG](CHANGELOG.md)** - Version history and changes
|
|
74
|
+
|
|
75
|
+
## Usage
|
|
76
|
+
|
|
77
|
+
### Reading Data
|
|
78
|
+
|
|
79
|
+
```ruby
|
|
80
|
+
# Get an item with all its data
|
|
81
|
+
item = client.get_item("Q42")
|
|
82
|
+
|
|
83
|
+
# Get specific language label
|
|
84
|
+
label = client.get_item_label("Q42", "en")
|
|
85
|
+
|
|
86
|
+
# Get label with language fallback
|
|
87
|
+
label = client.get_item_label_with_language_fallback("Q42", "en-gb")
|
|
88
|
+
|
|
89
|
+
# Get descriptions
|
|
90
|
+
desc = client.get_item_description("Q42", "en")
|
|
91
|
+
|
|
92
|
+
# Get aliases
|
|
93
|
+
aliases = client.get_item_aliases("Q42")
|
|
94
|
+
|
|
95
|
+
# Get statements (claims)
|
|
96
|
+
statements = client.get_item_statements("Q42")
|
|
97
|
+
|
|
98
|
+
# Filter statements by property
|
|
99
|
+
statements = client.get_item_statements("Q42", property: "P31") # instance of
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Search
|
|
103
|
+
|
|
104
|
+
```ruby
|
|
105
|
+
# Full-text search
|
|
106
|
+
results = client.search_items("Albert Einstein")
|
|
107
|
+
|
|
108
|
+
# Autocomplete suggestions
|
|
109
|
+
suggestions = client.suggest_items("Einst")
|
|
110
|
+
|
|
111
|
+
# Search properties
|
|
112
|
+
properties = client.search_properties("instance of")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Writing Data (requires authentication)
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
# Configure an authenticated REST API client with a bearer token
|
|
119
|
+
rest_api = WikidataAdaptor::RestApi.new(
|
|
120
|
+
"https://www.wikidata.org/w/rest.php/wikibase",
|
|
121
|
+
bearer_token: "your_oauth_token"
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Build a WikidataAdaptor client using the authenticated REST API instance
|
|
125
|
+
client = WikidataAdaptor::Client.new(rest_api: rest_api)
|
|
126
|
+
# Create a new item
|
|
127
|
+
new_item = client.post_item({
|
|
128
|
+
item: {
|
|
129
|
+
labels: { en: "My New Item" },
|
|
130
|
+
descriptions: { en: "A test item" }
|
|
131
|
+
},
|
|
132
|
+
comment: "Creating test item"
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
# Update a label
|
|
136
|
+
client.put_item_label("Q42", "en", {
|
|
137
|
+
label: "Douglas Noël Adams",
|
|
138
|
+
comment: "Adding middle name"
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
# Add a statement
|
|
142
|
+
client.post_item_statement("Q42", {
|
|
143
|
+
statement: {
|
|
144
|
+
property: { id: "P31" },
|
|
145
|
+
value: { content: "Q5", type: "item" }
|
|
146
|
+
},
|
|
147
|
+
comment: "Adding instance of human"
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
# Delete a label
|
|
151
|
+
client.delete_item_label("Q42", "en", {
|
|
152
|
+
comment: "Removing English label"
|
|
153
|
+
})
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Using Different Wikibase Instances
|
|
157
|
+
|
|
158
|
+
By default, the gem connects to Wikidata. To use a different Wikibase instance:
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
ENV["WIKIBASE_REST_ENDPOINT"] = "https://your-wikibase.org/w/rest.php/wikibase"
|
|
162
|
+
client = WikidataAdaptor.rest_api
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Test Helpers
|
|
166
|
+
|
|
167
|
+
The gem includes WebMock test helpers for easy testing:
|
|
168
|
+
|
|
169
|
+
```ruby
|
|
170
|
+
require "wikidata_adaptor/test_helpers/rest_api"
|
|
171
|
+
|
|
172
|
+
RSpec.describe MyClass do
|
|
173
|
+
include WikidataAdaptor::TestHelpers::RestApi
|
|
174
|
+
|
|
175
|
+
it "fetches an item" do
|
|
176
|
+
stub_get_item("Q42") # Stubs the API call
|
|
177
|
+
|
|
178
|
+
result = MyClass.fetch_item("Q42")
|
|
179
|
+
expect(result["labels"]["en"]).to eq("Douglas Adams")
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
See the [test helpers documentation](https://huwd.github.io/wikidata_adaptor/WikidataAdaptor/TestHelpers/RestApi.html) for all available stubs.
|
|
185
|
+
|
|
186
|
+
## Development
|
|
187
|
+
|
|
188
|
+
After checking out the repository:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Install dependencies
|
|
192
|
+
bundle install
|
|
193
|
+
|
|
194
|
+
# Run tests
|
|
195
|
+
bundle exec rake # Run all tests + RuboCop
|
|
196
|
+
bundle exec rspec # Run unit tests only
|
|
197
|
+
bundle exec rubocop # Run linter only
|
|
198
|
+
|
|
199
|
+
# Generate documentation
|
|
200
|
+
bundle exec rake yard
|
|
201
|
+
|
|
202
|
+
# Run integration tests (requires Docker)
|
|
203
|
+
./script/integration-up # Start Wikibase instance
|
|
204
|
+
./script/integration-test # Run integration tests
|
|
205
|
+
./script/integration-down # Stop Wikibase instance
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Project Structure
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
lib/
|
|
212
|
+
├── wikidata_adaptor/
|
|
213
|
+
│ ├── rest_api.rb # Main client class
|
|
214
|
+
│ ├── rest_api/ # API endpoint modules
|
|
215
|
+
│ │ ├── items.rb
|
|
216
|
+
│ │ ├── labels.rb
|
|
217
|
+
│ │ ├── statements.rb
|
|
218
|
+
│ │ └── ...
|
|
219
|
+
│ └── test_helpers/ # WebMock test stubs
|
|
220
|
+
│ └── rest_api/
|
|
221
|
+
│ ├── items.rb
|
|
222
|
+
│ ├── labels.rb
|
|
223
|
+
│ └── ...
|
|
224
|
+
spec/
|
|
225
|
+
├── wikidata_adaptor/rest_api/ # Unit tests
|
|
226
|
+
└── integration/ # Integration tests
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Requirements
|
|
230
|
+
|
|
231
|
+
- Ruby >= 3.2.0
|
|
232
|
+
- Bundler
|
|
233
|
+
|
|
234
|
+
## Contributing
|
|
235
|
+
|
|
236
|
+
Bug reports and pull requests are welcome on [GitHub](https://github.com/huwd/wikidata_adaptor).
|
|
237
|
+
|
|
238
|
+
1. Fork the repository
|
|
239
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
240
|
+
3. Make your changes with tests
|
|
241
|
+
4. Ensure all tests pass (`bundle exec rake`)
|
|
242
|
+
5. Commit following [commit conventions](CLAUDE.md#commit-standards)
|
|
243
|
+
6. Push to the branch (`git push origin my-new-feature`)
|
|
244
|
+
7. Create a Pull Request
|
|
245
|
+
|
|
246
|
+
Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before contributing.
|
|
247
|
+
|
|
248
|
+
See [CLAUDE.md](CLAUDE.md) for detailed development guidelines including:
|
|
249
|
+
- Commit standards (Conventional Commits)
|
|
250
|
+
- Git workflow (branch/PR process)
|
|
251
|
+
- TDD workflow
|
|
252
|
+
- Testing conventions
|
|
253
|
+
|
|
254
|
+
## License
|
|
255
|
+
|
|
256
|
+
This gem is available as open source under the terms of the [MIT License](LICENSE.txt).
|
|
257
|
+
|
|
258
|
+
## Code of Conduct
|
|
259
|
+
|
|
260
|
+
Everyone interacting in the WikidataAdaptor project is expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
261
|
+
|
|
262
|
+
## Links
|
|
263
|
+
|
|
264
|
+
- [Documentation](https://huwd.github.io/wikidata_adaptor/)
|
|
265
|
+
- [Source Code](https://github.com/huwd/wikidata_adaptor)
|
|
266
|
+
- [Issue Tracker](https://github.com/huwd/wikidata_adaptor/issues)
|
|
267
|
+
- [Changelog](CHANGELOG.md)
|
|
268
|
+
- [Wikibase REST API](https://doc.wikimedia.org/Wikibase/master/js/rest-api/)
|
|
269
|
+
- [Wikidata](https://www.wikidata.org/)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "bundler/gem_tasks"
|
|
4
|
+
require "rspec/core/rake_task"
|
|
5
|
+
|
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
7
|
+
|
|
8
|
+
require "rubocop/rake_task"
|
|
9
|
+
|
|
10
|
+
RuboCop::RakeTask.new
|
|
11
|
+
|
|
12
|
+
require "yard"
|
|
13
|
+
|
|
14
|
+
YARD::Rake::YardocTask.new(:yard) do |t|
|
|
15
|
+
t.stats_options = ["--list-undoc"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
task default: %i[spec rubocop]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Copy to integration/.env (optional) and adjust as needed.
|
|
2
|
+
#
|
|
3
|
+
# This stack is intended for local integration testing.
|
|
4
|
+
|
|
5
|
+
WIKIBASE_PORT=8080
|
|
6
|
+
MW_WG_SITENAME=Wikibase
|
|
7
|
+
MW_ADMIN_NAME=admin
|
|
8
|
+
MW_ADMIN_PASS=integration-admin-12345
|
|
9
|
+
MW_ADMIN_EMAIL=admin@example.org
|
|
10
|
+
MW_WG_SERVER=http://localhost:8080
|
|
11
|
+
|
|
12
|
+
# Required by wikibase/wikibase image on first boot
|
|
13
|
+
METADATA_CALLBACK=false
|
|
14
|
+
|
|
15
|
+
DB_NAME=my_wiki
|
|
16
|
+
DB_USER=wikiuser
|
|
17
|
+
DB_PASS=wikpass
|
|
18
|
+
|
|
19
|
+
# Lowering memory can speed up startup on small machines, but too low will crash ES.
|
|
20
|
+
ES_JAVA_OPTS=-Xms512m -Xmx512m -Dlog4j2.formatMsgNoLookups=true
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Integration tests
|
|
2
|
+
|
|
3
|
+
This repo’s default RSpec suite uses WebMock and stubs requests.
|
|
4
|
+
|
|
5
|
+
For end-to-end verification against a real Wikibase instance, run the integration suite.
|
|
6
|
+
|
|
7
|
+
## Prereqs
|
|
8
|
+
|
|
9
|
+
- Docker + Docker Compose (v2)
|
|
10
|
+
- A running Wikibase instance exposing the REST API at `.../w/rest.php/wikibase`
|
|
11
|
+
- You can use the provided `integration/docker-compose.yml` (core-only; no WDQS/SPARQL)
|
|
12
|
+
- `WIKIBASE_REST_ENDPOINT` set to that base URL (defaults to `http://localhost:8080/w/rest.php/wikibase`)
|
|
13
|
+
- If your Wikibase requires authentication for writes, set `WIKIBASE_BEARER_TOKEN`
|
|
14
|
+
|
|
15
|
+
## Running
|
|
16
|
+
|
|
17
|
+
### Bring up local Wikibase (recommended)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cp integration/.env.example integration/.env
|
|
21
|
+
./script/integration-up
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If `wikibase` fails to start with `METADATA_CALLBACK not configured`, make sure
|
|
25
|
+
`METADATA_CALLBACK=false` is present in `integration/.env`.
|
|
26
|
+
|
|
27
|
+
If the MediaWiki installer rejects `MW_ADMIN_PASS`, pick a less common password
|
|
28
|
+
of at least 10 characters in `integration/.env`.
|
|
29
|
+
|
|
30
|
+
### Run integration specs
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
INTEGRATION=1 \
|
|
34
|
+
WIKIBASE_REST_ENDPOINT=http://localhost:8080/w/rest.php/wikibase \
|
|
35
|
+
WIKIBASE_BEARER_TOKEN=... \
|
|
36
|
+
bundle exec rspec --tag integration
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
./script/integration-test
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Tear down
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
./script/integration-down
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Notes
|
|
52
|
+
|
|
53
|
+
- The integration tests currently seed data via `POST /v1/entities/items` and then validate read-only endpoints.
|
|
54
|
+
- If you prefer seeding without write access, we can switch to a container-side import step instead.
|
|
55
|
+
|
|
56
|
+
## Performance
|
|
57
|
+
|
|
58
|
+
This stack omits WDQS/SPARQL and traefik to start faster.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
; ##############################################################################
|
|
2
|
+
; Wikibase Suite PHP settings
|
|
3
|
+
; ##############################################################################
|
|
4
|
+
; Feel free to adjust those settings according your needs.
|
|
5
|
+
; Changes will be picked up automatically by the wikibase container on restart.
|
|
6
|
+
|
|
7
|
+
; Set the PHP upload limits be the same as the MediaWiki default of 100M.
|
|
8
|
+
; Should match the wgMaxUploadSize setting in LocalSettings.php
|
|
9
|
+
file_uploads = On
|
|
10
|
+
upload_max_filesize = 100M
|
|
11
|
+
post_max_size = 100M
|
|
12
|
+
|
|
13
|
+
; Set the PHP memory and execution limits
|
|
14
|
+
memory_limit = 100M
|
|
15
|
+
max_execution_time = 600
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
name: wikidata-adaptor-integration
|
|
2
|
+
|
|
3
|
+
# Core-only Wikibase stack based on:
|
|
4
|
+
# https://github.com/wmde/wikibase-release-pipeline/blob/main/deploy/docker-compose.yml
|
|
5
|
+
#
|
|
6
|
+
# Intentionally omitted for speed:
|
|
7
|
+
# - WDQS / SPARQL (wdqs, wdqs-updater, wdqs-frontend)
|
|
8
|
+
# - traefik
|
|
9
|
+
# - quickstatements
|
|
10
|
+
|
|
11
|
+
services:
|
|
12
|
+
mysql:
|
|
13
|
+
image: mariadb:10.11
|
|
14
|
+
restart: unless-stopped
|
|
15
|
+
environment:
|
|
16
|
+
MYSQL_DATABASE: ${DB_NAME:-my_wiki}
|
|
17
|
+
MYSQL_USER: ${DB_USER:-wikiuser}
|
|
18
|
+
MYSQL_PASSWORD: ${DB_PASS:-wikpass}
|
|
19
|
+
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
|
|
20
|
+
volumes:
|
|
21
|
+
- mysql-data:/var/lib/mysql
|
|
22
|
+
healthcheck:
|
|
23
|
+
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
|
24
|
+
start_period: 60s
|
|
25
|
+
interval: 10s
|
|
26
|
+
timeout: 5s
|
|
27
|
+
retries: 20
|
|
28
|
+
|
|
29
|
+
elasticsearch:
|
|
30
|
+
image: wikibase/elasticsearch:1
|
|
31
|
+
restart: unless-stopped
|
|
32
|
+
environment:
|
|
33
|
+
discovery.type: single-node
|
|
34
|
+
ES_JAVA_OPTS: ${ES_JAVA_OPTS:--Xms512m -Xmx512m -Dlog4j2.formatMsgNoLookups=true}
|
|
35
|
+
volumes:
|
|
36
|
+
- elasticsearch-data:/usr/share/elasticsearch/data
|
|
37
|
+
healthcheck:
|
|
38
|
+
test: ["CMD", "curl", "--silent", "--fail", "http://localhost:9200"]
|
|
39
|
+
start_period: 120s
|
|
40
|
+
interval: 10s
|
|
41
|
+
timeout: 5s
|
|
42
|
+
retries: 20
|
|
43
|
+
|
|
44
|
+
wikibase:
|
|
45
|
+
image: wikibase/wikibase:5
|
|
46
|
+
depends_on:
|
|
47
|
+
mysql:
|
|
48
|
+
condition: service_healthy
|
|
49
|
+
elasticsearch:
|
|
50
|
+
condition: service_healthy
|
|
51
|
+
restart: unless-stopped
|
|
52
|
+
ports:
|
|
53
|
+
- "${WIKIBASE_PORT:-8080}:80"
|
|
54
|
+
volumes:
|
|
55
|
+
# Optional: mount custom config if you need to tweak LocalSettings.
|
|
56
|
+
- ./config:/config:rw
|
|
57
|
+
- ./config/99_IntegrationTesting.php:/var/www/html/LocalSettings.d/99_IntegrationTesting.php:ro
|
|
58
|
+
- wikibase-image-data:/var/www/html/images
|
|
59
|
+
environment:
|
|
60
|
+
# Required by the wikibase/wikibase image on first boot
|
|
61
|
+
METADATA_CALLBACK: ${METADATA_CALLBACK:-false}
|
|
62
|
+
|
|
63
|
+
MW_WG_SITENAME: ${MW_WG_SITENAME:-Wikibase}
|
|
64
|
+
MW_ADMIN_NAME: ${MW_ADMIN_NAME:-admin}
|
|
65
|
+
# MediaWiki enforces password strength requirements on first install.
|
|
66
|
+
MW_ADMIN_PASS: ${MW_ADMIN_PASS:-integration-admin-12345}
|
|
67
|
+
MW_ADMIN_EMAIL: ${MW_ADMIN_EMAIL:-admin@example.org}
|
|
68
|
+
# When running locally without a reverse proxy, keep this http.
|
|
69
|
+
MW_WG_SERVER: ${MW_WG_SERVER:-http://localhost:${WIKIBASE_PORT:-8080}}
|
|
70
|
+
|
|
71
|
+
DB_SERVER: mysql:3306
|
|
72
|
+
DB_USER: ${DB_USER:-wikiuser}
|
|
73
|
+
DB_PASS: ${DB_PASS:-wikpass}
|
|
74
|
+
DB_NAME: ${DB_NAME:-my_wiki}
|
|
75
|
+
|
|
76
|
+
ELASTICSEARCH_HOST: elasticsearch
|
|
77
|
+
healthcheck:
|
|
78
|
+
test:
|
|
79
|
+
["CMD", "curl", "--silent", "--fail", "http://localhost/wiki/Main_Page"]
|
|
80
|
+
interval: 10s
|
|
81
|
+
start_period: 300s
|
|
82
|
+
timeout: 5s
|
|
83
|
+
retries: 30
|
|
84
|
+
|
|
85
|
+
wikibase-jobrunner:
|
|
86
|
+
image: wikibase/wikibase:5
|
|
87
|
+
command: /jobrunner-entrypoint.sh
|
|
88
|
+
depends_on:
|
|
89
|
+
wikibase:
|
|
90
|
+
condition: service_healthy
|
|
91
|
+
restart: unless-stopped
|
|
92
|
+
volumes_from:
|
|
93
|
+
- wikibase
|
|
94
|
+
|
|
95
|
+
volumes:
|
|
96
|
+
mysql-data:
|
|
97
|
+
elasticsearch-data:
|
|
98
|
+
wikibase-image-data:
|