Class: Contentful::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/contentful/client.rb

Overview

The client object is initialized with a space and a key and then used for querying resources from this space. See README for details

Constant Summary collapse

DEFAULT_CONFIGURATION =

Default configuration for Contentful::Client

{
  secure: true,
  raise_errors: true,
  raise_for_empty_fields: true,
  dynamic_entries: :manual,
  api_url: 'cdn.contentful.com',
  api_version: 1,
  environment: 'master',
  authentication_mechanism: :header,
  resource_builder: ResourceBuilder,
  resource_mapping: {},
  entry_mapping: {},
  default_locale: 'en-US',
  raw_mode: false,
  gzip_encoded: true,
  logger: false,
  proxy_host: nil,
  proxy_username: nil,
  proxy_password: nil,
  proxy_port: nil,
  timeout_connect: nil,
  timeout_read: nil,
  timeout_write: nil,
  max_rate_limit_retries: 1,
  max_rate_limit_wait: 60,
  max_include_resolution_depth: 20,
  use_camel_case: false,
  application_name: nil,
  application_version: nil,
  integration_name: nil,
  integration_version: nil
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(given_configuration = {}) ⇒ Client

Returns a new instance of Client.

Parameters:

  • given_configuration (Hash) (defaults to: {})

Options Hash (given_configuration):

  • :space (String)

    Required

  • :access_token (String)

    Required

  • :api_url (String)

    Modifying this to ‘preview.contentful.com’ gives you access to our Preview API

  • :api_version (String)
  • :default_locale (String)
  • :proxy_host (String)
  • :proxy_username (String)
  • :proxy_password (String)
  • :proxy_port (Number)
  • :timeout_read (Number)
  • :timeout_write (Number)
  • :timeout_connect (Number)
  • :max_rate_limit_retries (Number)
  • :max_rate_limit_wait (Number)
  • :max_include_resolution_depth (Number)
  • :use_camel_case (Boolean)
  • :gzip_encoded (Boolean)
  • :raw_mode (Boolean)
  • :logger (false, ::Logger)
  • :log_level (::Logger::DEBUG, ::Logger::INFO, ::Logger::WARN, ::Logger::ERROR)
  • :raise_errors (Boolean)
  • :raise_for_empty_fields (Boolean)
  • :dynamic_entries (::Array<String>)
  • :resource_mapping (::Hash<String, Contentful::Resource>)
  • :entry_mapping (::Hash<String, Contentful::Resource>)
  • :application_name (String)
  • :application_version (String)
  • :integration_name (String)
  • :integration_version (String)

See Also:

  • https://github.com/contentful/contentful.rb#client-configuration-options


95
96
97
98
99
100
101
102
# File 'lib/contentful/client.rb', line 95

def initialize(given_configuration = {})
  @configuration = default_configuration.merge(given_configuration)
  normalize_configuration!
  validate_configuration!
  setup_logger

  update_dynamic_entry_cache! if configuration[:dynamic_entries] == :auto
end

Instance Attribute Details

#configurationObject (readonly)

Returns the value of attribute configuration.



50
51
52
# File 'lib/contentful/client.rb', line 50

def configuration
  @configuration
end

#loggerObject (readonly)

Returns the value of attribute logger.



50
51
52
# File 'lib/contentful/client.rb', line 50

def logger
  @logger
end

#proxyObject (readonly)

Returns the value of attribute proxy.



50
51
52
# File 'lib/contentful/client.rb', line 50

def proxy
  @proxy
end

Class Method Details

.get_http(url, query, headers = {}, proxy = {}, timeout = {}) ⇒ Object

Wraps the actual HTTP request via proxy



54
55
56
57
58
59
60
61
62
# File 'lib/contentful/client.rb', line 54

def self.get_http(url, query, headers = {}, proxy = {}, timeout = {})
  http = HTTP[headers]
  http = http.timeout(timeout) if timeout.any?
  if proxy[:host]
    http.via(proxy[:host], proxy[:port], proxy[:username], proxy[:password]).get(url, params: query)
  else
    http.get(url, params: query)
  end
end

Instance Method Details

#app_infoObject

Returns the X-Contentful-User-Agent app data



246
247
248
# File 'lib/contentful/client.rb', line 246

def app_info
  { name: configuration[:application_name], version: configuration[:application_version] }
end

#asset(id, query = {}) ⇒ Contentful::Asset

Gets a specific asset

Parameters:

  • id (String)
  • query (Hash) (defaults to: {})

Returns:



195
196
197
# File 'lib/contentful/client.rb', line 195

def asset(id, query = {})
  Request.new(self, environment_url('/assets'), query, id).get
end

#assets(query = {}) ⇒ Contentful::Array<Contentful::Asset>

Gets a collection of assets

Parameters:

  • query (Hash) (defaults to: {})

Returns:



204
205
206
207
# File 'lib/contentful/client.rb', line 204

def assets(query = {})
  normalize_select!(query)
  Request.new(self, environment_url('/assets'), query).get
end

#base_urlObject

Returns the base url for all of the client’s requests



220
221
222
# File 'lib/contentful/client.rb', line 220

def base_url
  "http#{configuration[:secure] ? 's' : ''}://#{configuration[:api_url]}/spaces/#{configuration[:space]}"
end

#content_type(id, query = {}) ⇒ Contentful::ContentType

Gets a specific content type

Parameters:

  • id (String)
  • query (Hash) (defaults to: {})

Returns:



150
151
152
# File 'lib/contentful/client.rb', line 150

def content_type(id, query = {})
  Request.new(self, environment_url('/content_types'), query, id).get
end

#content_types(query = {}) ⇒ Contentful::Array<Contentful::ContentType>

Gets a collection of content types

Parameters:

  • query (Hash) (defaults to: {})

Returns:



159
160
161
# File 'lib/contentful/client.rb', line 159

def content_types(query = {})
  Request.new(self, environment_url('/content_types'), query).get
end

#contentful_user_agentObject

Returns the X-Contentful-User-Agent



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/contentful/client.rb', line 275

def contentful_user_agent
  header = {
    'sdk' => sdk_info,
    'app' => app_info,
    'integration' => integration_info,
    'platform' => platform_info,
    'os' => os_info
  }

  result = []
  header.each do |key, values|
    next unless values[:name]
    result << format_user_agent_header(key, values)
  end
  result.join(' ')
end

#default_configurationObject

Returns the default configuration



131
132
133
# File 'lib/contentful/client.rb', line 131

def default_configuration
  DEFAULT_CONFIGURATION.dup
end

#do_build_resource(response) ⇒ Object

Runs Resource Builder



382
383
384
385
386
387
388
389
390
391
392
# File 'lib/contentful/client.rb', line 382

def do_build_resource(response)
  logger.debug(response: response) if logger
  configuration[:resource_builder].new(
    response.object,
    configuration.merge(endpoint: response.request.endpoint),
    (response.request.query || {}).fetch(:locale, nil) == '*',
    0,
    [],
    response.request.query || {}
  ).run
end

#entries(query = {}) ⇒ Contentful::Array<Contentful::Entry>

Gets a collection of entries

Parameters:

  • query (Hash) (defaults to: {})

Returns:



184
185
186
187
# File 'lib/contentful/client.rb', line 184

def entries(query = {})
  normalize_select!(query)
  Request.new(self, environment_url('/entries'), query).get
end

#entry(id, query = {}) ⇒ Contentful::Entry

Gets a specific entry

Parameters:

  • id (String)
  • query (Hash) (defaults to: {})

Returns:



169
170
171
172
173
174
175
176
177
# File 'lib/contentful/client.rb', line 169

def entry(id, query = {})
  normalize_select!(query)
  query['sys.id'] = id
  entries = Request.new(self, environment_url('/entries'), query).get

  return entries if configuration[:raw_mode]

  entries.first
end

#environment_url(path) ⇒ Object

Returns the url aware of the currently selected environment



226
227
228
# File 'lib/contentful/client.rb', line 226

def environment_url(path)
  "/environments/#{configuration[:environment]}#{path}"
end

#fail_response(response) ⇒ Object



354
355
356
357
# File 'lib/contentful/client.rb', line 354

def fail_response(response)
  fail response.object if configuration[:raise_errors]
  response.object
end

#format_user_agent_header(key, values) ⇒ Object

Returns the formatted part of the X-Contentful-User-Agent header



232
233
234
235
236
# File 'lib/contentful/client.rb', line 232

def format_user_agent_header(key, values)
  header = "#{key} #{values[:name]}"
  header = "#{header}/#{values[:version]}" if values[:version]
  "#{header};"
end

#get(request, build_resource = true) ⇒ Object

Get a Contentful::Request object Set second parameter to false to deactivate Resource building and return Response objects instead



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/contentful/client.rb', line 316

def get(request, build_resource = true)
  retries_left = configuration[:max_rate_limit_retries]
  result = nil
  begin
    response = run_request(request)

    return response if !build_resource || configuration[:raw_mode]

    return fail_response(response) if response.status != :ok

    result = do_build_resource(response)
  rescue UnparsableResource => error
    raise error if configuration[:raise_errors]
    return error
  rescue Contentful::RateLimitExceeded => rate_limit_error
    reset_time = rate_limit_error.reset_time.to_i
    if should_retry(retries_left, reset_time, configuration[:max_rate_limit_wait])
      retries_left -= 1
      logger.info(retry_message(retries_left, reset_time)) if logger
      sleep(reset_time * Random.new.rand(1.0..1.2))
      retry
    end

    raise
  end

  result
end

#integration_infoObject

Returns the X-Contentful-User-Agent integration data



252
253
254
# File 'lib/contentful/client.rb', line 252

def integration_info
  { name: configuration[:integration_name], version: configuration[:integration_version] }
end

#locales(query = {}) ⇒ Contentful::Array<Contentful::Locale>

Gets a collection of locales for the current environment

Parameters:

  • query (Hash) (defaults to: {})

Returns:



214
215
216
# File 'lib/contentful/client.rb', line 214

def locales(query = {})
  Request.new(self, environment_url('/locales'), query).get
end

#os_infoObject

Returns the X-Contentful-User-Agent os data



264
265
266
267
268
269
270
271
# File 'lib/contentful/client.rb', line 264

def os_info
  os_name = case ::RbConfig::CONFIG['host_os']
            when /(cygwin|mingw|mswin|windows)/i then 'Windows'
            when /(darwin|macruby|mac os)/i      then 'macOS'
            when /(linux|bsd|aix|solarix)/i      then 'Linux'
            end
  { name: os_name, version: Gem::Platform.local.version }
end

#platform_infoObject

Returns the X-Contentful-User-Agent platform data



258
259
260
# File 'lib/contentful/client.rb', line 258

def platform_info
  { name: 'ruby', version: RUBY_VERSION }
end

#proxy_paramsObject



111
112
113
114
115
116
117
118
# File 'lib/contentful/client.rb', line 111

def proxy_params
  {
    host: configuration[:proxy_host],
    port: configuration[:proxy_port],
    username: configuration[:proxy_username],
    password: configuration[:proxy_password]
  }
end

#register_dynamic_entry(key, klass) ⇒ Object

Use this method to manually register a dynamic entry See examples/dynamic_entries.rb



407
408
409
# File 'lib/contentful/client.rb', line 407

def register_dynamic_entry(key, klass)
  ContentTypeCache.cache_set(configuration[:space], key, klass)
end

#request_headersObject

Returns the headers used for the HTTP requests



294
295
296
297
298
299
300
# File 'lib/contentful/client.rb', line 294

def request_headers
  headers = { 'X-Contentful-User-Agent' => contentful_user_agent }
  headers['Authorization'] = "Bearer #{configuration[:access_token]}" if configuration[:authentication_mechanism] == :header
  headers['Content-Type'] = "application/vnd.contentful.delivery.v#{configuration[:api_version].to_i}+json" if configuration[:api_version]
  headers['Accept-Encoding'] = 'gzip' if configuration[:gzip_encoded]
  headers
end

#request_query(query) ⇒ Object

Patches a query hash with the client configurations for queries



304
305
306
307
308
309
# File 'lib/contentful/client.rb', line 304

def request_query(query)
  if configuration[:authentication_mechanism] == :query_string
    query['access_token'] = configuration[:access_token]
  end
  query
end

#retry_message(retries_left, reset_time) ⇒ Object



346
347
348
349
350
351
# File 'lib/contentful/client.rb', line 346

def retry_message(retries_left, reset_time)
  message = 'Contentful API Rate Limit Hit! '
  message += "Retrying - Retries left: #{retries_left}"
  message += "- Time until reset (seconds): #{reset_time}"
  message
end

#run_request(request) ⇒ Object

Runs request and parses Response



366
367
368
369
370
371
372
373
374
375
376
377
378
# File 'lib/contentful/client.rb', line 366

def run_request(request)
  url = request.absolute? ? request.url : base_url + request.url
  logger.info(request: { url: url, query: request.query, header: request_headers }) if logger
  Response.new(
    self.class.get_http(
      url,
      request_query(request.query),
      request_headers,
      proxy_params,
      timeout_params
    ), request
  )
end

#sdk_infoObject

Returns the X-Contentful-User-Agent sdk data



240
241
242
# File 'lib/contentful/client.rb', line 240

def sdk_info
  { name: 'contentful.rb', version: ::Contentful::VERSION }
end

#setup_loggerObject



105
106
107
108
# File 'lib/contentful/client.rb', line 105

def setup_logger
  @logger = configuration[:logger]
  logger.level = configuration[:log_level] if logger && configuration.key?(:log_level)
end

#should_retry(retries_left, reset_time, max_wait) ⇒ Object



360
361
362
# File 'lib/contentful/client.rb', line 360

def should_retry(retries_left, reset_time, max_wait)
  retries_left > 0 && max_wait > reset_time
end

#space(query = {}) ⇒ Contentful::Space

Gets the client’s space

Parameters:

  • query (Hash) (defaults to: {})

Returns:



140
141
142
# File 'lib/contentful/client.rb', line 140

def space(query = {})
  Request.new(self, '', query).get
end

#sync(options = { initial: true }) ⇒ Contentful::Sync

Note:

You will need to call #each_page or #first_page on it

Create a new synchronisation object

Parameters:

  • options (Hash, String) (defaults to: { initial: true })

    Options or Sync URL

Returns:



418
419
420
# File 'lib/contentful/client.rb', line 418

def sync(options = { initial: true })
  Sync.new(self, options)
end

#timeout_paramsObject



121
122
123
124
125
126
127
# File 'lib/contentful/client.rb', line 121

def timeout_params
  {
    connect: configuration[:timeout_connect],
    read: configuration[:timeout_read],
    write: configuration[:timeout_write]
  }.reject { |_, value| value.nil? }
end

#update_dynamic_entry_cache!Object

Use this method together with the client’s :dynamic_entries configuration. See README for details.



397
398
399
400
401
402
# File 'lib/contentful/client.rb', line 397

def update_dynamic_entry_cache!
  return if configuration[:raw_mode]
  content_types(limit: 1000).map do |ct|
    ContentTypeCache.cache_set(configuration[:space], ct.id, ct)
  end
end