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



284
285
286
# File 'lib/contentful/client.rb', line 284

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



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

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



313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/contentful/client.rb', line 313

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



420
421
422
423
424
425
426
427
428
429
430
# File 'lib/contentful/client.rb', line 420

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



264
265
266
# File 'lib/contentful/client.rb', line 264

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

#fail_response(response) ⇒ Object



392
393
394
395
# File 'lib/contentful/client.rb', line 392

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



270
271
272
273
274
# File 'lib/contentful/client.rb', line 270

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



354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
# File 'lib/contentful/client.rb', line 354

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



290
291
292
# File 'lib/contentful/client.rb', line 290

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



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

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



296
297
298
# File 'lib/contentful/client.rb', line 296

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



445
446
447
# File 'lib/contentful/client.rb', line 445

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

#request_headersObject

Returns the headers used for the HTTP requests



332
333
334
335
336
337
338
# File 'lib/contentful/client.rb', line 332

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



342
343
344
345
346
347
# File 'lib/contentful/client.rb', line 342

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



384
385
386
387
388
389
# File 'lib/contentful/client.rb', line 384

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



404
405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/contentful/client.rb', line 404

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



278
279
280
# File 'lib/contentful/client.rb', line 278

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



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

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:



456
457
458
# File 'lib/contentful/client.rb', line 456

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

#taxonomy_concept(id, query = {}) ⇒ Contentful::TaxonomyConcept

Gets a specific taxonomy concept

Parameters:

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

Returns:



224
225
226
# File 'lib/contentful/client.rb', line 224

def taxonomy_concept(id, query = {})
  Request.new(self, environment_url('/taxonomy/concepts'), query, id).get
end

#taxonomy_concept_scheme(id, query = {}) ⇒ Contentful::TaxonomyConceptScheme

Gets a specific taxonomy concept scheme

Parameters:

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

Returns:



243
244
245
# File 'lib/contentful/client.rb', line 243

def taxonomy_concept_scheme(id, query = {})
  Request.new(self, environment_url('/taxonomy/concept-schemes'), query, id).get
end

#taxonomy_concept_schemes(query = {}) ⇒ Contentful::Array<Contentful::TaxonomyConceptScheme>

Gets a collection of taxonomy concept schemes

Parameters:

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

Returns:



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

def taxonomy_concept_schemes(query = {})
  Request.new(self, environment_url('/taxonomy/concept-schemes'), query).get
end

#taxonomy_concepts(query = {}) ⇒ Contentful::Array<Contentful::TaxonomyConcept>

Gets a collection of taxonomy concepts

Parameters:

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

Returns:



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

def taxonomy_concepts(query = {})
  Request.new(self, environment_url('/taxonomy/concepts'), query).get
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.



435
436
437
438
439
440
# File 'lib/contentful/client.rb', line 435

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