Python 请求 POST 图像文件到 rails 回形针,Rails:params ParseError
Python requests POST image file to rails paperclip, Rails: params ParseError
我正在使用 Google 驱动器 API 下载图像并使用 Paperclip 将文件上传到我的 Rails API。
我已经将 Google 驱动器映像下载为 BytesIO()
并使用 Pillow 将字节 save/convert 放入名为 tmp.png
的映像中。我现在正在使用请求 POST 我的文件到 Rails:
# I have a io.BytesIO() instance fh, with the image byte data.
fh.seek(0)
img = Image.open(fh)
img.save('tmp.png')
response = requests.post(LOCALHOST_MEDIA_ENDPOINT,
data={
"media": {
"attachment": open('tmp.png', 'rb')
# I've also tried just using img
}
},
headers={
'content-type': 'application/json'
})
media/paperclip 控制器工作;它已经在带有文件 dropzone 的 Node 应用程序上通过表单提交进行了测试。然而,当我提出这个请求时,我的本地主机日志吐出:
Started POST "/media" for 172.18.0.1 at 2017-11-14 02:16:35 +0000
web_1 | Error occurred while parsing request parameters.
web_1 | Contents:
web_1 |
web_1 | media=attachment
web_1 |
web_1 | ActionDispatch::Http::Parameters::ParseError (822: unexpected token at 'media=attachment'):
web_1 |
web_1 | actionpack (5.1.2) lib/action_dispatch/http/parameters.rb:113:in `rescue in parse_formatted_parameters'
web_1 | actionpack (5.1.2) lib/action_dispatch/http/parameters.rb:107:in `parse_formatted_parameters'
web_1 | actionpack (5.1.2) lib/action_dispatch/http/request.rb:358:in `block in POST'
web_1 | rack (2.0.3) lib/rack/request.rb:57:in `fetch'
web_1 | rack (2.0.3) lib/rack/request.rb:57:in `fetch_header'
web_1 | actionpack (5.1.2) lib/action_dispatch/http/request.rb:357:in `POST'
web_1 | actionpack (5.1.2) lib/action_controller/metal/params_wrapper.rb:286:in `_wrapper_enabled?'
web_1 | actionpack (5.1.2) lib/action_controller/metal/params_wrapper.rb:235:in `process_action'
web_1 | activerecord (5.1.2) lib/active_record/railties/controller_runtime.rb:22:in `process_action'
web_1 | actionpack (5.1.2) lib/abstract_controller/base.rb:124:in `process'
web_1 | actionpack (5.1.2) lib/action_controller/metal.rb:189:in `dispatch'
web_1 | actionpack (5.1.2) lib/action_controller/metal.rb:253:in `dispatch'
web_1 | actionpack (5.1.2) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
web_1 | actionpack (5.1.2) lib/action_dispatch/routing/route_set.rb:31:in `serve'
web_1 | actionpack (5.1.2) lib/action_dispatch/journey/router.rb:46:in `block in serve'
web_1 | actionpack (5.1.2) lib/action_dispatch/journey/router.rb:33:in `each'
web_1 | actionpack (5.1.2) lib/action_dispatch/journey/router.rb:33:in `serve'
web_1 | actionpack (5.1.2) lib/action_dispatch/routing/route_set.rb:832:in `call'
web_1 | omniauth (1.6.1) lib/omniauth/strategy.rb:189:in `call!'
web_1 | omniauth (1.6.1) lib/omniauth/strategy.rb:167:in `call'
web_1 | omniauth (1.6.1) lib/omniauth/builder.rb:63:in `call'
web_1 | rack (2.0.3) lib/rack/session/abstract/id.rb:232:in `context'
web_1 | rack (2.0.3) lib/rack/session/abstract/id.rb:226:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/cookies.rb:613:in `call'
web_1 | olive_branch (1.2.3) lib/olive_branch/middleware.rb:14:in `call'
web_1 | warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
web_1 | warden (1.2.7) lib/warden/manager.rb:35:in `catch'
web_1 | warden (1.2.7) lib/warden/manager.rb:35:in `call'
web_1 | rack (2.0.3) lib/rack/etag.rb:25:in `call'
web_1 | rack (2.0.3) lib/rack/conditional_get.rb:38:in `call'
web_1 | rack (2.0.3) lib/rack/head.rb:12:in `call'
web_1 | activerecord (5.1.2) lib/active_record/migration.rb:556:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
web_1 | activesupport (5.1.2) lib/active_support/callbacks.rb:97:in `run_callbacks'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/callbacks.rb:24:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/executor.rb:12:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
web_1 | railties (5.1.2) lib/rails/rack/logger.rb:36:in `call_app'
web_1 | railties (5.1.2) lib/rails/rack/logger.rb:24:in `block in call'
web_1 | activesupport (5.1.2) lib/active_support/tagged_logging.rb:69:in `block in tagged'
web_1 | activesupport (5.1.2) lib/active_support/tagged_logging.rb:26:in `tagged'
web_1 | activesupport (5.1.2) lib/active_support/tagged_logging.rb:69:in `tagged'
web_1 | railties (5.1.2) lib/rails/rack/logger.rb:24:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/request_id.rb:25:in `call'
web_1 | rack (2.0.3) lib/rack/runtime.rb:22:in `call'
web_1 | activesupport (5.1.2) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/executor.rb:12:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/static.rb:125:in `call'
web_1 | rack (2.0.3) lib/rack/sendfile.rb:111:in `call'
web_1 | rack-cors (1.0.1) lib/rack/cors.rb:93:in `call'
web_1 | railties (5.1.2) lib/rails/engine.rb:522:in `call'
web_1 | puma (3.9.1) lib/puma/configuration.rb:224:in `call'
web_1 | puma (3.9.1) lib/puma/server.rb:602:in `handle_request'
web_1 | puma (3.9.1) lib/puma/server.rb:435:in `process_client'
web_1 | puma (3.9.1) lib/puma/server.rb:299:in `block in run'
web_1 | puma (3.9.1) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
我的控制器:
def create
@medium = Medium.new(medium_params)
if @medium.save
render json: @medium.to_json(
:only => [:id, :title, :caption],
:methods => [
:attachment_url,
:medium_attachment_url,
:thumb_attachment_url
]
), status: :created, location: @medium
else
render json: @medium.errors, status: :unprocessable_entity
end
end
...
def medium_params
params.require(:medium).permit(
# other irrelevant string/int permitted params
:attachment
)
end
我在想,在这个请求中,图像的编码方式可能与表单提交数据的方式不同。但不幸的是我很困。
创建一个 multipart/form-data 请求而不是 application/json。
或者如果你想使用 base64 编码的文件内容,你将不得不做一些额外的解码工作并将图像分配给 papercip (Use paperclip for saving base64 images obtained from an api)
我正在使用 Google 驱动器 API 下载图像并使用 Paperclip 将文件上传到我的 Rails API。
我已经将 Google 驱动器映像下载为 BytesIO()
并使用 Pillow 将字节 save/convert 放入名为 tmp.png
的映像中。我现在正在使用请求 POST 我的文件到 Rails:
# I have a io.BytesIO() instance fh, with the image byte data.
fh.seek(0)
img = Image.open(fh)
img.save('tmp.png')
response = requests.post(LOCALHOST_MEDIA_ENDPOINT,
data={
"media": {
"attachment": open('tmp.png', 'rb')
# I've also tried just using img
}
},
headers={
'content-type': 'application/json'
})
media/paperclip 控制器工作;它已经在带有文件 dropzone 的 Node 应用程序上通过表单提交进行了测试。然而,当我提出这个请求时,我的本地主机日志吐出:
Started POST "/media" for 172.18.0.1 at 2017-11-14 02:16:35 +0000
web_1 | Error occurred while parsing request parameters.
web_1 | Contents:
web_1 |
web_1 | media=attachment
web_1 |
web_1 | ActionDispatch::Http::Parameters::ParseError (822: unexpected token at 'media=attachment'):
web_1 |
web_1 | actionpack (5.1.2) lib/action_dispatch/http/parameters.rb:113:in `rescue in parse_formatted_parameters'
web_1 | actionpack (5.1.2) lib/action_dispatch/http/parameters.rb:107:in `parse_formatted_parameters'
web_1 | actionpack (5.1.2) lib/action_dispatch/http/request.rb:358:in `block in POST'
web_1 | rack (2.0.3) lib/rack/request.rb:57:in `fetch'
web_1 | rack (2.0.3) lib/rack/request.rb:57:in `fetch_header'
web_1 | actionpack (5.1.2) lib/action_dispatch/http/request.rb:357:in `POST'
web_1 | actionpack (5.1.2) lib/action_controller/metal/params_wrapper.rb:286:in `_wrapper_enabled?'
web_1 | actionpack (5.1.2) lib/action_controller/metal/params_wrapper.rb:235:in `process_action'
web_1 | activerecord (5.1.2) lib/active_record/railties/controller_runtime.rb:22:in `process_action'
web_1 | actionpack (5.1.2) lib/abstract_controller/base.rb:124:in `process'
web_1 | actionpack (5.1.2) lib/action_controller/metal.rb:189:in `dispatch'
web_1 | actionpack (5.1.2) lib/action_controller/metal.rb:253:in `dispatch'
web_1 | actionpack (5.1.2) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
web_1 | actionpack (5.1.2) lib/action_dispatch/routing/route_set.rb:31:in `serve'
web_1 | actionpack (5.1.2) lib/action_dispatch/journey/router.rb:46:in `block in serve'
web_1 | actionpack (5.1.2) lib/action_dispatch/journey/router.rb:33:in `each'
web_1 | actionpack (5.1.2) lib/action_dispatch/journey/router.rb:33:in `serve'
web_1 | actionpack (5.1.2) lib/action_dispatch/routing/route_set.rb:832:in `call'
web_1 | omniauth (1.6.1) lib/omniauth/strategy.rb:189:in `call!'
web_1 | omniauth (1.6.1) lib/omniauth/strategy.rb:167:in `call'
web_1 | omniauth (1.6.1) lib/omniauth/builder.rb:63:in `call'
web_1 | rack (2.0.3) lib/rack/session/abstract/id.rb:232:in `context'
web_1 | rack (2.0.3) lib/rack/session/abstract/id.rb:226:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/cookies.rb:613:in `call'
web_1 | olive_branch (1.2.3) lib/olive_branch/middleware.rb:14:in `call'
web_1 | warden (1.2.7) lib/warden/manager.rb:36:in `block in call'
web_1 | warden (1.2.7) lib/warden/manager.rb:35:in `catch'
web_1 | warden (1.2.7) lib/warden/manager.rb:35:in `call'
web_1 | rack (2.0.3) lib/rack/etag.rb:25:in `call'
web_1 | rack (2.0.3) lib/rack/conditional_get.rb:38:in `call'
web_1 | rack (2.0.3) lib/rack/head.rb:12:in `call'
web_1 | activerecord (5.1.2) lib/active_record/migration.rb:556:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
web_1 | activesupport (5.1.2) lib/active_support/callbacks.rb:97:in `run_callbacks'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/callbacks.rb:24:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/executor.rb:12:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
web_1 | railties (5.1.2) lib/rails/rack/logger.rb:36:in `call_app'
web_1 | railties (5.1.2) lib/rails/rack/logger.rb:24:in `block in call'
web_1 | activesupport (5.1.2) lib/active_support/tagged_logging.rb:69:in `block in tagged'
web_1 | activesupport (5.1.2) lib/active_support/tagged_logging.rb:26:in `tagged'
web_1 | activesupport (5.1.2) lib/active_support/tagged_logging.rb:69:in `tagged'
web_1 | railties (5.1.2) lib/rails/rack/logger.rb:24:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/request_id.rb:25:in `call'
web_1 | rack (2.0.3) lib/rack/runtime.rb:22:in `call'
web_1 | activesupport (5.1.2) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/executor.rb:12:in `call'
web_1 | actionpack (5.1.2) lib/action_dispatch/middleware/static.rb:125:in `call'
web_1 | rack (2.0.3) lib/rack/sendfile.rb:111:in `call'
web_1 | rack-cors (1.0.1) lib/rack/cors.rb:93:in `call'
web_1 | railties (5.1.2) lib/rails/engine.rb:522:in `call'
web_1 | puma (3.9.1) lib/puma/configuration.rb:224:in `call'
web_1 | puma (3.9.1) lib/puma/server.rb:602:in `handle_request'
web_1 | puma (3.9.1) lib/puma/server.rb:435:in `process_client'
web_1 | puma (3.9.1) lib/puma/server.rb:299:in `block in run'
web_1 | puma (3.9.1) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
我的控制器:
def create
@medium = Medium.new(medium_params)
if @medium.save
render json: @medium.to_json(
:only => [:id, :title, :caption],
:methods => [
:attachment_url,
:medium_attachment_url,
:thumb_attachment_url
]
), status: :created, location: @medium
else
render json: @medium.errors, status: :unprocessable_entity
end
end
...
def medium_params
params.require(:medium).permit(
# other irrelevant string/int permitted params
:attachment
)
end
我在想,在这个请求中,图像的编码方式可能与表单提交数据的方式不同。但不幸的是我很困。
创建一个 multipart/form-data 请求而不是 application/json。
或者如果你想使用 base64 编码的文件内容,你将不得不做一些额外的解码工作并将图像分配给 papercip (Use paperclip for saving base64 images obtained from an api)