Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ GEM
unicode-display_width (3.1.4)
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
uri (1.0.2)
uri (1.0.3)

PLATFORMS
arm64-darwin-24
Expand Down
20 changes: 16 additions & 4 deletions lib/ontologies_api_client/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ def type
@type
end

def self.explore(id)
path = self.respond_to?(:collection_path) ? collection_path : ''
id = "#{path}/#{id}" unless id.include?(path)
inst = self.new(values: {id: id})
LinkedData::Client::LinkExplorer.new({}, inst)
end

##
# Retrieve a set of data using a link provided on an object
# This instantiates an instance of this class and uses
Expand Down Expand Up @@ -132,11 +139,16 @@ def create_attributes(attributes)
attr_exists = self.public_methods(false).include?(attr)
unless attr_exists
self.class.class_eval do
define_method attr.to_sym do
instance_variable_get("@#{attr}")
unless method_defined?(attr.to_sym)
define_method attr.to_sym do
instance_variable_get("@#{attr}")
end
end
define_method "#{attr}=" do |val|
instance_variable_set("@#{attr}", val)

unless method_defined?("#{attr}=".to_sym)
define_method "#{attr}=" do |val|
instance_variable_set("@#{attr}", val)
end
end
end
end
Expand Down
9 changes: 5 additions & 4 deletions lib/ontologies_api_client/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ def method_missing(meth, *args, &block)

##
# Get all top-level links for the API
def top_level_links
@top_level_links ||= HTTP.get(LinkedData::Client.settings.rest_url)
def top_level_links(link = LinkedData::Client.settings.rest_url)
@top_level_links ||= {}
@top_level_links[link] ||= HTTP.get(link)
end

##
#
# Return a link given an object (with links) and a media type
def uri_from_context(object, media_type)
object.links.each do |type, link|
return link if link.media_type && link.media_type.downcase.eql?(media_type.downcase)
return link.dup if link.media_type && link.media_type.downcase.eql?(media_type.downcase)
end
end

Expand Down
30 changes: 25 additions & 5 deletions lib/ontologies_api_client/link_explorer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ def initialize(links, instance)
@instance = instance
end

def get(params = {})
get_link(@instance.id, params)
end

def method_missing(meth, *args, &block)
if combined_links.key?(meth.to_s)
explore_link(meth, *args)
elsif meth == :batch
explore_link(args)
elsif !@instance.id.blank?
forward_explore(meth, *args)
else
super
end
Expand Down Expand Up @@ -43,10 +49,7 @@ def explore_link(*args)
ids = link.map {|l| l.to_s}
value_cls.where {|o| ids.include?(o.id)}
else
url = replace_template_elements(link.to_s, replacements)
value_cls = LinkedData::Client::Base.class_for_type(link.media_type)
params[:include] ||= value_cls.attributes(full_attributes)
HTTP.get(url, params)
get_link(link, params, replacements, full_attributes)
end
end

Expand All @@ -56,6 +59,23 @@ def combined_links

private

def forward_explore(meth, *args)
sub_id = Array(args).find { |x| x.is_a?(String) } || ''
escaped_sub_id = Addressable::URI.encode_component(sub_id, Addressable::URI::CharacterClasses::UNRESERVED)
link = "#{@instance.id}/#{meth}/#{escaped_sub_id}".chomp('/')
@instance.id = link
LinkExplorer.new(@links, @instance)
end

def get_link(link, params, replacements = [], full_attributes = {})
url = replace_template_elements(link.to_s, replacements)
if link.respond_to? :media_type
value_cls = LinkedData::Client::Base.class_for_type(link.media_type)
params[:include] ||= value_cls.attributes(full_attributes)
end
HTTP.get(url, params)
end

def replace_template_elements(url, values = [])
return url if values.nil? || values.empty?

Expand Down Expand Up @@ -95,4 +115,4 @@ def linkable_attributes
end
end
end
end
end
6 changes: 3 additions & 3 deletions lib/ontologies_api_client/models/class.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ module Models
class Class < LinkedData::Client::Base
HTTP = LinkedData::Client::HTTP
@media_type = %w[http://www.w3.org/2002/07/owl#Class http://www.w3.org/2004/02/skos/core#Concept]
@include_attrs = "prefLabel,definition,synonym,obsolete,hasChildren"
@include_attrs_full = "prefLabel,definition,synonym,obsolete,properties,hasChildren,children"
@attrs_always_present = :prefLabel, :definition, :synonym, :obsolete, :properties, :hasChildren, :children
@include_attrs = "prefLabel,definition,synonym,obsolete,hasChildren,inScheme,memberOf"
@include_attrs_full = "prefLabel,definition,synonym,obsolete,properties,hasChildren,childre,inScheme,memberOf"
@attrs_always_present = :prefLabel, :definition, :synonym, :obsolete, :properties, :hasChildren, :children, :inScheme, :memberOf

alias :fullId :id

Expand Down
12 changes: 12 additions & 0 deletions lib/ontologies_api_client/models/collection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require_relative "../base"

module LinkedData
module Client
module Models
class Collection < LinkedData::Client::Base
include LinkedData::Client::Collection
@media_type = "http://www.w3.org/2004/02/skos/core#Collection"
end
end
end
end
12 changes: 12 additions & 0 deletions lib/ontologies_api_client/models/scheme.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require_relative "../base"

module LinkedData
module Client
module Models
class Scheme < LinkedData::Client::Base
include LinkedData::Client::Collection
@media_type = "http://www.w3.org/2004/02/skos/core#ConceptScheme"
end
end
end
end
12 changes: 12 additions & 0 deletions lib/ontologies_api_client/models/skos_xl_label.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require_relative "../base"

module LinkedData
module Client
module Models
class Label < LinkedData::Client::Base
include LinkedData::Client::Collection
@media_type = "http://www.w3.org/2008/05/skos-xl#Label"
end
end
end
end
37 changes: 21 additions & 16 deletions test/models/test_class.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# frozen_string_literal: true

require 'faraday/follow_redirects'
require_relative '../test_case'

class ClassTest < LinkedData::Client::TestCase
@@purl_prefix = LinkedData::Client.settings.purl_prefix

def test_find
id = 'http://bioontology.org/ontologies/Activity.owl#Activity'
ontology = 'https://data.bioontology.org/ontologies/BRO'
Expand All @@ -24,12 +25,13 @@ def test_purl_owl
'https://data.bioontology.org/ontologies/BRO'
)
refute_nil cls
expected_purl = "#{@@purl_prefix}/BRO?conceptid=http%3A%2F%2Fbioontology.org%2Fontologies%2FActivity.owl%23Activity"
assert_equal expected_purl, cls.purl

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

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

# The ID already contains the PURL host, so .purl should return it as-is
assert_equal cls.id, cls.purl

res = fetch_response(cls.purl)
assert_equal 200, res.status
assert_equal 'https://bioportal.bioontology.org/ontologies/SNOMEDCT?p=classes&conceptid=64572001',
res.env[:url].to_s
assert_equal 302, res.status
assert_equal 'https://bioportal.bioontology.org/ontologies/SNOMEDCT/classes/64572001',
res.headers['location']
end

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

expected_purl = "#{@@purl_prefix}/DOID?conceptid=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FDOID_4"
assert_equal expected_purl, cls.purl

res = fetch_response(cls.purl)
assert_equal 200, res.status
assert_equal 'https://bioportal.bioontology.org/ontologies/DOID'\
'?p=classes&conceptid=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FDOID_4',
res.env[:url].to_s
assert_equal 302, res.status
assert_equal 'https://bioportal.bioontology.org/ontologies/DOID/classes?conceptid=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FDOID_4',
res.headers['location']
end

private

def fetch_response(url)
conn = Faraday.new do |f|
f.response :follow_redirects
Faraday.new do |f|
f.adapter Faraday.default_adapter
end
conn.get(url)
end.get(url)
end
end
50 changes: 50 additions & 0 deletions test/models/test_explore.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
require_relative '../test_case'
require 'pry'

module Models
def self.method_missing
binding.pry
end
end

class LinkExploreTest < LinkedData::Client::TestCase
def test_explore
sub_direct_explore = LinkedData::Client::Models::Ontology.explore('MEDDRA')
.latest_submission
.get(include: 'all')

sub_indirect_explore = LinkedData::Client::Models::Ontology.find('MEDDRA').explore.latest_submission

refute_nil sub_direct_explore
refute_nil sub_indirect_explore

sub_direct_explore.to_hash.each do |key, value|
value_to_compare = sub_indirect_explore.to_hash[key]
if value.class.ancestors.include?(LinkedData::Client::Base)
value = value.to_hash
value_to_compare = value_to_compare.to_hash
end
# assert_equal value_to_compare, value, "Mismatch for key #{key}"
assert value == value_to_compare, "Mismatch for key #{key}: #{value.inspect} != #{value_to_compare.inspect}"
end
end

def test_explore_class

id = 'http://purl.org/sig/ont/fma/fma62955'
cls = LinkedData::Client::Models::Ontology.explore('FMA')
.classes(id)
.children
.get

refute_empty cls.collection

cls = LinkedData::Client::Models::Ontology.explore('FMA')
.classes(id)
.children
.get(include: 'prefLabel')

refute_empty cls.collection
end

end
Loading