Class: Unipept::Commands::ApiRunner

Inherits:
Cri::CommandRunner
  • Object
show all
Defined in:
lib/commands/unipept/api_runner.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args, opts, cmd) ⇒ ApiRunner

Returns a new instance of ApiRunner.



7
8
9
10
11
12
13
14
15
# File 'lib/commands/unipept/api_runner.rb', line 7

def initialize(args, opts, cmd)
  super
  @configuration = Unipept::Configuration.new

  @host = host
  @user_agent = "Unipept CLI - unipept #{Unipept::VERSION}"
  @url = "#{@host}/api/v2/#{cmd.name}.json"
  @fasta = false
end

Instance Attribute Details

#configurationObject (readonly)

Returns the value of attribute configuration.



5
6
7
# File 'lib/commands/unipept/api_runner.rb', line 5

def configuration
  @configuration
end

#urlObject (readonly)

Returns the value of attribute url.



5
6
7
# File 'lib/commands/unipept/api_runner.rb', line 5

def url
  @url
end

#user_agentObject (readonly)

Returns the value of attribute user_agent.



5
6
7
# File 'lib/commands/unipept/api_runner.rb', line 5

def user_agent
  @user_agent
end

Instance Method Details

#batch_iteratorObject

Returns a new batch_iterator based on the batch_size



67
68
69
# File 'lib/commands/unipept/api_runner.rb', line 67

def batch_iterator
  Unipept::BatchIterator.new(batch_size)
end

#batch_sizeObject

returns the effective batch_size of a command



53
54
55
56
57
58
59
# File 'lib/commands/unipept/api_runner.rb', line 53

def batch_size
  if options[:batch]
    options[:batch].to_i
  else
    default_batch_size
  end
end

#concurrent_requestsObject



71
72
73
74
75
76
77
# File 'lib/commands/unipept/api_runner.rb', line 71

def concurrent_requests
  if options[:parallel]
    options[:parallel].to_i
  else
    10
  end
end

#construct_request_body(input) ⇒ Object

Constructs a request body (a Hash) for set of input strings, using the options supplied by the user.



99
100
101
102
103
104
105
# File 'lib/commands/unipept/api_runner.rb', line 99

def construct_request_body(input)
  names = selected_fields.empty? || selected_fields.any? { |f| f.to_s.include?('name') || f.to_s.include?('.*$') }
  { input: input,
    equate_il: options[:equate] == true,
    extra: options[:all] == true,
    names: options[:all] == true && names }
end

#default_batch_sizeObject

Returns the default default_batch_size of a command.

Raises:

  • (NotImplementedError)


48
49
50
# File 'lib/commands/unipept/api_runner.rb', line 48

def default_batch_size
  raise NotImplementedError, 'This must be implemented in a subclass.'
end

#formatterObject

Returns a formatter, based on the format specified in the options



93
94
95
# File 'lib/commands/unipept/api_runner.rb', line 93

def formatter
  @formatter ||= Unipept::Formatter.new_for_format(options[:format])
end

#hostObject

Returns the host. If a value is defined by both an option and the config file, the value of the option is used.



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/commands/unipept/api_runner.rb', line 19

def host
  # find host in opts first
  host = options[:host] || @configuration['host']
  host = 'http://api.unipept.ugent.be' if host.nil? || host.empty?

  # add http:// if needed
  if host.start_with?('http://', 'https://')
    host
  else
    "http://#{host}"
  end
end

#input_iteratorObject

Returns an input iterator to use for the request.

  • if arguments are given, uses arguments

  • if the input file option is given, uses file input

  • if none of the previous are given, uses stdin



36
37
38
39
40
41
# File 'lib/commands/unipept/api_runner.rb', line 36

def input_iterator
  return arguments.each unless arguments.empty?
  return File.foreach(options[:input]) if options[:input]

  $stdin.each_line
end

#output_writerObject



43
44
45
# File 'lib/commands/unipept/api_runner.rb', line 43

def output_writer
  @output_writer ||= OutputWriter.new(options[:output])
end

#queue_sizeObject



79
80
81
# File 'lib/commands/unipept/api_runner.rb', line 79

def queue_size
  concurrent_requests * 20
end

#required_fieldsObject

returns the required fields to do any mapping



62
63
64
# File 'lib/commands/unipept/api_runner.rb', line 62

def required_fields
  []
end

#runObject

Runs the command



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/commands/unipept/api_runner.rb', line 108

def run
  ServerMessage.new(@host).print unless options[:quiet]
  hydra = Typhoeus::Hydra.new(max_concurrency: concurrent_requests)
  batch_order = Unipept::BatchOrder.new
  last_id = 0

  # puts input_iterator.inspect

  batch_iterator.iterate(input_iterator) do |input_slice, batch_id, fasta_mapper|
    last_id = batch_id
    @fasta = !fasta_mapper.nil?
    request = ::RetryableTyphoeus::Request.new(
      @url,
      method: :post,
      body: construct_request_body(input_slice),
      accept_encoding: 'gzip',
      followlocation: true,
      postredir: :post_all,
      headers: { 'User-Agent' => @user_agent }
    )

    request.on_complete do |resp|
      block = handle_response(resp, batch_id, fasta_mapper)
      batch_order.wait(batch_id, &block)
    end

    hydra.queue request
    hydra.run if (batch_id % queue_size).zero?
  end

  hydra.run
  batch_order.wait(last_id + 1) { output_writer.write_line formatter.footer }
end

#save_error(message) ⇒ Object

Saves an error to a new file in the .unipept directory in the users home directory.



144
145
146
147
148
149
# File 'lib/commands/unipept/api_runner.rb', line 144

def save_error(message)
  path = error_file_path
  FileUtils.mkdir_p File.dirname(path)
  File.write(path, message)
  warn "API request failed! log can be found in #{path}"
end

#selected_fieldsObject

Returns an array of regular expressions containing all the selected fields



84
85
86
87
88
89
90
# File 'lib/commands/unipept/api_runner.rb', line 84

def selected_fields
  return @selected_fields unless @selected_fields.nil?

  fields = [*options[:select]].map { |f| f.split(',') }.flatten
  fields.concat(required_fields) if @fasta && !fields.empty?
  @selected_fields = fields.map { |f| glob_to_regex(f) }
end