Class: Praxis::MultipartPart
- Inherits:
-
Object
- Object
- Praxis::MultipartPart
- Includes:
- Attributor::Type
- Defined in:
- lib/praxis/multipart/part.rb
Instance Attribute Summary collapse
-
#body ⇒ Object
(also: #payload)
Returns the value of attribute body.
-
#default_handler ⇒ Object
Returns the value of attribute default_handler.
-
#filename ⇒ Object
Returns the value of attribute filename.
-
#filename_attribute ⇒ Object
Returns the value of attribute filename_attribute.
-
#headers ⇒ Object
Returns the value of attribute headers.
-
#headers_attribute ⇒ Object
Returns the value of attribute headers_attribute.
-
#name ⇒ Object
Returns the value of attribute name.
-
#payload_attribute ⇒ Object
Returns the value of attribute payload_attribute.
Class Method Summary collapse
- .check_option!(name, definition) ⇒ Object
- .describe(shallow = true, example: nil, options: {}) ⇒ Object
- .dump_for_openapi(_example_part) ⇒ Object
- .example(context = nil, options: {}) ⇒ Object
- .json_schema_type ⇒ Object
- .native_type ⇒ Object
Instance Method Summary collapse
- #attribute=(attribute) ⇒ Object
-
#content_type ⇒ MediaTypeIdentifier
Determine the content type of this response.
-
#content_type=(identifier) ⇒ String
Set the content type for this response.
-
#derive_content_type(handler_name) ⇒ Object
Determine an appropriate default content_type for this part given the preferred handler_name, if possible.
- #dump(default_format: nil, **opts) ⇒ Object
- #encode! ⇒ Object
- #handler ⇒ Object
-
#initialize(body, headers = {}, **args) ⇒ MultipartPart
constructor
A new instance of MultipartPart.
- #load_headers(_context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
- #load_payload(_context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
- #reset_content_disposition ⇒ Object
- #status ⇒ Object
- #validate(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
- #validate_filename(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
- #validate_headers(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
- #validate_payload(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
Constructor Details
#initialize(body, headers = {}, **args) ⇒ MultipartPart
Returns a new instance of MultipartPart.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# 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 |
Instance Attribute Details
#body ⇒ Object Also known as: payload
Returns the value of attribute body.
8 9 10 |
# File 'lib/praxis/multipart/part.rb', line 8 def body @body end |
#default_handler ⇒ Object
Returns the value of attribute default_handler.
8 9 10 |
# File 'lib/praxis/multipart/part.rb', line 8 def default_handler @default_handler end |
#filename ⇒ Object
Returns the value of attribute filename.
7 8 9 |
# File 'lib/praxis/multipart/part.rb', line 7 def filename @filename end |
#filename_attribute ⇒ Object
Returns the value of attribute filename_attribute.
8 9 10 |
# File 'lib/praxis/multipart/part.rb', line 8 def filename_attribute @filename_attribute end |
#headers ⇒ Object
Returns the value of attribute headers.
8 9 10 |
# File 'lib/praxis/multipart/part.rb', line 8 def headers @headers end |
#headers_attribute ⇒ Object
Returns the value of attribute headers_attribute.
8 9 10 |
# File 'lib/praxis/multipart/part.rb', line 8 def headers_attribute @headers_attribute end |
#name ⇒ Object
Returns the value of attribute name.
7 8 9 |
# File 'lib/praxis/multipart/part.rb', line 7 def name @name end |
#payload_attribute ⇒ Object
Returns the value of attribute payload_attribute.
8 9 10 |
# File 'lib/praxis/multipart/part.rb', line 8 def payload_attribute @payload_attribute end |
Class Method Details
.check_option!(name, definition) ⇒ Object
10 11 12 13 14 15 16 17 18 19 |
# 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 |
.describe(shallow = true, example: nil, options: {}) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/praxis/multipart/part.rb', line 52 def self.describe(shallow = true, example: nil, options: {}) hash = super(shallow, example: example) if (payload_attribute = [:payload_attribute]) payload_example = example.payload if example hash[:payload] = payload_attribute.describe(shallow, example: payload_example) end if (headers_attribute = [:headers_attribute]) headers_example = example.headers if example hash[:headers] = headers_attribute.describe(shallow, example: headers_example) end if (filename_attribute = [:filename_attribute]) filename_example = example.filename if example hash[:filename] = filename_attribute.describe(shallow, example: filename_example) end hash end |
.dump_for_openapi(_example_part) ⇒ Object
258 259 260 261 |
# 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 |
.example(context = nil, options: {}) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/praxis/multipart/part.rb', line 29 def self.example(context = nil, options: {}) if (payload_attribute = [:payload_attribute]) payload = payload_attribute.example(context + ['payload']) end headers = if (headers_attribute = [:headers_attribute]) headers_attribute.example(context + ['headers']) else {} end name = [:name] filename = if (filename_attribute = [: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 |
.json_schema_type ⇒ Object
25 26 27 |
# File 'lib/praxis/multipart/part.rb', line 25 def self.json_schema_type :object end |
.native_type ⇒ Object
21 22 23 |
# File 'lib/praxis/multipart/part.rb', line 21 def self.native_type self end |
Instance Method Details
#attribute=(attribute) ⇒ Object
91 92 93 94 95 96 97 98 99 |
# 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.[:payload_attribute] if attribute..key? :payload_attribute @headers_attribute = attribute.[:headers_attribute] if attribute..key? :headers_attribute @filename_attribute = attribute.[:filename_attribute] if attribute..key? :filename_attribute end |
#content_type ⇒ MediaTypeIdentifier
Determine the content type of this response.
119 120 121 |
# File 'lib/praxis/multipart/part.rb', line 119 def content_type @content_type ||= MediaTypeIdentifier.load(headers['Content-Type']).freeze end |
#content_type=(identifier) ⇒ String
DRY this out (also used in Response)
Set the content type for this response.
128 129 130 131 |
# File 'lib/praxis/multipart/part.rb', line 128 def content_type=(identifier) @content_type = nil headers['Content-Type'] = MediaTypeIdentifier.load(identifier).to_s end |
#derive_content_type(handler_name) ⇒ Object
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.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# 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&.&.key?(:values) content_type_attribute.[: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 |
#dump(default_format: nil, **opts) ⇒ Object
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# 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 |
#encode! ⇒ Object
137 138 139 140 141 142 143 144 145 |
# 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 |
#handler ⇒ Object
192 193 194 195 |
# 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 |
#load_headers(_context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
112 113 114 |
# 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 |
#load_payload(_context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
101 102 103 104 105 106 107 108 109 110 |
# 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 |
#reset_content_disposition ⇒ Object
171 172 173 174 175 176 177 178 |
# 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 |
#status ⇒ Object
133 134 135 |
# File 'lib/praxis/multipart/part.rb', line 133 def status @headers['Status'].to_i end |
#validate(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
165 166 167 168 169 |
# 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 |
#validate_filename(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
159 160 161 162 163 |
# 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 |
#validate_headers(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
147 148 149 150 151 |
# 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 |
#validate_payload(context = Attributor::DEFAULT_ROOT_CONTEXT) ⇒ Object
153 154 155 156 157 |
# 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 |