0
我正在嘗試將文件發佈到我的graphql
endpoint @ scaphold.io。我通常寫Javascript
,但我必須將這個特定操作轉換爲Python
。如何使用請求的多部分表單數據POST解決此AttributeError?
與curl
這樣做的命令如下(from their docs):
curl -v https://us-west-2.api.scaphold.io/graphql/scaphold-graphql \
-H "Content-Type:multipart/form-data" \
-F 'query=mutation CreateFile($input: CreateFileInput!) { createFile(input: $input) { changedFile { id name blobMimeType blobUrl user { id username } } } }' \
-F 'variables={ "input": { "name": "Profile Picture", "userId": "VXNlcjoxMA==", "blobFieldName": "myBlobField" } };type=application/json' \
-F [email protected]
凡blobFieldName
道具在variables
保存上傳文件Form
字段名稱相匹配。
使用Requests
,我這一步得到:
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)
不幸的是,這是會見了AttributeError
:
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'
我怕我不夠Python的神交此錯誤,但我已經消除了一些嫌疑人:
- 翻譯簡單
query
從curl
到Python
正常工作,所以我知道這是不是權限等 - 使用不同的文件,對
plain/text
味,失敗瓦特/同樣的錯誤 - 使用元組的元組,而不是對於
fields
一個dict
(as described here)沒有任何影響
curl轉換器:http://curl.trillworks.com/和https://shibukawa.github.io/curl_as_dsl/index.html – furas
看到你的最後一個鏈接 - 它們使用'files ='的元組,而不是' data =' – furas
@furas謝謝,這些轉換器很棒(尤其是第一個)。只需要注意其他人是否嘗試使用它們:第二個轉換器僅支持python 3,並且第一個轉換器似乎錯誤地截斷了帶有「=」字符的任何字符串。否則,其代碼看起來是正確的。 re:'files' vs'data',我相信在使用'MultpartEncoder'時,參數會變成'data'。至少,在接受答案中實施解決方案時,我可以說「數據」起作用。 – Brandon