class Scorpio::Request

Constants

FALLBACK_CONTENT_TYPE
SUPPORTED_REQUEST_MEDIA_TYPES

Attributes

operation[R]

@return [Scorpio::OpenAPI::Operation]

Public Class Methods

best_media_type(media_types) click to toggle source
# File lib/scorpio/request.rb, line 6
def self.best_media_type(media_types)
  if media_types.size == 1
    media_types.first
  else
    SUPPORTED_REQUEST_MEDIA_TYPES.detect { |mt| media_types.include?(mt) }
  end
end
new(operation, configuration = {}) { |self| ... } click to toggle source

@param operation [Scorpio::OpenAPI::Operation] @param configuration [#to_hash] a hash keyed with configurable attributes for

the request - instance methods of Scorpio::Request::Configurables, whose values
will be assigned for those attributes.
# File lib/scorpio/request.rb, line 118
def initialize(operation, configuration = {}, &b)
  @operation = operation

  configuration = JSI.stringify_symbol_keys(configuration)
  params_set = Set.new # the set of params that have been set
  # do the Configurables first
  configuration.each do |name, value|
    if Configurables.public_method_defined?("#{name}=")
      Configurables.instance_method("#{name}=").bind(self).call(value)
      params_set << name
    end
  end
  # then do other top-level params
  configuration.reject { |name, _| params_set.include?(name) }.each do |name, value|
    param = param_for(name) || raise(ArgumentError, "unrecognized configuration value passed: #{name.inspect}")
    set_param_from(param['in'], param['name'], value)
  end

  extend operation.request_accessor_module

  if block_given?
    yield self
  end
end

Public Instance Methods

content_type() click to toggle source

@return [::Ur::ContentType] Content-Type for this request, taken from request headers if

present, or the request media_type.
# File lib/scorpio/request.rb, line 204
def content_type
  content_type_header || (media_type ? ::Ur::ContentType.new(media_type) : nil)
end
content_type_header() click to toggle source

@return [::Ur::ContentType] the value of the request Content-Type header

# File lib/scorpio/request.rb, line 195
def content_type_header
  headers.each do |k, v|
    return ::Ur::ContentType.new(v) if k =~ /\Acontent[-_]type\z/i
  end
  nil
end
each_page_ur(next_page: , raise_on_http_error: true) { |page_ur| ... } click to toggle source

todo make a proper iterator interface @param next_page [#call] a callable which will take a parameter `page_ur`, which is a {Scorpio::Ur},

and must result in an Ur representing the next page, which will be yielded to the block.

@yield [Scorpio::Ur] yields the first page, and each subsequent result of calls to `next_page` until

that results in nil

@return [void]

# File lib/scorpio/request.rb, line 359
def each_page_ur(next_page: , raise_on_http_error: true)
  return to_enum(__method__, next_page: next_page, raise_on_http_error: raise_on_http_error) unless block_given?
  page_ur = run_ur
  while page_ur
    page_ur.raise_on_http_error if raise_on_http_error
    yield page_ur
    page_ur = next_page.call(page_ur)
  end
  nil
end
faraday_connection(yield_ur = nil) click to toggle source

builds a Faraday connection with this Request's faraday_builder and faraday_adapter. passes a given proc yield_ur to middleware to yield an Ur for requests made with the connection.

@param yield_ur [Proc] @return [::Faraday::Connection]

# File lib/scorpio/request.rb, line 218
def faraday_connection(yield_ur = nil)
  Faraday.new do |faraday_connection|
    faraday_builder.call(faraday_connection)
    if yield_ur
      -> { ::Ur::Faraday }.() # autoload trigger

      faraday_connection.response(:yield_ur, schemas: Set[Scorpio::Ur.schema], logger: self.logger, &yield_ur)
    end
    faraday_connection.adapter(*faraday_adapter)
  end
end
get_param(name) click to toggle source

@param name [String, Symbol] the 'name' property of one applicable parameter @return [Object] the value of the named parameter on this request @raise [Scorpio::AmbiguousParameter] if more than one parameter has the given name

# File lib/scorpio/request.rb, line 245
def get_param(name)
  param = param_for!(name)
  get_param_from(param['in'], param['name'])
end
get_param_from(param_in, name) click to toggle source

@param in [String, Symbol] one of 'path', 'query', 'header', or 'cookie' - where to apply the named value @param name [String, Symbol] the parameter name @return [Object] the value of the named parameter on this request @raise [ArgumentError] invalid 'in' parameter @raise [NotImplementedError] cookies aren't implemented

# File lib/scorpio/request.rb, line 300
def get_param_from(param_in, name)
  if param_in == 'path'
    path_params[name]
  elsif param_in == 'query'
    query_params ? query_params[name] : nil
  elsif param_in == 'header'
    _, value = headers.detect { |headername, _| headername.downcase == name.downcase }
    value
  elsif param_in == 'cookie'
    raise(NotImplementedError, "cookies not implemented: #{name.inspect}")
  else
    raise(ArgumentError, "cannot get param from param_in = #{param_in.inspect} (name: #{name.pretty_inspect.chomp})")
  end
end
http_method() click to toggle source

@return [Symbol] the http method for this request - :get, :post, etc.

# File lib/scorpio/request.rb, line 152
def http_method
  operation.http_method.downcase.to_sym
end
openapi_document() click to toggle source

@return [Scorpio::OpenAPI::Document]

# File lib/scorpio/request.rb, line 147
def openapi_document
  operation.openapi_document
end
param_for(name) click to toggle source

@param name [String, Symbol] the 'name' property of one applicable parameter @return [#to_hash, nil]

# File lib/scorpio/request.rb, line 252
def param_for(name)
  name = name.to_s if name.is_a?(Symbol)
  params = operation.inferred_parameters.select { |p| p['name'] == name }
  if params.size == 1
    params.first
  elsif params.size == 0
    nil
  else
    raise(AmbiguousParameter.new(
      "There are multiple parameters for #{name}. matched parameters were: #{params.pretty_inspect.chomp}"
    ).tap { |e| e.name = name })
  end
end
param_for!(name) click to toggle source

@param name [String, Symbol] the name or {in}.{name} (e.g. “query.search”) for the applicable parameter. @return [#to_hash]

# File lib/scorpio/request.rb, line 268
def param_for!(name)
  param_for(name) || raise(ParameterError, "There is no parameter named #{name} on operation #{operation.human_id}:\n#{operation.pretty_inspect.chomp}")
end
path() click to toggle source

@return [Addressable::URI] an Addressable::URI containing only the path to append to

the base_url for this request
# File lib/scorpio/request.rb, line 164
def path
  path_params = JSI.stringify_symbol_keys(self.path_params)
  missing_variables = path_template.variables - path_params.keys
  if missing_variables.any?
    raise(ArgumentError, "path #{operation.path_template_str} for operation #{operation.human_id} requires path_params " +
      "which were missing: #{missing_variables.inspect}")
  end
  empty_variables = path_template.variables.select { |v| path_params[v].to_s.empty? }
  if empty_variables.any?
    raise(ArgumentError, "path #{operation.path_template_str} for operation #{operation.human_id} requires path_params " +
      "which were empty: #{empty_variables.inspect}")
  end

  path_template.expand(path_params).tap do |path|
    if query_params
      path.query_values = query_params
    end
  end
end
path_template() click to toggle source

@return [Addressable::Template] the template for the request's path, to be expanded

with path_params and appended to the request's base_url
# File lib/scorpio/request.rb, line 158
def path_template
  operation.path_template
end
request_schema(media_type: self.media_type) click to toggle source

@return [::JSI::Schema]

# File lib/scorpio/request.rb, line 209
def request_schema(media_type: self.media_type)
  operation.request_schema(media_type: media_type)
end
run() click to toggle source

runs this request. returns the response body object - that is, the response body parsed according to an understood media type, and instantiated with the applicable response schema if one is specified. see Scorpio::Response#body_object for more detail.

@raise [Scorpio::HTTPError] if the request returns a 4xx or 5xx status, the appropriate

error is raised - see Scorpio::HTTPErrors
# File lib/scorpio/request.rb, line 347
def run
  ur = run_ur
  ur.raise_on_http_error
  ur.response.body_object
end
run_ur() click to toggle source

runs this request and returns the full representation of the request that was run and its response.

@return [Scorpio::Ur]

# File lib/scorpio/request.rb, line 318
def run_ur
  headers = {}
  if user_agent
    headers['User-Agent'] = user_agent
  end
  if !content_type_header
    if media_type
      headers['Content-Type'] = media_type
    else
      # I'd rather not have a default content-type, but if none is set then the HTTP adapter sets this to
      # application/x-www-form-urlencoded and issues a warning about it.
      headers['Content-Type'] = FALLBACK_CONTENT_TYPE
    end
  end
  if self.headers
    headers.update(self.headers)
  end
  ur = nil
  faraday_connection(-> (yur) { ur = yur }).run_request(http_method, url, body, headers)
  ur.scorpio_request = self
  ur
end
set_param(name, value) click to toggle source

if there is only one parameter with the given name, of any sort, this will set it.

@param name [String, Symbol] the 'name' property of one applicable parameter @param value [Object] the applicable parameter will be applied to the request with the given value. @return [Object] echoes the value param @raise [Scorpio::AmbiguousParameter] if more than one parameter has the given name

# File lib/scorpio/request.rb, line 236
def set_param(name, value)
  param = param_for!(name)
  set_param_from(param['in'], param['name'], value)
  value
end
set_param_from(param_in, name, value) click to toggle source

@param in [String, Symbol] one of 'path', 'query', 'header', or 'cookie' - where to apply the named value @param name [String, Symbol] the parameter name to apply the value to @param value [Object] the value @return [Object] echoes the value param @raise [ArgumentError] invalid 'in' parameter @raise [NotImplementedError] cookies aren't implemented

# File lib/scorpio/request.rb, line 278
def set_param_from(param_in, name, value)
  param_in = param_in.to_s if param_in.is_a?(Symbol)
  name = name.to_s if name.is_a?(Symbol)
  if param_in == 'path'
    self.path_params = self.path_params.merge(name => value)
  elsif param_in == 'query'
    self.query_params = (self.query_params || {}).merge(name => value)
  elsif param_in == 'header'
    self.headers = self.headers.merge(name => value)
  elsif param_in == 'cookie'
    raise(NotImplementedError, "cookies not implemented: #{name.inspect} => #{value.inspect}")
  else
    raise(ArgumentError, "cannot set param from param_in = #{param_in.inspect} (name: #{name.pretty_inspect.chomp}, value: #{value.pretty_inspect.chomp})")
  end
  value
end
url() click to toggle source

@return [Addressable::URI] the full URL for this request

# File lib/scorpio/request.rb, line 185
def url
  unless base_url
    raise(ArgumentError, "no base_url has been specified for request")
  end
  # we do not use Addressable::URI#join as the paths should just be concatenated, not resolved.
  # we use File.join just to deal with consecutive slashes.
  Addressable::URI.parse(File.join(base_url, path))
end