class Praxis::MultipartPart
Attributes
Public Class Methods
Source
# File lib/praxis/multipart/part.rb, line 10 def self.check_option!(name, definition) case name when :payload_attribute, :headers_attribute, :filename_attribute raise Attributor::AttributorException, "Value for option #{name.inspect} must be an Attribute. Got #{definition.class.name}" unless definition.nil? || definition.is_a?(Attributor::Attribute) else return :unknown end :ok end
Source
# File lib/praxis/multipart/part.rb, line 52 def self.describe(shallow = true, example: nil, options: {}) hash = super(shallow, example: example) if (payload_attribute = options[:payload_attribute]) payload_example = example.payload if example hash[:payload] = payload_attribute.describe(shallow, example: payload_example) end if (headers_attribute = options[:headers_attribute]) headers_example = example.headers if example hash[:headers] = headers_attribute.describe(shallow, example: headers_example) end if (filename_attribute = options[:filename_attribute]) filename_example = example.filename if example hash[:filename] = filename_attribute.describe(shallow, example: filename_example) end hash end
Calls superclass method
Source
# File lib/praxis/multipart/part.rb, line 258 def self.dump_for_openapi(_example_part) # TODO: This needs to be structured as OpenAPI requires it raise 'dumping a part for open api not implemented yet' end
Source
# File lib/praxis/multipart/part.rb, line 29 def self.example(context = nil, options: {}) if (payload_attribute = options[:payload_attribute]) payload = payload_attribute.example(context + ['payload']) end headers = if (headers_attribute = options[:headers_attribute]) headers_attribute.example(context + ['headers']) else {} end name = options[:name] filename = if (filename_attribute = options[:filename_attribute]) filename_attribute.example(context + ['filename']) end new(payload, headers, name: name, filename: filename, payload_attribute: payload_attribute, headers_attribute: headers_attribute, filename_attribute: filename_attribute) end
Source
# File lib/praxis/multipart/part.rb, line 25 def self.json_schema_type :object end
Source
# File lib/praxis/multipart/part.rb, line 71 def initialize(body, headers = {}, **args) @name = args[:name] @body = body @headers = headers @default_handler = Praxis::Application.instance.handlers['json'] self.content_type = 'text/plain' if content_type.nil? @filename = args[:filename] @payload_attribute = args[:payload_attribute] @headers_attribute = args[:headers_attribute] @filename_attribute = args[:filename_attribute] reset_content_disposition end
Public Instance Methods
Source
# File lib/praxis/multipart/part.rb, line 91 def attribute=(attribute) raise ArgumentError, "invalid attribute type #{attribute.type}" unless is_a?(attribute.type) @payload_attribute = attribute.options[:payload_attribute] if attribute.options.key? :payload_attribute @headers_attribute = attribute.options[:headers_attribute] if attribute.options.key? :headers_attribute @filename_attribute = attribute.options[:filename_attribute] if attribute.options.key? :filename_attribute end
Source
# File lib/praxis/multipart/part.rb, line 119 def content_type @content_type ||= MediaTypeIdentifier.load(headers['Content-Type']).freeze end
Determine the content type of this response.
@return [MediaTypeIdentifier]
Source
# File lib/praxis/multipart/part.rb, line 128 def content_type=(identifier) @content_type = nil headers['Content-Type'] = MediaTypeIdentifier.load(identifier).to_s end
Set the content type for this response. @todo DRY this out (also used in Response
)
@return [String] @param [String,MediaTypeIdentifier] identifier
Source
# File lib/praxis/multipart/part.rb, line 202 def derive_content_type(handler_name) possible_values = if content_type.match 'text/plain' _, content_type_attribute = headers_attribute&.attributes&.find { |k, _v| k.to_s =~ /^content[-_]{1}type$/i } if content_type_attribute&.options&.key?(:values) content_type_attribute.options[:values] else [] end else [content_type] end # generic default encoding is the best we can do return MediaTypeIdentifier.load("application/#{handler_name}") if possible_values.empty? # if any defined value match the preferred handler_name, return it possible_values.each do |ct| mti = MediaTypeIdentifier.load(ct) return mti if mti.handler_name == handler_name end # otherwise, pick the first pick = MediaTypeIdentifier.load(possible_values.first) # and return that one if it already corresponds to a registered handler # otherwise, add the encoding if Praxis::Application.instance.handlers.include?(pick.handler_name) pick else pick + handler_name end end
Determine an appropriate default content_type
for this part given the preferred handler_name, if possible.
Considers any pre-defined set of values on the content_type
attributge of the headers.
Source
# File lib/praxis/multipart/part.rb, line 235 def dump(default_format: nil, **opts) original_content_type = content_type body = payload_attribute.dump(payload, **opts) body_string = case body when Hash, Array self.content_type = derive_content_type(default_format) if default_format handler.generate(body) else body end header_string = headers.collect do |name, value| "#{name}: #{value}" end.join("\r\n") "#{header_string}\r\n\r\n#{body_string}" ensure self.content_type = original_content_type end
Source
# File lib/praxis/multipart/part.rb, line 137 def encode! case @body when Hash, Array # response payload is structured data; transform it into an entity using the handler # implied by the response's media type. If no handler is registered for this # name, assume JSON as a default handler. @body = JSON.pretty_generate(@body) end end
Source
# File lib/praxis/multipart/part.rb, line 186 def filename=(filename) @filename = filename reset_content_disposition filename end
Source
# File lib/praxis/multipart/part.rb, line 192 def handler handlers = Praxis::Application.instance.handlers (content_type && handlers[content_type.handler_name]) || @default_handler end
Source
# File lib/praxis/multipart/part.rb, line 112 def load_headers(_context = Attributor::DEFAULT_ROOT_CONTEXT) self.headers = headers_attribute.load(headers) if headers_attribute end
Source
# File lib/praxis/multipart/part.rb, line 101 def load_payload(_context = Attributor::DEFAULT_ROOT_CONTEXT) return unless payload_attribute value = if payload.is_a?(String) handler.parse(payload) else payload end self.payload = payload_attribute.load(value) end
Source
# File lib/praxis/multipart/part.rb, line 180 def name=(name) @name = name reset_content_disposition name end
Source
# File lib/praxis/multipart/part.rb, line 171 def reset_content_disposition headers['Content-Disposition'] = begin disposition = "form-data; name=#{name}" disposition += "; filename=#{filename}" if filename disposition end end
Source
# File lib/praxis/multipart/part.rb, line 133 def status @headers['Status'].to_i end
Source
# File lib/praxis/multipart/part.rb, line 165 def validate(context = Attributor::DEFAULT_ROOT_CONTEXT) errors = validate_headers(context) errors.push(*validate_payload(context)) errors.push(*validate_filename(context)) end
Source
# File lib/praxis/multipart/part.rb, line 159 def validate_filename(context = Attributor::DEFAULT_ROOT_CONTEXT) return [] unless filename_attribute filename_attribute.validate(filename, context + ['filename']) end
Source
# File lib/praxis/multipart/part.rb, line 147 def validate_headers(context = Attributor::DEFAULT_ROOT_CONTEXT) return [] unless headers_attribute headers_attribute.validate(headers, context + ['headers']) end
Source
# File lib/praxis/multipart/part.rb, line 153 def validate_payload(context = Attributor::DEFAULT_ROOT_CONTEXT) return [] unless payload_attribute payload_attribute.validate(payload, context + ['payload']) end