【问题标题】:How can I upload files through aiohttp using response from get request?如何使用 get 请求的响应通过 aiohttp 上传文件?
【发布时间】:2020-11-07 05:18:13
【问题描述】:

首先,我正在为 WordPress REST API 编写一个异步包装器。我有一个托管在 Bluehost 上的 Wordpress 网站。我正在使用端点进行媒体(图像)上传。我已经成功上传了一张图片,但我想做两处更改。第二个更改是我真正想要的,但出于好奇,我也想知道如何实现更改 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

我的另一个变化是我想要另一个功能,可以直接将文件上传到 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() 函数的示例中,我显然传入了 <_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 代码对它们的处理方式不同。

这也不重要,但this 是我传递给更改 2 示例的 url。

【问题讨论】:

    标签: python wordpress aiohttp python-aiofiles


    【解决方案1】:

    好的,所以我发现了这两个变化。

    对于尝试使用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)
    

    【讨论】:

    • 但这会将整个文件内容读入内存...我正在处理大文件并且需要流式传输它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-09
    • 2013-01-12
    • 2016-12-10
    • 2019-05-23
    相关资源
    最近更新 更多