Некоторый способ преобразовать строковое представление PDF в байты в Python - PullRequest
0 голосов
/ 06 сентября 2018

Я на самом деле пытаюсь сделать что-то, чего не знаю, нормально ли это.

Проблема:

У меня есть веб-клиент и веб-сервер, сервер (написанный на pythonwith flask) обрабатывает файл pdf для получения некоторых данных, а клиент просто отправляет файл pdf и ожидает ответа.Суть в том, что клиент может отправлять различные pdf-файлы для обработки, и я хочу отправить все pdf-файлы с клиента на сервер всего за один запрос.

Что я планировал сделать:

Я думал о том, чтобы преобразовать Blob каждого pdf в строку и отправить запрос POST с телом JSON следующим образом:

BODY:
  {
    "content":[
        {"name": "pdf_name_1.pdf", "data": "some blob data converted to string"},
        {"name": "pdf_name_2.pdf", "data": "some blob data converted to string"},
        {"name": "pdf_name_3.pdf", "data": "some blob data converted to string"},
        ...
    ]
}

Итак, на сервере я думал преобразоватьснова данные в большой двоичный объект (байты), чтобы записать pdf-файл и начать обработку данных.

Мой вопрос:

Есть ли способ преобразовать str-представление pdfв байты для того, чтобы записать на диск pdf с python?

Большое спасибо, если кто-то придумает другую идею отправить pdf в одном запросе, дайте мне знать, пожалуйста.

pd: я использую python 3.5 и Flask для веб-сервера.

1 Ответ

0 голосов
/ 06 сентября 2018

В таких случаях предпочтительно передавать данные файла, передавая их с ключевым словом files , например:

import requests


def send_pdf_data(filename_list, encoded_pdf_data):
    files = {}

    for (filename, encoded, index) in zip(filename_list, encoded_pdf_data, range(len(filename_list))):
        files[f"pdf_name_[index].pdf"] = (filename, open(filename, 'rb'), 'application/pdf')

    data = {}
    # *Put whatever you want in data dict*

    requests.post("http://yourserveradders", data=data, files=files)


def main():
    filename_list = ["pdf_name_1.pdf", "pdf_name_2.pdf"]
    pdf_blob_data = [open(filename, 'wb').read() for filename
                     in filename_list]

if __name__ == '__main__':
    main()

Однако, если вы действительно хотите передать данные как json, вы должны использовать модуль base-64, как упоминалось в @Mark Ransom.

Вы можете реализовать это следующим образом:

import requests
import json
import base64


def encode(data: bytes):
    """
    Return base-64 encoded value of binary data.
    """
    return base64.b64encode(data)


def decode(data: str):
    """
    Return decoded value of a base-64 encoded string.
    """
    return base64.b64decode(data.encode())


def get_pdf_data(filename):
    """
    Open pdf file in binary mode,
    return a string encoded in base-64.
    """
    with open(filename, 'rb') as file:
        return encode(file.read())


def send_pdf_data(filename_list, encoded_pdf_data):
    data = {}
    # *Put whatever you want in data dict*
    # Create content dict.
    content = [dict([("name", filename), ("data", pdf_data)])
               for (filename, data) in zip(filename_list, encoded_pdf_data)]
    data["content"] = content

    data = json.dumps(data) # Convert it to json.
    requests.post("http://yourserveradders", data=data)


def main():
    filename_list = ["pdf_name_1.pdf", "pdf_name_2.pdf"]
    pdf_blob_data = [get_pdf_data(filename) for filename
                     in filename_list]

if __name__ == '__main__':
    main()
...