Skip to content

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
syphax-bouazzouni committed May 9, 2024
1 parent fff5453 commit cf68ad1
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 57 deletions.
35 changes: 21 additions & 14 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,22 @@ PATH
remote: .
specs:
ontologies_api_client (2.2.0)
activesupport
activesupport (~> 7.0.4)
excon
faraday
faraday-excon (~> 2.0.0)
faraday-multipart
lz4-ruby
multi_json
oj
parallel
request_store
spawnling (= 2.1.5)

GEM
remote: https://rubygems.org/
specs:
activesupport (7.0.4)
activesupport (7.0.8.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
Expand All @@ -24,11 +26,11 @@ GEM
public_suffix (>= 2.0.2, < 6.0)
bigdecimal (3.1.7)
coderay (1.1.3)
concurrent-ruby (1.1.10)
concurrent-ruby (1.2.3)
crack (1.0.0)
bigdecimal
rexml
excon (0.95.0)
excon (0.110.0)
faraday (2.0.1)
faraday-net_http (~> 2.0)
ruby2_keywords (>= 0.0.4)
Expand All @@ -39,26 +41,31 @@ GEM
multipart-post (~> 2)
faraday-net_http (2.1.0)
hashdiff (1.1.0)
i18n (1.12.0)
i18n (1.14.4)
concurrent-ruby (~> 1.0)
lz4-ruby (0.3.3)
method_source (1.0.0)
minitest (5.16.3)
method_source (1.1.0)
minitest (5.22.3)
multi_json (1.15.0)
multipart-post (2.2.3)
oj (3.13.23)
power_assert (2.0.2)
pry (0.14.1)
multipart-post (2.4.0)
oj (3.16.3)
bigdecimal (>= 3.0)
parallel (1.24.0)
power_assert (2.0.3)
pry (0.14.2)
coderay (~> 1.1)
method_source (~> 1.0)
public_suffix (5.0.5)
rake (13.0.6)
rack (3.0.10)
rake (13.2.1)
request_store (1.7.0)
rack (>= 1.4)
rexml (3.2.6)
ruby2_keywords (0.0.5)
spawnling (2.1.5)
test-unit (3.5.7)
test-unit (3.6.2)
power_assert
tzinfo (2.0.5)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
webmock (3.23.0)
addressable (>= 2.8.0)
Expand Down
37 changes: 28 additions & 9 deletions config/config.test.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
# config.rb is required for testing
# unit test makes calls to bioportal api so it needs a valid API key which can
# be set via ENV variable UT_APIKEY
abort('UT_APIKEY env variable is not set. Canceling tests') unless ENV.include?('UT_APIKEY')
abort('UT_APIKEY env variable is set to an empty value. Canceling tests') unless ENV['UT_APIKEY'].size > 5
$API_CLIENT_INVALIDATE_CACHE = false
$DEBUG_API_CLIENT = false

LinkedData::Client.config do |config|
config.rest_url = 'https://data.bioontology.org'
config.apikey = ENV['UT_APIKEY']
# config.apikey = 'xxxxx-xxxxx-xxxxxxxxxx'
config.rest_url = 'https://data.bioontology.org/'
config.apikey = '8b5b7825-538d-40e0-9e9e-5ab9274a9aeb'
config.links_attr = 'links'
config.cache = false
config.cache = true
config.debug_client = false
config.debug_client_keys = []
config.federated_portals = {
bioportal: {
api: 'https://data.agroportal.lirmm.fr/',
apikey: '1de0a270-29c5-4dda-b043-7c3580628cd5',
color: '#234979',
},
ecoportal: {
api: 'https://data.ecoportal.lifewatch.eu/',
apikey: "43a437ba-a437-4bf0-affd-ab520e584719",
color: '#0f4e8a',
},
# earthportal: {
# api: 'https://earthportal.eu:8443/',
# apikey: "c9147279-954f-41bd-b068-da9b0c441288",
# color: '#1e2251',
# },
biodivportal: {
api: 'https://data.biodivportal.gfbio.org/',
apikey: "47a57aa3-7b54-4f34-b695-dbb5f5b7363e",
color: '#1e2251',
}
}
end
29 changes: 20 additions & 9 deletions lib/ontologies_api_client/analytics.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require_relative 'request_federation'

module LinkedData::Client
class Analytics
HTTP = LinkedData::Client::HTTP
include LinkedData::Client::RequestFederation

attr_accessor :onts, :date

Expand All @@ -10,18 +13,26 @@ def self.all(params = {})

def self.last_month
data = self.new
data.date = last_month = DateTime.now - 1.month
last_month = DateTime.now - 1.month
year_num = last_month.year
month_num = last_month.month
analytics = get(:analytics, {year: year_num, month: month_num}).to_h
analytics.delete(:links)
analytics.delete(:context)
onts = []
analytics.keys.each do |ont|
views = analytics[ont][:"#{year_num}"][:"#{month_num}"]
onts << {ont: ont, views: views}
params = { year: year_num, month: month_num }

responses = federated_get(params) do |url|
"#{url}/analytics"
end
data.onts = onts

data.onts = responses.map do |portal_views|
next nil if portal_views.errors

portal_views.delete(:links)
portal_views.delete(:context)
portal_views.keys.map do |ont|
views = portal_views[ont][:"#{year_num}"][:"#{month_num}"]
{ ont: "#{conn.url_prefix.to_s.chomp('/')}/ontologies/#{ont}", views: views}
end
end.flatten.compact

data
end

Expand Down
13 changes: 9 additions & 4 deletions lib/ontologies_api_client/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,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
15 changes: 11 additions & 4 deletions lib/ontologies_api_client/collection.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
require_relative 'config'
require_relative 'http'
require_relative 'request_federation'
require 'parallel'

module LinkedData
module Client
module Collection


def self.included(base)
base.include LinkedData::Client::RequestFederation
base.extend(ClassMethods)
end

Expand All @@ -24,8 +28,8 @@ 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)
HTTP.get(link)
end

##
Expand All @@ -36,11 +40,14 @@ def uri_from_context(object, media_type)
end
end


##
# Get the first collection of resources for a given type
def entry_point(media_type, params = {})
params = {include: @include_attrs}.merge(params)
HTTP.get(uri_from_context(top_level_links, media_type), params)
params = { include: @include_attrs, display_links: false, display_context: false}.merge(params)
federated_get(params) do |url|
uri_from_context(top_level_links(url), media_type)
end
end

##
Expand Down
25 changes: 17 additions & 8 deletions lib/ontologies_api_client/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,22 @@ def config(&block)

def config_connection(options = {})
return if @settings_run_connection
store = options[:cache_store]
@settings.conn = Faraday.new(@settings.rest_url) do |faraday|
store = options[:cache_store] || ActiveSupport::Cache::MemoryStore.new
@settings.conn = faraday_connection(@settings.rest_url, @settings.apikey, store)
@settings.federated_conn = @settings.federated_portals.map do |portal_name, portal_info|
[portal_name, faraday_connection(portal_info[:api], portal_info[:apikey], store)]
end.to_h

@settings_run_connection = true
end

def connection_configured?
@settings_run_connection
end

private
def faraday_connection(url, apikey, store)
Faraday.new(url.to_s.chomp('/')) do |faraday|
if @settings.enable_long_request_log
require_relative 'middleware/faraday-long-requests'
faraday.use :long_requests
Expand Down Expand Up @@ -69,15 +83,10 @@ def config_connection(options = {})
faraday.adapter :excon
faraday.headers = {
"Accept" => "application/json",
"Authorization" => "apikey token=#{@settings.apikey}",
"Authorization" => "apikey token=#{apikey}",
"User-Agent" => "NCBO API Ruby Client v0.1.0"
}
end
@settings_run_connection = true
end

def connection_configured?
@settings_run_connection
end
end
end
12 changes: 9 additions & 3 deletions lib/ontologies_api_client/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'digest'
require 'ostruct'
require 'benchmark'
require 'active_support/cache'
##
# This monkeypatch makes OpenStruct act like Struct objects
class OpenStruct
Expand Down Expand Up @@ -48,30 +49,35 @@ def self.conn
rails = Kernel.const_get("Rails")
store = rails.cache if rails.cache
end
LinkedData::Client.config_connection(cache_store: store)
LinkedData::Client.config_connection(cache_store: store || ActiveSupport::Cache::MemoryStore.new)
end
LinkedData::Client.settings.conn
end

def self.federated_conn
LinkedData::Client.settings.federated_conn
end

def self.get(path, params = {}, options = {})
headers = options[:headers] || {}
raw = options[:raw] || false # return the unparsed body of the request
params = params.delete_if { |k, v| v == nil || v.to_s.empty? }
params[:ncbo_cache_buster] = Time.now.to_f if raw # raw requests don't get cached to ensure body is available
invalidate_cache = params.delete(:invalidate_cache) || $API_CLIENT_INVALIDATE_CACHE || false
connection = options[:connection] || conn
begin
begin
response = nil
time = Benchmark.realtime do
response = conn.get do |req|
response = connection.get do |req|
req.url path
req.params = params.dup
req.options[:timeout] = 60
req.headers.merge(headers)
req.headers[:invalidate_cache] = invalidate_cache
end
end
puts "Getting: #{path} with #{params} (#{time}s)" if $DEBUG_API_CLIENT
puts "Getting: #{path} with #{params} (t: #{time}s - cache: #{response.headers["X-Rack-Cache"]})" if $DEBUG_API_CLIENT
rescue Exception => e
params = Faraday::Utils.build_query(params)
path << "?" unless params.empty? || path.include?("?")
Expand Down
5 changes: 3 additions & 2 deletions lib/ontologies_api_client/middleware/faraday-object-cache.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'digest/sha1'
require 'active_support'
require 'active_support/cache'
require 'lz4-ruby'
require_relative '../http'
Expand Down Expand Up @@ -70,7 +71,7 @@ def retrieve_cached_response(request_key)
env = { status: 304 }
cached_response = ObjectCacheResponse.new(env)
cached_response.parsed_body = ld_obj
cached_response.env.response_headers = { "x-rack-cache" => 'hit' }
cached_response.env.response_headers = { "X-Rack-Cache" => 'hit' }
cached_response
end

Expand All @@ -88,7 +89,7 @@ def process_response(response_env, request_key)

response = ObjectCacheResponse.new(response_env)
response.parsed_body = ld_obj
response.env.response_headers["x-rack-cache"] = cache_state
response.env.response_headers["X-Rack-Cache"] = cache_state
response
end

Expand Down
39 changes: 39 additions & 0 deletions lib/ontologies_api_client/request_federation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
require 'active_support/core_ext/hash'

module LinkedData
module Client
module RequestFederation

def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
def federated_get(params = {}, &link)
federate = params.delete(:federate) || ::RequestStore.store[:federated_portals]

portals = [LinkedData::Client::HTTP.conn]

if federate.is_a?(Array)
portals += LinkedData::Client::HTTP.federated_conn
.select{|portal_name, _| federate.include?(portal_name) || federate.include?(portal_name.to_s)}
.values
elsif !federate.blank? # all
portals += LinkedData::Client::HTTP.federated_conn.values
end

connections = Parallel.map(portals, in_threads: portals.size) do |conn|
begin
HTTP.get(link.call(conn.url_prefix.to_s.chomp('/')), params, connection: conn)
rescue StandardError => e
[OpenStruct.new(errors: "Problem retrieving #{link.call(conn.url_prefix.to_s.chomp('/'))}")]
end
end

connections.flatten
end
end

end
end
end
Loading

0 comments on commit cf68ad1

Please sign in to comment.