module Mfkessai::Client

Public Instance Methods

_uname_uname() click to toggle source
# File lib/mfkessai/client.rb, line 118
def _uname_uname
  (`uname -a 2>/dev/null` || '').strip
rescue Errno::ENOMEM # couldn't create subprocess
  "uname lookup failed"
end
_uname_ver() click to toggle source
# File lib/mfkessai/client.rb, line 124
def _uname_ver
  (`ver` || '').strip
rescue Errno::ENOMEM # couldn't create subprocess
  "uname lookup failed"
end
check_api_key!(api_key) click to toggle source
# File lib/mfkessai/client.rb, line 200
def check_api_key!(api_key)
  unless api_key
    error_message = "No API key provided. " \
      'Set your API key using "Mfkessai.api_key = <API-KEY>". ' \
      "You can generate API keys from the Mfkessai web interface. "
    raise AuthenticationError.new(message: error_message)
  end

  return unless api_key =~ /\s/
  error_message = "Your API key is invalid, as it contains " \
    "whitespace. (HINT: You can double-check your API key from the "
  raise AuthenticationError.new(message: error_message)
end
from_faraday_response(http_resp) click to toggle source
# File lib/mfkessai/client.rb, line 41
def from_faraday_response(http_resp)
  response = Struct.new(:data, :http_body, :http_headers, :http_status)
  resp = response.new

  # response bodyがokの場合、v1/pingからのリクエストなので処理を分ける
  if http_resp.body == 'ok'
    resp.http_body = http_resp.body
    resp.http_headers = http_resp.headers
    resp.http_status = http_resp.status
  else
    resp.data = JSON.parse(http_resp.body, symbolize_names: true)
    resp.http_body = http_resp.body
    resp.http_headers = http_resp.headers
    resp.http_status = http_resp.status
  end
  resp
end
general_api_error(status:, body:) click to toggle source
# File lib/mfkessai/client.rb, line 193
def general_api_error(status:, body:)
  error_message = "Invalid response object from API: #{body.inspect} \n HTTP response code was #{status})"
  APIConnectionError.new(message: error_message,
                         http_status: status,
                         http_body: body)
end
handle_error_response(error_response:) click to toggle source
# File lib/mfkessai/client.rb, line 130
def handle_error_response(error_response:)
  case error_response[:status]
  when 400
    data = JSON.parse(error_response[:body], symbolize_names: true)
    raise BadRequestError.new(message: data[:detail],
                              http_status: error_response[:status],
                              http_body: error_response[:body],
                              json_body: data)
  when 401
    data = JSON.parse(error_response[:body], symbolize_names: true)
    raise AuthenticationError.new(message: data[:detail],
                                  http_status: error_response[:status],
                                  http_body: error_response[:body],
                                  json_body: data)
  when 403
    data = JSON.parse(error_response[:body], symbolize_names: true)
    raise ForbiddenError.new(message: data[:detail],
                             http_status: error_response[:status],
                             http_body: error_response[:body],
                             json_body: data)
  when 404
    data = JSON.parse(error_response[:body], symbolize_names: true)
    raise NotFoundError.new(message: data[:detail],
                            http_status: error_response[:status],
                            http_body: error_response[:body],
                            json_body: data)
  when 500
    data = JSON.parse(error_response[:body], symbolize_names: true)
    raise ServerError.new(message: data[:detail],
                          http_status: error_response[:status],
                          http_body: error_response[:body],
                          json_body: data)
  when 503
    data = JSON.parse(error_response[:body], symbolize_names: true)
    raise ServerError.new(message: data[:detail],
                          http_status: error_response[:status],
                          http_body: error_response[:body],
                          json_body: data)
  else
    raise ServerError.new(http_status: 500)
  end
end
handle_network_error(e) click to toggle source
# File lib/mfkessai/client.rb, line 173
def handle_network_error(e)
  case e
  when Faraday::ConnectionFailed
    message = "Unexpected error communicating when trying to connect to Mfkessai. " \
      "You may be seeing this message because your DNS is not working. "
  when Faraday::SSLError
    message = "Could not establish a secure connection to Mfkessai, you may " \
              "need to upgrade your OpenSSL version. To check, try running "
  when Faraday::TimeoutError
    message = "Could not connect to Mfkessai (#{Mfkessai.api_key}). " \
      "Please check your internet connection and try again. "
  else
    message = "Unexpected error communicating with Mfkessai. "
  end

  message += " Request was retried"

  raise APIConnectionError.new(message: message + "\n\n(Network error: #{e.message})")
end
list_filter_parameters(page, per_page) click to toggle source
# File lib/mfkessai/client.rb, line 59
def list_filter_parameters(page, per_page)
  params = {}
  params[:page] = page if page
  params[:per_page] = per_page if per_page
  '?' + URI.encode_www_form(params)
end
request(url:, request_type:, request_body: nil) click to toggle source
# File lib/mfkessai/client.rb, line 4
def request(url:, request_type:, request_body: nil)
  api_url = Mfkessai.api_url
  api_key = Mfkessai.api_key

  check_api_key!(api_key)

  url = "#{api_url}#{url}"
  uri = URI.parse(url)

  conn = Faraday.new(:ssl => {:verify => false}) do |c|
    c.use Faraday::Request::Multipart
    c.use Faraday::Request::UrlEncoded
    c.use Faraday::Response::RaiseError
    c.adapter Faraday.default_adapter
  end

  payload = request_body.nil? ? request_body : request_body.to_json

  http_resp = conn.run_request(request_type, uri, payload, request_headers) do |req|
    req.options.open_timeout = Mfkessai.open_timeout
    req.options.timeout = Mfkessai.read_timeout
  end
  from_faraday_response(http_resp)
rescue JSON::ParserError => e
  raise general_api_error(status: http_resp.status, body: http_resp.body)
rescue Faraday::ClientError => e
  if e.response
    handle_error_response(error_response: e.response)
  else
    handle_network_error(e)
  end
rescue AuthenticationError => e
  raise AuthenticationError.new(http_status: 401, message: e.message)
rescue StandardError => e
  raise ServerError.new(http_status: 500)
end
request_headers() click to toggle source
# File lib/mfkessai/client.rb, line 66
def request_headers
  headers = {
    "User-Agent" => "Mfkessai/v1 RubyBindings/#{Mfkessai::VERSION}",
    "apiKey" => Mfkessai.api_key,
    "Content-Type" => "application/json",
  }

  headers["Mfkessai-Version"] = Mfkessai.api_version if Mfkessai.api_version

  begin
    headers.update(
      "X-Mfkessai-Client-User-Agent" => JSON.generate(user_agent)
    )
  rescue StandardError => e
    headers.update(
      "X-Mfkessai-Client-Raw-User-Agent" => user_agent.inspect,
      :error => "#{e} (#{e.class})"
    )
  end
  headers
end
uname() click to toggle source
# File lib/mfkessai/client.rb, line 103
def uname
  if File.exist?('/proc/version')
    File.read('/proc/version').strip
  else
    case RbConfig::CONFIG['host_os']
    when /linux|darwin|bsd|sunos|solaris|cygwin/i
      _uname_uname
    when /mswin|mingw/i
      _uname_ver
    else
      "unknown platform"
    end
  end
end
user_agent() click to toggle source
# File lib/mfkessai/client.rb, line 88
def user_agent
  @uname ||= uname
  lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"

  {
    :bindings_version => Mfkessai::VERSION,
    :lang => 'ruby',
    :lang_version => lang_version,
    :platform => RUBY_PLATFORM,
    :engine => defined?(RUBY_ENGINE) ? RUBY_ENGINE : '',
    :uname => @uname,
    :hostname => Socket.gethostname
  }
end