[英]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.