Python 如何使用请求解决此AttributeError';s多部分表单数据发布?
我正在尝试将文件发布到我的Python 如何使用请求解决此AttributeError';s多部分表单数据发布?,python,python-2.7,python-requests,Python,Python 2.7,Python Requests,我正在尝试将文件发布到我的graphqlendpoint@scaphold.io。我通常编写Javascript,但我必须将此特定操作转换为Python 使用curl执行此操作的命令如下(): 其中variables中的blobFieldName属性与保存要上载的文件的表单字段名匹配 使用请求,我已经做到了这一点: import requests from requests_toolbelt import MultipartEncoder url = 'https://us-west-2.ap
graphql
endpoint@scaphold.io。我通常编写Javascript
,但我必须将此特定操作转换为Python
使用curl
执行此操作的命令如下():
其中variables
中的blobFieldName
属性与保存要上载的文件的表单
字段名匹配
使用请求
,我已经做到了这一点:
import requests
from requests_toolbelt import MultipartEncoder
url = 'https://us-west-2.api.scaphold.io/graphql/scaphold-graphql'
multipart_data = MultipartEncoder(
fields={
"query":"mutation CreateFile($input: CreateFileInput!) { createFile(input: $input) { changedFile { id name blobMimeType blobUrl user { id username } } } }",
"variables": { "input": { "name": "Profile Picture", "userId": "VXNlcjoxMA==", "blobFieldName": "myBlobField" } },
"type":'application/json',
"myBlobField": ('example.jpg', open('example.jpg', 'rb'), 'image/jpeg' )
}
)
req_headers = {'Content-Type':multipart_data.content_type, 'Authorization':'Bearer myreallylongkey'}
r = requests.post(url, data=multipart_data, headers=req_headers)
不幸的是,这遇到了属性错误:
Traceback (most recent call last):
File "test-gql.py", line 38, in <module>
"myBlobField": ('example.jpg', open('example.jpg', 'rb'), 'image/jpeg' )
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_field
body = coerce_data(field.data, encoding)
File "/home/bmp/code/wayhome/python-phash/requests_toolbelt/multipart/encoder.py", line 466, in coerce_data
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_with
return string.encode(encoding)
AttributeError: 'dict' object has no attribute 'encode'
回溯(最近一次呼叫最后一次):
文件“test gql.py”,第38行,在
“myBlobField”:('example.jpg',open('example.jpg','rb'),'image/jpeg')
文件“/home/bmp/code/wayhome/python phash/requests\u toolbelt/multipart/encoder.py”,第119行,在__
自行准备零件()
文件“/home/bmp/code/wayhome/python phash/requests\u toolbelt/multipart/encoder.py”,第240行,在“准备”部分中
self.parts=[self中f的Part.from_字段(f,enc).\u iter_字段()]
文件“/home/bmp/code/wayhome/python phash/requests\u toolbelt/multipart/encoder.py”,第488行,在from\u字段中
body=强制_数据(field.data,编码)
强制数据中的文件“/home/bmp/code/wayhome/python phash/requests\u toolbelt/multipart/encoder.py”,第466行
返回CustomBytesIO(数据、编码)
文件“/home/bmp/code/wayhome/python phash/requests\u toolbelt/multipart/encoder.py”,第529行,在__
缓冲区=使用(缓冲区,编码)编码
文件“/home/bmp/code/wayhome/python phash/requests_toolbelt/multipart/encoder.py”,第410行,在encode_中使用
返回字符串.encode(编码)
AttributeError:“dict”对象没有属性“encode”
恐怕我没有足够的能力去探究这个错误,但我已经排除了几个嫌疑犯:
- 将一个简单的
query
从curl
翻译成Python
很好,所以我知道这不是权限,等等
- 使用不同的
纯/文本
风格的文件失败,但出现相同错误
- 对于
字段(),使用元组的元组而不是dict
,没有效果
从您的示例中可以看出,您似乎将“变量”作为字典传递,但它应该是字符串。改变
"variables": { "input": { "name": "Profile Picture", "userId": "VXNlcjoxMA==", "blobFieldName": "myBlobField" } },
到
请注意使用单引号使其成为字符串
编辑::从MultipartEncoder的代码中,MultipartEncoder尝试对值运行.encode(…)方法。encode(…)带有字符串。因为键“variables”的值的数据类型是dict,.encode(…)似乎在这方面失败。从您的示例来看,您似乎将“variables”作为字典传递,但它应该是字符串。改变
"variables": { "input": { "name": "Profile Picture", "userId": "VXNlcjoxMA==", "blobFieldName": "myBlobField" } },
到
请注意使用单引号使其成为字符串
编辑::从MultipartEncoder的代码中,MultipartEncoder尝试对值运行.encode(…)方法。encode(…)带有字符串。因为键“variables”的值的数据类型是dict,.encode(…)似乎失败了。curl转换器:看看你的最后一个链接-它们使用tuple与文件=
,而不是数据=
@furas谢谢,这些转换器很棒(特别是第一个)。如果有人尝试,请注意:第二个转换器只支持Python3,而第一个转换器似乎错误地截断了带有=
字符的任何字符串。否则,其代码看起来是正确的。回复:文件
与数据
相比,我相信当使用多端口编码
时,参数会变为数据
。我可以说,data
在实现公认答案中的解决方案时起到了作用,至少。curl converters:请查看您的最后一个链接-它们使用tuple withfiles=
,而不是data=
@furas谢谢,这些转换器非常棒(特别是第一个)。如果有人尝试,请注意:第二个转换器只支持Python3,而第一个转换器似乎错误地截断了带有=
字符的任何字符串。否则,其代码看起来是正确的。回复:文件
与数据
相比,我相信当使用多端口编码
时,参数会变为数据
。我可以说,至少在公认的答案中实施解决方案时,数据
起了作用。
"variables": '{ "input": { "name": "Profile Picture", "userId": "VXNlcjoxMA==", "blobFieldName": "myBlobField" } }',