Skip to content

Commit d115613

Browse files
authored
Merge pull request #9 from ncbo/master
Sync with BioPortal release 2.6.0
2 parents c17ab05 + fbf0efd commit d115613

10 files changed

Lines changed: 157 additions & 33 deletions

File tree

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ GEM
100100
unicode-display_width (3.1.4)
101101
unicode-emoji (~> 4.0, >= 4.0.4)
102102
unicode-emoji (4.0.4)
103-
uri (1.0.2)
103+
uri (1.0.3)
104104

105105
PLATFORMS
106106
arm64-darwin-24

lib/ontologies_api_client/base.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ def type
6666
@type
6767
end
6868

69+
def self.explore(id)
70+
path = self.respond_to?(:collection_path) ? collection_path : ''
71+
id = "#{path}/#{id}" unless id.include?(path)
72+
inst = self.new(values: {id: id})
73+
LinkedData::Client::LinkExplorer.new({}, inst)
74+
end
75+
6976
##
7077
# Retrieve a set of data using a link provided on an object
7178
# This instantiates an instance of this class and uses
@@ -132,11 +139,16 @@ def create_attributes(attributes)
132139
attr_exists = self.public_methods(false).include?(attr)
133140
unless attr_exists
134141
self.class.class_eval do
135-
define_method attr.to_sym do
136-
instance_variable_get("@#{attr}")
142+
unless method_defined?(attr.to_sym)
143+
define_method attr.to_sym do
144+
instance_variable_get("@#{attr}")
145+
end
137146
end
138-
define_method "#{attr}=" do |val|
139-
instance_variable_set("@#{attr}", val)
147+
148+
unless method_defined?("#{attr}=".to_sym)
149+
define_method "#{attr}=" do |val|
150+
instance_variable_set("@#{attr}", val)
151+
end
140152
end
141153
end
142154
end

lib/ontologies_api_client/collection.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ def method_missing(meth, *args, &block)
2424

2525
##
2626
# Get all top-level links for the API
27-
def top_level_links
28-
@top_level_links ||= HTTP.get(LinkedData::Client.settings.rest_url)
27+
def top_level_links(link = LinkedData::Client.settings.rest_url)
28+
@top_level_links ||= {}
29+
@top_level_links[link] ||= HTTP.get(link)
2930
end
3031

31-
##
32+
#
3233
# Return a link given an object (with links) and a media type
3334
def uri_from_context(object, media_type)
3435
object.links.each do |type, link|
35-
return link if link.media_type && link.media_type.downcase.eql?(media_type.downcase)
36+
return link.dup if link.media_type && link.media_type.downcase.eql?(media_type.downcase)
3637
end
3738
end
3839

lib/ontologies_api_client/link_explorer.rb

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ def initialize(links, instance)
1111
@instance = instance
1212
end
1313

14+
def get(params = {})
15+
get_link(@instance.id, params)
16+
end
17+
1418
def method_missing(meth, *args, &block)
1519
if combined_links.key?(meth.to_s)
1620
explore_link(meth, *args)
1721
elsif meth == :batch
1822
explore_link(args)
23+
elsif !@instance.id.blank?
24+
forward_explore(meth, *args)
1925
else
2026
super
2127
end
@@ -43,10 +49,7 @@ def explore_link(*args)
4349
ids = link.map {|l| l.to_s}
4450
value_cls.where {|o| ids.include?(o.id)}
4551
else
46-
url = replace_template_elements(link.to_s, replacements)
47-
value_cls = LinkedData::Client::Base.class_for_type(link.media_type)
48-
params[:include] ||= value_cls.attributes(full_attributes)
49-
HTTP.get(url, params)
52+
get_link(link, params, replacements, full_attributes)
5053
end
5154
end
5255

@@ -56,6 +59,23 @@ def combined_links
5659

5760
private
5861

62+
def forward_explore(meth, *args)
63+
sub_id = Array(args).find { |x| x.is_a?(String) } || ''
64+
escaped_sub_id = Addressable::URI.encode_component(sub_id, Addressable::URI::CharacterClasses::UNRESERVED)
65+
link = "#{@instance.id}/#{meth}/#{escaped_sub_id}".chomp('/')
66+
@instance.id = link
67+
LinkExplorer.new(@links, @instance)
68+
end
69+
70+
def get_link(link, params, replacements = [], full_attributes = {})
71+
url = replace_template_elements(link.to_s, replacements)
72+
if link.respond_to? :media_type
73+
value_cls = LinkedData::Client::Base.class_for_type(link.media_type)
74+
params[:include] ||= value_cls.attributes(full_attributes)
75+
end
76+
HTTP.get(url, params)
77+
end
78+
5979
def replace_template_elements(url, values = [])
6080
return url if values.nil? || values.empty?
6181

@@ -95,4 +115,4 @@ def linkable_attributes
95115
end
96116
end
97117
end
98-
end
118+
end

lib/ontologies_api_client/models/class.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ module Models
88
class Class < LinkedData::Client::Base
99
HTTP = LinkedData::Client::HTTP
1010
@media_type = %w[http://www.w3.org/2002/07/owl#Class http://www.w3.org/2004/02/skos/core#Concept]
11-
@include_attrs = "prefLabel,definition,synonym,obsolete,hasChildren"
12-
@include_attrs_full = "prefLabel,definition,synonym,obsolete,properties,hasChildren,children"
13-
@attrs_always_present = :prefLabel, :definition, :synonym, :obsolete, :properties, :hasChildren, :children
11+
@include_attrs = "prefLabel,definition,synonym,obsolete,hasChildren,inScheme,memberOf"
12+
@include_attrs_full = "prefLabel,definition,synonym,obsolete,properties,hasChildren,childre,inScheme,memberOf"
13+
@attrs_always_present = :prefLabel, :definition, :synonym, :obsolete, :properties, :hasChildren, :children, :inScheme, :memberOf
1414

1515
alias :fullId :id
1616

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
require_relative "../base"
2+
3+
module LinkedData
4+
module Client
5+
module Models
6+
class Collection < LinkedData::Client::Base
7+
include LinkedData::Client::Collection
8+
@media_type = "http://www.w3.org/2004/02/skos/core#Collection"
9+
end
10+
end
11+
end
12+
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
require_relative "../base"
2+
3+
module LinkedData
4+
module Client
5+
module Models
6+
class Scheme < LinkedData::Client::Base
7+
include LinkedData::Client::Collection
8+
@media_type = "http://www.w3.org/2004/02/skos/core#ConceptScheme"
9+
end
10+
end
11+
end
12+
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
require_relative "../base"
2+
3+
module LinkedData
4+
module Client
5+
module Models
6+
class Label < LinkedData::Client::Base
7+
include LinkedData::Client::Collection
8+
@media_type = "http://www.w3.org/2008/05/skos-xl#Label"
9+
end
10+
end
11+
end
12+
end

test/models/test_class.rb

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# frozen_string_literal: true
22

3-
require 'faraday/follow_redirects'
43
require_relative '../test_case'
54

65
class ClassTest < LinkedData::Client::TestCase
6+
@@purl_prefix = LinkedData::Client.settings.purl_prefix
7+
78
def test_find
89
id = 'http://bioontology.org/ontologies/Activity.owl#Activity'
910
ontology = 'https://data.bioontology.org/ontologies/BRO'
@@ -24,12 +25,13 @@ def test_purl_owl
2425
'https://data.bioontology.org/ontologies/BRO'
2526
)
2627
refute_nil cls
28+
expected_purl = "#{@@purl_prefix}/BRO?conceptid=http%3A%2F%2Fbioontology.org%2Fontologies%2FActivity.owl%23Activity"
29+
assert_equal expected_purl, cls.purl
2730

2831
res = fetch_response(cls.purl)
29-
assert_equal 200, res.status
30-
assert_equal 'https://bioportal.bioontology.org/ontologies/BRO'\
31-
'?p=classes&conceptid=http%3A%2F%2Fbioontology.org%2Fontologies%2FActivity.owl%23Activity',
32-
res.env[:url].to_s
32+
assert_equal 302, res.status
33+
assert_equal 'https://bioportal.bioontology.org/ontologies/BRO/classes?conceptid=http%3A%2F%2Fbioontology.org%2Fontologies%2FActivity.owl%23Activity',
34+
res.headers['location']
3335
end
3436

3537
# Test PURL generation for a class in a UMLS format ontology
@@ -40,10 +42,13 @@ def test_purl_umls
4042
)
4143
refute_nil cls
4244

45+
# The ID already contains the PURL host, so .purl should return it as-is
46+
assert_equal cls.id, cls.purl
47+
4348
res = fetch_response(cls.purl)
44-
assert_equal 200, res.status
45-
assert_equal 'https://bioportal.bioontology.org/ontologies/SNOMEDCT?p=classes&conceptid=64572001',
46-
res.env[:url].to_s
49+
assert_equal 302, res.status
50+
assert_equal 'https://bioportal.bioontology.org/ontologies/SNOMEDCT/classes/64572001',
51+
res.headers['location']
4752
end
4853

4954
# Test PURL generation for a class in an OBO format ontology
@@ -54,20 +59,20 @@ def test_purl_obo
5459
)
5560
refute_nil cls
5661

62+
expected_purl = "#{@@purl_prefix}/DOID?conceptid=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FDOID_4"
63+
assert_equal expected_purl, cls.purl
64+
5765
res = fetch_response(cls.purl)
58-
assert_equal 200, res.status
59-
assert_equal 'https://bioportal.bioontology.org/ontologies/DOID'\
60-
'?p=classes&conceptid=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FDOID_4',
61-
res.env[:url].to_s
66+
assert_equal 302, res.status
67+
assert_equal 'https://bioportal.bioontology.org/ontologies/DOID/classes?conceptid=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FDOID_4',
68+
res.headers['location']
6269
end
6370

6471
private
6572

6673
def fetch_response(url)
67-
conn = Faraday.new do |f|
68-
f.response :follow_redirects
74+
Faraday.new do |f|
6975
f.adapter Faraday.default_adapter
70-
end
71-
conn.get(url)
76+
end.get(url)
7277
end
7378
end

test/models/test_explore.rb

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
require_relative '../test_case'
2+
require 'pry'
3+
4+
module Models
5+
def self.method_missing
6+
binding.pry
7+
end
8+
end
9+
10+
class LinkExploreTest < LinkedData::Client::TestCase
11+
def test_explore
12+
sub_direct_explore = LinkedData::Client::Models::Ontology.explore('MEDDRA')
13+
.latest_submission
14+
.get(include: 'all')
15+
16+
sub_indirect_explore = LinkedData::Client::Models::Ontology.find('MEDDRA').explore.latest_submission
17+
18+
refute_nil sub_direct_explore
19+
refute_nil sub_indirect_explore
20+
21+
sub_direct_explore.to_hash.each do |key, value|
22+
value_to_compare = sub_indirect_explore.to_hash[key]
23+
if value.class.ancestors.include?(LinkedData::Client::Base)
24+
value = value.to_hash
25+
value_to_compare = value_to_compare.to_hash
26+
end
27+
# assert_equal value_to_compare, value, "Mismatch for key #{key}"
28+
assert value == value_to_compare, "Mismatch for key #{key}: #{value.inspect} != #{value_to_compare.inspect}"
29+
end
30+
end
31+
32+
def test_explore_class
33+
34+
id = 'http://purl.org/sig/ont/fma/fma62955'
35+
cls = LinkedData::Client::Models::Ontology.explore('FMA')
36+
.classes(id)
37+
.children
38+
.get
39+
40+
refute_empty cls.collection
41+
42+
cls = LinkedData::Client::Models::Ontology.explore('FMA')
43+
.classes(id)
44+
.children
45+
.get(include: 'prefLabel')
46+
47+
refute_empty cls.collection
48+
end
49+
50+
end

0 commit comments

Comments
 (0)