Method: DatadogAPIClient::APIClient#call_api

Defined in:
lib/datadog_api_client/api_client.rb

#call_api(http_method, path, opts = {}) ⇒ Array<(Object, Integer, Hash)>

Call an API with given options.

Returns:

  • (Array<(Object, Integer, Hash)>)

    an array of 3 elements: the data deserialized from response body (could be nil), response status code and response headers.

[View source]

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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
# File 'lib/datadog_api_client/api_client.rb', line 56

def call_api(http_method, path, opts = {})
  request = build_request(http_method, path, opts)
  attempt = 0
  loop do
    if opts[:stream_body]
      tempfile = nil
      encoding = nil

      response = request.perform do | chunk |
        unless tempfile
          content_disposition = chunk.http_response.header['Content-Disposition']
          if content_disposition && content_disposition =~ /filename=/i
            filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
            prefix = sanitize_filename(filename)
          else
            prefix = 'download-'
          end
          prefix = prefix + '-' unless prefix.end_with?('-')
          unless encoding
            encoding = chunk.encoding
          end
          tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
          @tempfile = tempfile
        end
        chunk.force_encoding(encoding)
        tempfile.write(chunk)
      end
      if tempfile
        tempfile.close
        @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
                          "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
                          "will be deleted automatically with GC. It's also recommended to delete the temp file "\
                          "explicitly with `tempfile.delete`"
      end
    else
      response = request.perform
    end

    if @config.debugging
      @config.logger.debug "HTTP response header\n#{response.headers}\n"
      @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
    end

    unless response.success?
      if response.request_timeout?
        fail APIError.new('Connection timed out')
      elsif response.code == 0
        # Errors from libcurl will be made visible here
        fail APIError.new(:code => 0,
                          :message => response.return_message)
      else
        body = response.body
        if response.headers['Content-Encoding'].eql?('gzip') && !(body.nil? || body.empty?) then
          gzip = Zlib::Inflate.new(Zlib::MAX_WBITS + 16)
          body = gzip.inflate(body)
          gzip.close
        end
        if should_retry(attempt, @config.max_retries, response.code, @config.enable_retry)
          sleep calculate_retry_interval(response, @config.backoff_base, @config.backoff_multiplier, attempt, @config.timeout)
          attempt = attempt + 1
          next
        else
          fail APIError.new(:code => response.code,
            :response_headers => response.headers,
            :response_body => body),
          response.message
        end
      end
    end

    if opts[:return_type]
      data = deserialize(opts[:api_version], response, opts[:return_type])
    else
      data = nil
    end
    return data, response.code, response.headers
  end
end