Class: NexusMods::ApiClient
- Inherits:
-
Object
- Object
- NexusMods::ApiClient
- Includes:
- CacheableApi
- Defined in:
- lib/nexus_mods/api_client.rb
Overview
Base class handling HTTP calls to the NexusMods API. Handle caching if needed.
Constant Summary collapse
- DEFAULT_API_CACHE_EXPIRY =
Default expiry times, in seconds
{ games: 24 * 60 * 60, mod: 24 * 60 * 60, mod_files: 24 * 60 * 60 }
Class Attribute Summary collapse
-
.api_client ⇒ Object
ApiClient: The API client to be used by the cacheable adapter (singleton pattern).
Instance Attribute Summary collapse
-
#api_cache_expiry ⇒ Object
readonly
Some attributes exposed for the cacheable feature to work.
Class Method Summary collapse
-
.cache_key(path, parameters:, verb:) ⇒ Object
Get the cache key to be used for a given API query.
Instance Method Summary collapse
-
#api(path, parameters: {}, verb: :get, clear_cache: false) ⇒ Object
Send an HTTP request to the API and get back the answer as a JSON.
-
#api_cache_timestamp(path, parameters: {}, verb: :get) ⇒ Object
Get the timestamp of the cached data linked to a given API call.
-
#http(path, parameters: {}, verb: :get) ⇒ Object
Send an HTTP request to the API and get back the HTTP response.
-
#initialize(api_key: nil, api_cache_expiry: DEFAULT_API_CACHE_EXPIRY, api_cache_file: "#{Dir.tmpdir}/nexus_mods_api_cache.json", logger: Logger.new($stdout)) ⇒ ApiClient
constructor
Constructor.
-
#load_api_cache ⇒ Object
Load the API cache if a file was given to this client.
-
#save_api_cache ⇒ Object
Save the API cache if a file was given to this client.
-
#set_api_cache_timestamp(path, cache_timestamp:, parameters: {}, verb: :get) ⇒ Object
Set the timestamp of the cached data linked to a given API call.
Methods included from CacheableApi
Constructor Details
#initialize(api_key: nil, api_cache_expiry: DEFAULT_API_CACHE_EXPIRY, api_cache_file: "#{Dir.tmpdir}/nexus_mods_api_cache.json", logger: Logger.new($stdout)) ⇒ ApiClient
Constructor
- Parameters
-
api_key (String or nil): The API key to be used, or nil for another authentication [default: nil]
-
api_cache_expiry (Hash<Symbol,Integer>): Expiry times in seconds, per expiry key. Possible keys are:
-
games: Expiry associated to queries on games [default: 1 day]
-
mod: Expiry associated to queries on mod [default: 1 day]
-
mod_files: Expiry associated to queries on mod files [default: 1 day]
-
-
api_cache_file (String): File used to store the NexusMods API cache, or nil for no cache [default: “#Dir.tmpdir/nexus_mods_api_cache.json”]
-
logger (Logger): The logger to be used for log messages [default: Logger.new(STDOUT)]
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/nexus_mods/api_client.rb', line 31 def initialize( api_key: nil, api_cache_expiry: DEFAULT_API_CACHE_EXPIRY, api_cache_file: "#{Dir.tmpdir}/nexus_mods_api_cache.json", logger: Logger.new($stdout) ) @api_key = api_key @api_cache_expiry = DEFAULT_API_CACHE_EXPIRY.merge(api_cache_expiry) @api_cache_file = api_cache_file ApiClient.api_client = self @logger = logger # Initialize our HTTP client @http_client = Faraday.new Cacheable.cache_adapter = :persistent_json load_api_cache end |
Class Attribute Details
.api_client ⇒ Object
ApiClient: The API client to be used by the cacheable adapter (singleton pattern)
131 132 133 |
# File 'lib/nexus_mods/api_client.rb', line 131 def api_client @api_client end |
Instance Attribute Details
#api_cache_expiry ⇒ Object (readonly)
Some attributes exposed for the cacheable feature to work
124 125 126 |
# File 'lib/nexus_mods/api_client.rb', line 124 def api_cache_expiry @api_cache_expiry end |
Class Method Details
.cache_key(path, parameters:, verb:) ⇒ Object
Get the cache key to be used for a given API query
- Parameters
-
path (String): API path to contact (from v1/ and without .json)
-
parameters (Hash<Symbol,Object>): Optional parameters to add to the path [default: {}]
-
verb (Symbol): Verb to be used (:get, :post…) [default: :get]
- Result
-
String: The corresponding cache key
141 142 143 |
# File 'lib/nexus_mods/api_client.rb', line 141 def cache_key(path, parameters:, verb:) "#{verb}/#{path}#{parameters.empty? ? '' : "/#{parameters.map { |param, value| "#{param}=#{value}" }.sort.join('/')}"}" end |
Instance Method Details
#api(path, parameters: {}, verb: :get, clear_cache: false) ⇒ Object
Send an HTTP request to the API and get back the answer as a JSON. Use caching.
- Parameters
-
path (String): API path to contact (from v1/ and without .json)
-
parameters (Hash<Symbol,Object>): Optional parameters to add to the path [default: {}]
-
verb (Symbol): Verb to be used (:get, :post…) [default: :get]
-
clear_cache (Boolean): Should we clear the API cache for this resource? [default: false]
- Result
-
Object: The JSON response
58 59 60 61 |
# File 'lib/nexus_mods/api_client.rb', line 58 def api(path, parameters: {}, verb: :get, clear_cache: false) clear_cached_api_cache(path, parameters:, verb:) if clear_cache cached_api(path, parameters:, verb:) end |
#api_cache_timestamp(path, parameters: {}, verb: :get) ⇒ Object
Get the timestamp of the cached data linked to a given API call
- Parameters
-
path (String): API path to contact (from v1/ and without .json)
-
parameters (Hash<Symbol,Object>): Optional parameters to add to the path [default: {}]
-
verb (Symbol): Verb to be used (:get, :post…) [default: :get]
- Result
-
Time or nil: The refresh time of the data, or nil if not part of the cache
71 72 73 74 75 76 77 |
# File 'lib/nexus_mods/api_client.rb', line 71 def (path, parameters: {}, verb: :get) key = ApiClient.cache_key(path, parameters:, verb:) return unless Cacheable.cache_adapter.exist?(key) str_time = Cacheable.cache_adapter.context.dig(key, 'invalidate_time') str_time.nil? ? nil : Time.parse(str_time) end |
#http(path, parameters: {}, verb: :get) ⇒ Object
Send an HTTP request to the API and get back the HTTP response
- Parameters
-
path (String): API path to contact (from v1/ and without .json)
-
parameters (Hash<Symbol,Object>): Optional parameters to add to the path [default: {}]
-
verb (Symbol): Verb to be used (:get, :post…) [default: :get]
- Result
-
Faraday::Response: The HTTP response
102 103 104 105 106 107 108 |
# File 'lib/nexus_mods/api_client.rb', line 102 def http(path, parameters: {}, verb: :get) @http_client.send(verb) do |req| req.url api_uri(path, parameters:) req.headers['apikey'] = @api_key req.headers['User-Agent'] = "nexus_mods/#{NexusMods::VERSION} (#{RUBY_PLATFORM}) Ruby/#{RUBY_VERSION}" end end |
#load_api_cache ⇒ Object
Load the API cache if a file was given to this client
111 112 113 |
# File 'lib/nexus_mods/api_client.rb', line 111 def load_api_cache Cacheable.cache_adapter.load(@api_cache_file) if @api_cache_file && File.exist?(@api_cache_file) end |
#save_api_cache ⇒ Object
Save the API cache if a file was given to this client
116 117 118 119 120 121 |
# File 'lib/nexus_mods/api_client.rb', line 116 def save_api_cache return unless @api_cache_file FileUtils.mkdir_p(File.dirname(@api_cache_file)) Cacheable.cache_adapter.save(@api_cache_file) end |
#set_api_cache_timestamp(path, cache_timestamp:, parameters: {}, verb: :get) ⇒ Object
Set the timestamp of the cached data linked to a given API call. This should be used only to update the cache timestamp of a resource we know is still up-to-date without fetching the resource for real again.
- Parameters
-
path (String): API path to contact (from v1/ and without .json)
-
parameters (Hash<Symbol,Object>): Optional parameters to add to the path [default: {}]
-
verb (Symbol): Verb to be used (:get, :post…) [default: :get]
-
cache_timestamp (Time): The cache timestamp to set for this resource
87 88 89 90 91 92 |
# File 'lib/nexus_mods/api_client.rb', line 87 def (path, cache_timestamp:, parameters: {}, verb: :get) key = ApiClient.cache_key(path, parameters:, verb:) Cacheable.cache_adapter.context[key] = {} unless Cacheable.cache_adapter.context.key?(key) Cacheable.cache_adapter.context[key]['invalidate_time'] = .utc.strftime('%FT%T.%9NUTC') save_api_cache end |