[英]How can I upload files through aiohttp using response from get request?
首先,我正在為 WordPress REST API 編寫一個異步包裝器。我在 Bluehost 上托管了一個 Wordpress 網站。 我正在使用媒體(圖像)上傳端點。 我已成功上傳圖片,但我想進行 2 處更改。 第二個變化是我真正想要的,但出於好奇,我也想知道如何實施變化 1。 我會先提供代碼,然后再提供一些細節。
工作代碼
async def upload_local_pic2(self, local_url, date, title):
url = f'{self.base_url}/wp-json/wp/v2/media'
with aiohttp.MultipartWriter() as mpwriter:
json = {'title': title, 'status':'publish'}
mpwriter.append_json(json)
with open(local_url, 'rb') as f:
print(f)
payload = mpwriter.append(f)
async with self.session.post(url, data=payload) as response:
x = await response.read()
print(x)
變化 1
第一個變化是使用 aiofiles.open() 而不是僅僅使用 open() 上傳,因為我希望處理大量文件。 以下代碼不起作用。
async def upload_local_pic(self, local_url, date, title):
url = f'{self.base_url}/wp-json/wp/v2/media'
with aiohttp.MultipartWriter() as mpwriter:
json = {'title': title, 'status':'publish'}
mpwriter.append_json(json)
async with aiofiles.open(local_url, 'rb') as f:
print(f)
payload = mpwriter.append(f)
async with self.session.post(url, data=payload) as response:
x = await response.read()
print(x)
變2
我的另一個變化是我想再有一個function可以直接把文件上傳到WordPress的服務器,不用本地下載。 所以我不想獲取本地圖片,而是想傳入一張在線圖片的url。 以下代碼也不起作用。
async def upload_pic(self, image_url, date, title):
url = f'{self.base_url}/wp-json/wp/v2/media'
with aiohttp.MultipartWriter() as mpwriter:
json = {'title':title, 'status':'publish'}
mpwriter.append_json(json)
async with self.session.get(image_url) as image_response:
image_content = image_response.content
print(image_content)
payload = mpwriter.append(image_content)
async with self.session.post(url, data = payload) as response:
x = await response.read()
print(x)
細節/調試
我試圖弄清楚為什么每個都不起作用。 我認為關鍵是調用print(image_content)
和print(f)
顯示我輸入到mpwriter.append
的內容
在我只使用標准 Python open()
function 的示例中,我顯然傳入了<_io.BufferedReader name='/redactedfilepath/index.jpeg'>
在帶有 aiofile 的更改 1 示例中,我傳入<aiofiles.threadpool.binary.AsyncBufferedReader object at 0x7fb803122250>
Wordpress 將返回此 html:
b'<head><title>Not Acceptable.</title></head><body><h1>Not Acceptable.</h1><p>An appropriate representation of the requested resource could not be found on this server. This error was generated by Mod_Security.</p></body></html>'
最后,在更改 2 中,我嘗試將 get 請求傳遞給 url 給我,我得到了<StreamReader 292 bytes>
。 WordPress 返回的響應與上面的 Mod Security 相同。
知道如何使這些示例起作用嗎? 看起來它們都是某種類型的 io 閱讀器,但我猜底層 aiohttp 代碼對它們的處理方式不同。
此外,這並不重要, 但這是我傳遞給更改 2 示例的 url。
好的,所以我想出了兩個變化。
對於嘗試使用aiofiles
讀取文件時的第一個更改,我只需要讀取整個文件而不是傳入文件處理程序。 另外,我需要手動設置內容配置。
async def upload_local_pic(self, local_url, date, title):
url = f'{self.base_url}/wp-json/wp/v2/media'
with aiohttp.MultipartWriter() as mpwriter:
json = {'status':'publish'}
mpwriter.append_json(json)
async with aiofiles.open(local_url, mode='rb') as f:
contents = await f.read()
payload = mpwriter.append(contents)
payload.set_content_disposition('attachment', filename= title+'.jpg')
async with self.session.post(url, data=payload) as response:
x = await response.read()
print(x)
對於第二個更改,它是一個類似的概念,只是直接從 URL 上傳文件。 我需要先讀取整個內容,而不是傳入將讀取內容的處理程序。 我還需要手動設置內容配置。
async def upload_pic(self, image_url, date, title):
url = f'{self.base_url}/wp-json/wp/v2/media'
with aiohttp.MultipartWriter() as mpwriter:
json = {'status':'publish'}
mpwriter.append_json(json)
async with self.session.get(image_url) as image_response:
image_content = await image_response.read()
payload = mpwriter.append(image_content)
payload.set_content_disposition('attachment', filename=title+'.jpg')
async with self.session.post(url, data = payload) as response:
x = await response.read()
print(x)
我只會回答帖子的標題(而不是中間的問題)。
下面的代碼應該給出一個簡短的示例,說明如何將文件從 URL#1 上傳到 URL#2(無需將文件下載到本地計算機,然后才進行上傳)。
我在這里舉兩個例子:
示例 #1:一次讀取所有文件內容並上傳
import asyncio
import aiohttp
async def http_upload_from_url(src, dst):
async with aiohttp.ClientSession() as session:
src_resp = await session.get(src)
#print(src_resp)
dst_resp = await session.post(dst, data=src_resp.content)
#print(dst_resp)
try:
asyncio.run(http_upload_from_url(SRC_URL, DST_URL))
except Exception as e:
print(e)
示例 #2:以塊的形式讀取文件內容並上傳
import asyncio
import aiohttp
async def url_sender(url=None, chunk_size=65536):
async with aiohttp.ClientSession() as session:
resp = await session.get(url)
#print(resp)
async for chunk in resp.content.iter_chunked(chunk_size):
#print(f"send chunk with size {len(chunk)}")
yield chunk
async def chunked_http_upload_from_url(src, dst):
async with aiohttp.ClientSession() as session:
resp = await session.post(dst, data=url_sender(src))
#print(resp)
#print(await resp.text())
try:
asyncio.run(chunked_http_upload_from_url(SRC_URL, DST_URL))
except Exception as e:
print(e)
一些注意事項:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.