class Contentful::Client
The client object is initialized with a space and a key and then used for querying resources from this space. See README for details
Constants
- DEFAULT_CONFIGURATION
Default configuration for
Contentful::Client
Attributes
Public Class Methods
Wraps the actual HTTP request via proxy @private
# 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
@see _ github.com/contentful/contentful.rb#client-configuration-options @param [Hash] given_configuration @option given_configuration [String] :space Required @option given_configuration [String] :access_token Required @option given_configuration [String] :api_url Modifying this to ‘preview.contentful.com’ gives you access to our Preview API @option given_configuration [String] :api_version @option given_configuration [String] :default_locale @option given_configuration [String] :proxy_host @option given_configuration [String] :proxy_username @option given_configuration [String] :proxy_password @option given_configuration [Number] :proxy_port @option given_configuration [Number] :timeout_read @option given_configuration [Number] :timeout_write @option given_configuration [Number] :timeout_connect @option given_configuration [Number] :max_rate_limit_retries @option given_configuration [Number] :max_rate_limit_wait @option given_configuration [Number] :max_include_resolution_depth @option given_configuration [Boolean] :use_camel_case @option given_configuration [Boolean] :gzip_encoded @option given_configuration [Boolean] :raw_mode @option given_configuration [false, ::Logger] :logger @option given_configuration [::Logger::DEBUG, ::Logger::INFO, ::Logger::WARN, ::Logger::ERROR] :log_level @option given_configuration [Boolean] :raise_errors @option given_configuration [Boolean] :raise_for_empty_fields @option given_configuration [::Array<String>] :dynamic_entries @option given_configuration [::Hash<String, Contentful::Resource>] :resource_mapping @option given_configuration [::Hash<String, Contentful::Resource>] :entry_mapping @option given_configuration [String] :application_name @option given_configuration [String] :application_version @option given_configuration [String] :integration_name @option given_configuration [String] :integration_version
# 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
Public Instance Methods
Returns the X-Contentful-User-Agent app data @private
# File lib/contentful/client.rb, line 246 def app_info { name: configuration[:application_name], version: configuration[:application_version] } end
Gets a specific asset
@param [String] id @param [Hash] query
@return [Contentful::Asset]
# File lib/contentful/client.rb, line 195 def asset(id, query = {}) Request.new(self, environment_url('/assets'), query, id).get end
Gets a collection of assets
@param [Hash] query
@return [Contentful::Array<Contentful::Asset>]
# File lib/contentful/client.rb, line 204 def assets(query = {}) normalize_select!(query) Request.new(self, environment_url('/assets'), query).get end
Returns the base url for all of the client’s requests @private
# File lib/contentful/client.rb, line 220 def base_url "http#{configuration[:secure] ? 's' : ''}://#{configuration[:api_url]}/spaces/#{configuration[:space]}" end
Gets a specific content type
@param [String] id @param [Hash] query
@return [Contentful::ContentType]
# File lib/contentful/client.rb, line 150 def content_type(id, query = {}) Request.new(self, environment_url('/content_types'), query, id).get end
Gets a collection of content types
@param [Hash] query
@return [Contentful::Array<Contentful::ContentType>]
# File lib/contentful/client.rb, line 159 def content_types(query = {}) Request.new(self, environment_url('/content_types'), query).get end
Returns the X-Contentful-User-Agent @private
# 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
Returns the default configuration @private
# File lib/contentful/client.rb, line 131 def default_configuration DEFAULT_CONFIGURATION.dup end
Runs Resource Builder @private
# 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
Gets a collection of entries
@param [Hash] query
@return [Contentful::Array<Contentful::Entry>]
# File lib/contentful/client.rb, line 184 def entries(query = {}) normalize_select!(query) Request.new(self, environment_url('/entries'), query).get end
Gets a specific entry
@param [String] id @param [Hash] query
@return [Contentful::Entry]
# 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
Returns the url aware of the currently selected environment @private
# File lib/contentful/client.rb, line 226 def environment_url(path) "/environments/#{configuration[:environment]}#{path}" end
@private
# File lib/contentful/client.rb, line 354 def fail_response(response) fail response.object if configuration[:raise_errors] response.object end
Returns the formatted part of the X-Contentful-User-Agent header @private
# 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 a Contentful::Request
object Set second parameter to false to deactivate Resource building and return Response
objects instead
@private
# 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
Returns the X-Contentful-User-Agent integration data @private
# File lib/contentful/client.rb, line 252 def integration_info { name: configuration[:integration_name], version: configuration[:integration_version] } end
Gets a collection of locales for the current environment
@param [Hash] query
@return [Contentful::Array<Contentful::Locale>]
# File lib/contentful/client.rb, line 214 def locales(query = {}) Request.new(self, environment_url('/locales'), query).get end
Returns the X-Contentful-User-Agent os data @private
# 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
Returns the X-Contentful-User-Agent platform data @private
# File lib/contentful/client.rb, line 258 def platform_info { name: 'ruby', version: RUBY_VERSION } end
@private
# 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
Use this method to manually register a dynamic entry See examples/dynamic_entries.rb @private
# File lib/contentful/client.rb, line 407 def register_dynamic_entry(key, klass) ContentTypeCache.cache_set(configuration[:space], key, klass) end
Returns the headers used for the HTTP requests @private
# 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
Patches a query hash with the client configurations for queries @private
# 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
@private
# 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
Runs request and parses Response
@private
# 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
Returns the X-Contentful-User-Agent sdk data @private
# File lib/contentful/client.rb, line 240 def sdk_info { name: 'contentful.rb', version: ::Contentful::VERSION } end
@private
# 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
@private
# File lib/contentful/client.rb, line 360 def should_retry(retries_left, reset_time, max_wait) retries_left > 0 && max_wait > reset_time end
Gets the client’s space
@param [Hash] query
@return [Contentful::Space]
# File lib/contentful/client.rb, line 140 def space(query = {}) Request.new(self, '', query).get end
Create a new synchronisation object
@param [Hash, String] options Options or Sync
URL
@note You will need to call each_page or first_page on it
@return [Contentful::Sync]
# File lib/contentful/client.rb, line 418 def sync(options = { initial: true }) Sync.new(self, options) end
@private
# 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
Use this method together with the client’s :dynamic_entries configuration. See README for details. @private
# 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
Private Instance Methods
# File lib/contentful/client.rb, line 436 def normalize_configuration! %i[space access_token api_url default_locale].each { |s| configuration[s] = configuration[s].to_s } configuration[:authentication_mechanism] = configuration[:authentication_mechanism].to_sym end
If the query contains the :select operator, we enforce :sys properties. The SDK requires sys.type to function properly, but as other of our SDKs require more parts of the :sys properties, we decided that every SDK should include the complete :sys block to provide consistency accross our SDKs.
# File lib/contentful/client.rb, line 428 def normalize_select!(query) return unless query.key?(:select) query[:select] = query[:select].split(',').map(&:strip) if query[:select].is_a? String query[:select] = query[:select].reject { |p| p.start_with?('sys.') } query[:select] << 'sys' unless query[:select].include?('sys') end
# File lib/contentful/client.rb, line 441 def validate_configuration! fail ArgumentError, 'You will need to initialize a client with a :space' if configuration[:space].empty? fail ArgumentError, 'You will need to initialize a client with an :access_token' if configuration[:access_token].empty? fail ArgumentError, 'The client configuration needs to contain an :api_url' if configuration[:api_url].empty? fail ArgumentError, 'The client configuration needs to contain a :default_locale' if configuration[:default_locale].empty? fail ArgumentError, 'The :api_version must be a positive number or nil' unless configuration[:api_version].to_i >= 0 fail ArgumentError, 'The authentication mechanism must be :header or :query_string' unless %i[header query_string].include?( configuration[:authentication_mechanism] ) fail ArgumentError, 'The :dynamic_entries mode must be :auto or :manual' unless %i[auto manual].include?( configuration[:dynamic_entries] ) fail ArgumentError, 'Timeout parameters must be all omitted or all present' unless timeout_params.empty? || timeout_params.length == 3 end