我如何 post 带有请求的多部分 POST 图像对象?
How do I post an Image object with a multi-part POST with Request?
我正在尝试将我写的一些 javascript
代码转换为 Python
,但在传递数据时卡住了 b/t PIL
和 Requests
对象。
我的 python
脚本将图像下载到内存:
from PIL import Image
import urllib2
import cStringIO
def fetch_image_to_memory(url):
req = urllib2.Request(url, headers={
'User-Agent': "Mozilla / 5.0 (X11; U; Linux i686) Gecko / 20071127 Firefox / 2.0.0.11"})
con = urllib2.urlopen(req)
imgData = con.read()
return Image.open(cStringIO.StringIO(imgData))
然后我想将它添加到 form data
以进行 POST
操作。当文件在磁盘上时,此代码成功:
from requests_toolbelt import MultipartEncoder
import requests
url = 'https://us-west-2.api.scaphold.io/graphql/some-gql-endpoint'
multipart_data = MultipartEncoder(
fields={
'query':'some-graphql-specific-query-string',
'variables': '{ "input": {"blobFieldName": "myBlobField" }}',
## `variables.input.blobFieldName` must hold name
## of Form field w/ the file to be uploaded
'type': 'application/json',
'myBlobField': ('example.jpg', img, 'image/jpeg')
}
)
req_headers = {'Content-Type':multipart_data.content_type,
'Authorization':'Bearer secret-bearer-token'}
r = requests.post(url, data=multipart_data, headers=req_headers)
但是,当尝试从 fetch_image_to_memory
函数传入 Image
对象时:
'myBlobField': ('example.jpg', image_object, 'image/jpeg')
...我收到错误:
Traceback (most recent call last):
File "test-gql.py", line 38, in <module>
'myBlobField': img
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 119, in __init__
self._prepare_parts()
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 240, in _prepare_
parts
self.parts = [Part.from_field(f, enc) for f in self._iter_fields()]
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 488, in from_fiel
d
body = coerce_data(field.data, encoding)
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 466, in coerce_da
ta
return CustomBytesIO(data, encoding)
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 529, in __init__
buffer = encode_with(buffer, encoding)
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 410, in encode_wi
th
return string.encode(encoding)
AttributeError: 'JpegImageFile' object has no attribute 'encode'
我从 open()
docs 中知道它 returns 是一个 file
类型的对象,但我在 PIL
中看到的唯一方法是从 [=23] 转换=] 到 file
是通过使用 save()
将其写入磁盘。我可以写入磁盘,但我宁愿避免这一步,因为我要处理很多图像。
是否可以将 Image
对象转换为 file
类型?或者其他一些具有类似效果的解决方法?
MultipartEncoder
可以接受字节字符串或文件对象,但 PIL
图像对象两者都不是。
您必须先创建一个内存中文件对象:
from io import BytesIO
image_file = BytesIO()
img.save(image_file, "JPEG")
image_file.seek(0)
然后在 post:
中使用 image_file
'myBlobField': ('example.jpg', image_file, 'image/jpeg')
我正在尝试将我写的一些 javascript
代码转换为 Python
,但在传递数据时卡住了 b/t PIL
和 Requests
对象。
我的 python
脚本将图像下载到内存:
from PIL import Image
import urllib2
import cStringIO
def fetch_image_to_memory(url):
req = urllib2.Request(url, headers={
'User-Agent': "Mozilla / 5.0 (X11; U; Linux i686) Gecko / 20071127 Firefox / 2.0.0.11"})
con = urllib2.urlopen(req)
imgData = con.read()
return Image.open(cStringIO.StringIO(imgData))
然后我想将它添加到 form data
以进行 POST
操作。当文件在磁盘上时,此代码成功:
from requests_toolbelt import MultipartEncoder
import requests
url = 'https://us-west-2.api.scaphold.io/graphql/some-gql-endpoint'
multipart_data = MultipartEncoder(
fields={
'query':'some-graphql-specific-query-string',
'variables': '{ "input": {"blobFieldName": "myBlobField" }}',
## `variables.input.blobFieldName` must hold name
## of Form field w/ the file to be uploaded
'type': 'application/json',
'myBlobField': ('example.jpg', img, 'image/jpeg')
}
)
req_headers = {'Content-Type':multipart_data.content_type,
'Authorization':'Bearer secret-bearer-token'}
r = requests.post(url, data=multipart_data, headers=req_headers)
但是,当尝试从 fetch_image_to_memory
函数传入 Image
对象时:
'myBlobField': ('example.jpg', image_object, 'image/jpeg')
...我收到错误:
Traceback (most recent call last):
File "test-gql.py", line 38, in <module>
'myBlobField': img
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 119, in __init__
self._prepare_parts()
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 240, in _prepare_
parts
self.parts = [Part.from_field(f, enc) for f in self._iter_fields()]
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 488, in from_fiel
d
body = coerce_data(field.data, encoding)
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 466, in coerce_da
ta
return CustomBytesIO(data, encoding)
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 529, in __init__
buffer = encode_with(buffer, encoding)
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 410, in encode_wi
th
return string.encode(encoding)
AttributeError: 'JpegImageFile' object has no attribute 'encode'
我从 open()
docs 中知道它 returns 是一个 file
类型的对象,但我在 PIL
中看到的唯一方法是从 [=23] 转换=] 到 file
是通过使用 save()
将其写入磁盘。我可以写入磁盘,但我宁愿避免这一步,因为我要处理很多图像。
是否可以将 Image
对象转换为 file
类型?或者其他一些具有类似效果的解决方法?
MultipartEncoder
可以接受字节字符串或文件对象,但 PIL
图像对象两者都不是。
您必须先创建一个内存中文件对象:
from io import BytesIO
image_file = BytesIO()
img.save(image_file, "JPEG")
image_file.seek(0)
然后在 post:
中使用image_file
'myBlobField': ('example.jpg', image_file, 'image/jpeg')