python - 如何将带有base64图像文件的流请求管理为json数据响应?

标签 python python-requests

我向服务器发出 requests.post() 调用,服务器用 json 回复我,在这个 json 中有一些键以及 base64 文件。

这是服务器响应的示例:

服务器响应如下:

  • 'success' 是了解私有(private)数据访问是否有效的关键 正确。
  • 'message' 是成功为 False 时的关键(在本例中为 success == True,消息不显示
  • 'data' 是包含文件名和文件名的字典键 Base64格式文件

所以:

{'success': True,
 'message': '',
 'data': {'fileName': 'Python_logo_and_wordmark.svg.png',
          'file': 'iVBORw0KGgoAAAANSUhEUgAABLAAAA....'}} #To limit the space, I cut the very long bytes example

因此 json 中的 respose 也包含该文件,我需要使用 base64.b64decode(r.json()['data']['file']) 进行解码

一切正常,我可以获取我的文件并正确解密。

问题是,对于大文件,我想使用如下的流方法:

file = "G:\Python_logo_and_wordmark.svg.png"
if os.path.isfile(file):
    os.remove(file)

def get_chunk(chunk):

    # Try to decode the base64 file (Chunked)
    # is this a wrong approach?
    chunk = chunk.decode("ascii")
    chunk = chunk.replace('"', '')
    if "file" in chunk:
        chunk = chunk.split('file:')[1]
    elif "}}" in chunk:
        chunk = chunk.split('}}')[0]
    else:
        chunk = chunk
    
    chunk += "=" * ((4 - len(chunk) % 4) % 4)
    chunk_decoded = base64.b64decode(chunk)
    return chunk_decoded

r = requests.post(url=my_url, json=my_data, stream=True)

iter_content = r.iter_content(chunk_size=64)
    
while True:
    chunk = next(iter_content, None)
    if not chunk:
        break
    chunk_decoded = get_chunk(chunk)

    with open(file, "ab") as file_object:
        file_object.write(chunk_decoded)

iter_content block 返回此:

b'{"success":true,"message":"","data":{"fileName":"Python_logo_and'
b'_wordmark.svg.png","file":"iVBORw0KGgoAAAANSUhEUgAABLAAAAFkCAYAA'
b'AAwtsJRAAAABGdBTUEAALGPC\\/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAA'
b'dTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA\\/wD\\/AP+gvaeTAACAAElEQVR42u'
b'zdeZwbdf0\\/8Nf7k2Ovdttyt7QIggoth1qUW1AQ5PLeAiK13UwWiqLiBZ4Eb+T6+'

有时在解码过程中填充会存在固有的错误,但经过 1 周的尝试后,我更愿意在这里问这个问题,因为我担心对这种情况采取错误的方法。 我想知道如何以正确的方式处理这种情况

最佳答案

根据您在评论中提到的要求,我指出以下当前问题和 future 可能出现的问题:

在您的 get_chunck 函数中,您正在执行以下操作:

chunk = chunk.decode("ascii")
chunk = chunk.replace('"', '')
if "file" in chunk:
    chunk = chunk.split('file:')[1]
elif "}}" in chunk:
    chunk = chunk.split('}}')[0]
else:
    chunk = chunk

现在查看由 iter_line 给出的第一个 block :

b'{"success":true,"message":"","data":{"fileName":"Python_logo_and'
  1. 因此,它将属于 if "file"in chunk: 条件,因为它在 fileName 中包含此 file 字符串。因此,当它尝试根据 file: 拆分此文件时,它将返回一个包含一个元素的列表,因为 file 位于 fileName 中,不是文件:。因此程序将出现以下错误:
Traceback (most recent call last):
  File "main.py", line 7, in <module>
    chunk = chunk.split('file:')[1]
IndexError: list index out of range

尝试使用 if "file:"in chunk: 来代替。

  • 如果 fileName 包含类似“prod_file:someName”的内容,您的程序也可能会失败。您也必须检查这一点。

  • 不包含文件的 block 可以包含 }},因此它也可能会破坏您想要实现的目标。

  • 您可以修改响应服务器并使用唯一标识符包装文件base64编码字符串的开头和结尾,以便您可以收到如下响应,从而可以在此流方法中保证识别文件的开头和结尾。例如:

    {'success': True,
     'message': '',
     'data': {'fileName': 'Python_logo_and_wordmark.svg.png',
              'file': '0000101100iVBORw0KGgoAAAANSUhEUgAABLAAAA....0000101101'}}
    

    我已附加 0000101100 作为起始标识符,并附加 0000101101 作为结束标识符。您可以在写入 block /文件时修剪它们。您可以使用任何其他唯一标识符格式作为您自己的唯一标识符格式,而不与 base64 编码冲突。

    如果还有任何困惑,请随时询问。

    关于python - 如何将带有base64图像文件的流请求管理为json数据响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68740486/

    相关文章:

    python - Airflow:如何将 PyMySQL 与 MySQL Hook 结合使用?

    python - 如何在 Python 中从生成表格的网站进行网页抓取?

    python - Python中的正则表达式抓取特殊字符之前的所有文本

    python - 关于 autocorrelation_plot 结果与 autocorr 结果的问题

    python - 最大化 PIL 逊相关性,损失函数应该是什么

    python - grequests 以什么方式异步?

    Python 请求带有 Unicode 参数的 URL

    Python-Requests,从字符串中提取url参数

    python - 同时进行多个异步请求

    python - 从命令行运行脚本时无法播放pygame.mixer声音