Преобразование PDF в DOCX с помощью Adobe PDF Services через REST API (с Python)

Я пытаюсь запросить API служб Adobe PDF для создания (экспорта) DOCX из документов PDF.

Я только что написал код на Python для создания токена на предъявителя , чтобы его можно было идентифицировать из служб Adobe PDF (см. Вопрос здесь: https://stackoverflow.com/questions/68351955/tunning-a-post-request-to-reach- Adobe-pdf-services-using-python-and-a-rest-api). Затем я написал следующий фрагмент кода, в котором попытался следовать инструкциям на этой странице, касающимся EXPORTвариант служб Adobe PDF (здесь: https://documentcloud.adobe.com/document-services/index.html#post-exportPDF ).

Вот фрагмент кода:

      import requests
import json
from requests.structures import CaseInsensitiveDict
N / B: я не писал часть кода, генерирующего токен и разрешающего идентификацию сервером
>> Эта часть представляет собой POST-запрос на загрузку моего PDF-файла с помощью параметров формы.
      URL = "https://cpf-ue1.adobe.io/ops/:create?respondWith=%257B%2522reltype%2522%253A%2520%2522http%253A%252F%252Fns.adobe.com%252Frel%252Fprimary%2522%257D"

headers = CaseInsensitiveDict()
headers["x-api-key"] = "client_id"
headers["Authorization"] = "Bearer MYREALLYLONGTOKENIGOT"
headers["Content-Type"] = "application/json"

myfile = {"file":open("absolute_path_to_the_pdf_file/input.pdf", "rb")}

j="""
{
  "cpf:engine": {
    "repo:assetId": "urn:aaid:cpf:Service-26c7fda2890b44ad9a82714682e35888"
  },
  "cpf:inputs": {
    "params": {
      "cpf:inline": {
        "targetFormat": "docx"
      }
    },
    "documentIn": {
      "dc:format": "application/pdf",
      "cpf:location": "C:/Users/a-bensghir/Downloads/P_D_F/trs_pdf_file_copy.pdf"
    }
  },
  "cpf:outputs": {
    "documentOut": {
      "dc:format": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "cpf:location": "C:/Users/a-bensghir/Downloads/P_D_F/output.docx"
    }
  }
}"""

resp = requests.post(url=URL, headers=headers, json=json.dumps(j), files=myfile)
   

print(resp.text)
print(resp.status_code)

Статус кода - 400. Я хорошо аутентифицирован сервером. Но в результате print(resp.text) :

      {"requestId":"the_request_id","type":"Bad Request","title":"Not a multipart request. Aborting.","status":400,"report":"{\"error_code\":\"INVALID_MULTIPART_REQUEST\"}"}

Я думаю, что у меня проблемы с пониманием «параметров формы» из Руководства Adobe относительно метода POST для задания EXPORT API (https://documentcloud.adobe.com/document-services/index.html).

Есть ли у вас идеи по улучшению. Спасибо !

2 ответа

Решение

Сделайте вас переменным j как питон dictсначала создайте из него строку JSON. Что также не совсем ясно из документации Adobe, так это ценность documentIn.cpf:locationдолжен быть таким же, как ключ, используемый для вашего файла. Я исправил это на InputFile0в вашем сценарии. Также предполагаю, что вы хотите сохранить свой файл, поэтому я тоже добавил его.

      import requests
import json
import time

URL = "https://cpf-ue1.adobe.io/ops/:create?respondWith=%257B%2522reltype%2522%253A%2520%2522http%253A%252F%252Fns.adobe.com%252Frel%252Fprimary%2522%257D"

headers = {
    'Authorization': f'Bearer {token}',
    'Accept': 'application/json, text/plain, */*',
    'x-api-key': client_id,
    'Prefer': "respond-async,wait=0",
}

myfile = {"InputFile0":open("absolute_path_to_the_pdf_file/input.pdf", "rb")}

j={
  "cpf:engine": {
    "repo:assetId": "urn:aaid:cpf:Service-26c7fda2890b44ad9a82714682e35888"
  },
  "cpf:inputs": {
    "params": {
      "cpf:inline": {
        "targetFormat": "docx"
      }
    },
    "documentIn": {
      "dc:format": "application/pdf",
      "cpf:location": "InputFile0"
    }
  },
  "cpf:outputs": {
    "documentOut": {
      "dc:format": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "cpf:location": "C:/Users/a-bensghir/Downloads/P_D_F/output.docx"
    }
  }
}

body = {"contentAnalyzerRequests": json.dumps(j)}

resp = requests.post(url=URL, headers=headers, data=body, files=myfile)
   

print(resp.text)
print(resp.status_code)

poll = True
while poll:
    new_request = requests.get(resp.headers['location'], headers=headers)
    if new_request.status_code == 200:
        open('test.docx', 'wb').write(new_request.content)
        poll = False
    else:
        time.sleep(5)

Я не знаю, почему файл docx (кстати, он хорошо создан) не открывается, сообщая через всплывающее окно, что содержимое не читается. может быть, это из-за 'wb'методы синтаксического анализа

Я была такая же проблема. Приведение типов к «байтам» содержимого запроса решило эту проблему.

      poll = True
    while poll:
        new_request = requests.get(resp.headers['location'], headers=headers)
        if new_request.status_code == 200:
            with open('test.docx', 'wb') as f:
                f.write(bytes(new_request.content))
            poll = False
        else:
            time.sleep(5)
Другие вопросы по тегам