Class: Crunchbase::API

Inherits:
Object
  • Object
show all
Defined in:
lib/crunchbase/api.rb

Constant Summary collapse

SUPPORTED_ENTITIES =
{
  'categories' => Model::Category,
  'organizations' => Model::OrganizationSummary,
  'organization' => Model::Organization,
  'people' => Model::PersonSummary,
  'person' => Model::Person,
  'products' => Model::ProductSummary,
  'ipos' => Model::Ipo,
  'funding_rounds' => Model::FundingRound,
  'funding-rounds' => Model::FundingRound,
  'acquisitions' => Model::Acquisition,
  'locations' => Model::Location,
  'offices' => Model::Office,
  'customers' => Model::Customer,
  'degrees' => Model::Degree,
  # 'experience' => nil,
  'primary_affiliation' => Model::PrimaryAffiliation,
  'videos' => Model::Video,
  'founded_companies' => Model::FoundedCompany,
  'primary_location' => Model::PrimaryLocation,
  'advisor_at' => Model::AdvisoryRole,
  'investors' => Model::Organization
}.freeze
RESOURCE_NAME =

Must be overridden in subclasses

'undefined'.freeze
RESOURCE_LIST =
'undefineds'.freeze
ORDER_CREATED_AT_ASC =
'created_at ASC'.freeze
ORDER_CREATED_AT_DESC =
'created_at DESC'.freeze
ORDER_UPDATED_AT_ASC =
'updated_at ASC'.freeze
ORDER_UPDATED_AT_DESC =
'updated_at DESC'.freeze

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.debugObject

Returns the value of attribute debug.



54
55
56
# File 'lib/crunchbase/api.rb', line 54

def debug
  @debug
end

.keyObject

Necessary



53
54
55
# File 'lib/crunchbase/api.rb', line 53

def key
  @key
end

.redirect_limitObject

Returns the value of attribute redirect_limit.



54
55
56
# File 'lib/crunchbase/api.rb', line 54

def redirect_limit
  @redirect_limit
end

.timeoutObject

Returns the value of attribute timeout.



54
55
56
# File 'lib/crunchbase/api.rb', line 54

def timeout
  @timeout
end

Class Method Details

.api_urlObject



56
57
58
# File 'lib/crunchbase/api.rb', line 56

def api_url
  [API_BASE_URL, '/', API_VERSION, '/'].join
end

.batch_search(requests_array) ⇒ Object

Fetches URI for the search interface and adapts the payload.



89
90
91
92
93
94
# File 'lib/crunchbase/api.rb', line 89

def batch_search(requests_array)
  uri = "#{api_url}batch"
  request_body = { requests: requests_array }

  post_json_response(uri, request_body)
end

.collect_parameters(options) ⇒ Object



106
107
108
# File 'lib/crunchbase/api.rb', line 106

def collect_parameters(options)
  options.map { |k, v| "#{k}=#{v}" }.join('&')
end

.debugging(uri) ⇒ Object



225
226
227
228
229
230
231
# File 'lib/crunchbase/api.rb', line 225

def debugging(uri)
  return unless debug

  puts '*' * 140
  puts "***  #{uri}  ***"
  puts '*' * 140
end

.fetch(permalink, kclass_name) ⇒ Object

Fetches URI for the permalink interface.



74
75
76
# File 'lib/crunchbase/api.rb', line 74

def fetch(permalink, kclass_name)
  get_json_response(api_url + "#{kclass_name}/#{permalink}")
end

.funding_rounds_lists(permalink, category, options) ⇒ Object



118
119
120
# File 'lib/crunchbase/api.rb', line 118

def funding_rounds_lists(permalink, category, options)
  lists_for_category('funding-rounds', permalink, category, options)
end

.get_json_response(uri) ⇒ Object

Gets specified URI, then parses the returned JSON. Raises Timeout error

if request time exceeds set limit. Raises Exception if returned
JSON contains an error.

Raises:



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/crunchbase/api.rb', line 135

def get_json_response(uri)
  raise Exception, 'User key required, visit https://data.crunchbase.com/v3.1/docs' unless @key

  uri += "#{uri =~ /\?/ ? '&' : '?'}user_key=#{@key}"

  resp = Timeout.timeout(@timeout) do
    get_url_following_redirects(uri, @redirect_limit)
  end

  response = parser.parse(resp)
  response = response[0] if response.is_a?(Array)
  raise Exception, response['message'] unless response['message'].nil?

  response['data']
end

.get_url_following_redirects(uri_str, limit = 10) ⇒ Object

Performs actual HTTP requests, recursively if a redirect response is encountered. Will raise HTTP error if response is not 200, 404, or 3xx.

Raises:



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/crunchbase/api.rb', line 153

def get_url_following_redirects(uri_str, limit = 10)
  raise Exception, 'HTTP redirect too deep' if limit.zero?

  uri = URI.parse(URI.encode(uri_str))

  debugging(uri)

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true if uri.scheme == 'https'
  response = http.start do |h|
    h.request Net::HTTP::Get.new(uri.request_uri, 'User-Agent' => 'crunchbase-ruby-library')
  end

  case response
  when Net::HTTPSuccess, Net::HTTPNotFound, Net::HTTPInternalServerError, Net::HTTPConflict
    response.body
  when Net::HTTPRedirection
    get_url_following_redirects(response['location'], limit - 1)
  else
    response.error!
  end
end

.list(options, resource_list) ⇒ Object

Fetches URI for the search interface.



97
98
99
100
101
102
103
104
# File 'lib/crunchbase/api.rb', line 97

def list(options, resource_list)
  options[:page]  = 1 if options[:page].nil?
  model_name      = options.delete(:model_name) || SUPPORTED_ENTITIES[resource_list]

  uri = api_url + "#{resource_list}?" + collect_parameters(options)

  Model::Search.new options, get_json_response(uri), model_name
end

.lists_for_category(classify_name, permalink, category, options) ⇒ Object



122
123
124
125
126
127
128
129
130
# File 'lib/crunchbase/api.rb', line 122

def lists_for_category(classify_name, permalink, category, options)
  options[:page]  = 1 if options[:page].nil?
  options[:order] = ORDER_CREATED_AT_ASC if options[:order].nil?
  model_name      = options.delete(:model_name)

  uri = api_url + "#{classify_name}/#{permalink}/#{category}?#{collect_parameters(options)}"

  Model::Search.new options, get_json_response(uri), model_name
end

.organization_lists(permalink, category, options) ⇒ Object



110
111
112
# File 'lib/crunchbase/api.rb', line 110

def organization_lists(permalink, category, options)
  lists_for_category('organizations', permalink, category, options)
end

.parserObject

Returns the JSON parser, whether that’s an instance of Yajl or JSON



67
68
69
70
71
# File 'lib/crunchbase/api.rb', line 67

def parser
  return Yajl::Parser if defined?(Yajl)

  JSON
end

.person_lists(permalink, category, options) ⇒ Object



114
115
116
# File 'lib/crunchbase/api.rb', line 114

def person_lists(permalink, category, options)
  lists_for_category('people', permalink, category, options)
end

.post_json_response(uri, request_body) ⇒ Object

Gets specified URI, and the object for request’s body, then parses the returned JSON. Raises Timeout error

if request time exceeds set limit. Raises Exception if returned
JSON contains an error.

Raises:



179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/crunchbase/api.rb', line 179

def post_json_response(uri, request_body)
  raise Exception, 'User key required, visit https://data.crunchbase.com/v3.1/docs' unless @key

  body_string = request_body.to_json

  resp = Timeout.timeout(@timeout) do
    post_url_following_redirects(uri, body_string, @redirect_limit)
  end

  response = parser.parse(resp)
  raise Exception, response['message'] unless response['message'].nil?

  response['data']
end

.post_url_following_redirects(uri_str, body_string, limit = 10) ⇒ Object

Performs actual HTTP requests, recursively if a redirect response is encountered. Will raise HTTP error if response is not 200, 404, or 3xx.

Raises:



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/crunchbase/api.rb', line 196

def post_url_following_redirects(uri_str, body_string, limit = 10)
  raise Exception, 'HTTP redirect too deep' if limit.zero?

  uri = URI.parse(URI.encode(uri_str))

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true if uri.scheme == 'https'

  req = Net::HTTP::Post.new(uri.request_uri)
  req.add_field('User-Agent', 'crunchbase-ruby-library')
  req.add_field('Content-Type', 'application/json')
  req.add_field('X-Cb-User-Key', @key)

  req.body = body_string

  response = http.start do |h|
    h.request req
  end

  case response
  when Net::HTTPSuccess, Net::HTTPNotFound, Net::HTTPInternalServerError, Net::HTTPConflict
    response.body
  when Net::HTTPRedirection
    post_url_following_redirects(response['location'], limit - 1)
  else
    response.error!
  end
end

.search(options, resource_list) ⇒ Object

Fetches URI for the search interface.



79
80
81
82
83
84
85
86
# File 'lib/crunchbase/api.rb', line 79

def search(options, resource_list)
  options[:page] = 1 if options[:page].nil?
  options[:order] = ORDER_CREATED_AT_ASC if options[:order].nil?

  uri = api_url + "#{resource_list}?" + collect_parameters(options)

  get_json_response(uri)
end

.single_entity(permalink, entity_name) ⇒ Object

Raises:

  • (CrunchException)


60
61
62
63
64
# File 'lib/crunchbase/api.rb', line 60

def single_entity(permalink, entity_name)
  raise CrunchException, 'Unsupported Entity Type' unless SUPPORTED_ENTITIES.keys.include?(entity_name)

  fetch(permalink, entity_name)
end