Ошибка "There was an error parsing the body" в ответе

В ответ на POST запрос серверу возвращает 400 статус код, при этом я вроде бы правильно перевел код CURL в python, но он не работает (в cURL работает).

Response:

{"detail":"There was an error parsing the body"}

Мой код:

import requests

url = 'https://background-removal4.p.rapidapi.com/v1/results?mode=fg-image'

headers = {
    'content-type': "multipart/form-data; boundary=---0123456789",
    'x-rapidapi-key': "MY_API_KEY",
    'x-rapidapi-host': "background-removal4.p.rapidapi.com"
    }

with open('test.jpg', 'rb') as img:
    response = requests.post(
        url, headers=headers, files={'image': img})

print(response.text)

cURL:

curl --request POST \
    --url 'https://background-removal4.p.rapidapi.com/v1/results?mode=fg-image' \
    --header 'content-type: multipart/form-data; boundary=---0123456789' \
    --header 'x-rapidapi-host: background-removal4.p.rapidapi.com' \
    --header 'x-rapidapi-key: MY_API_KEY' \
    --form [email protected]

Помогите пожалуйста! Докуентация: https://rapidapi.com/api4ai-api4ai-default/api/background-removal4/ Код, предложенный автором не работает.


Ответы (2 шт):

Автор решения: Alexey

Проблема была решена следующим образом:

  1. Убран заголовок 'content-type';
  2. В кортеже были добавлены 'test.jpg' до переменной img, а также 'image/jpeg' и {'Expires': '0'} после неё в requests body (подробнее: https://stackoverflow.com/questions/21399845/mime-type-for-requests-post-file/21400085#21400085)

Код:

import requests
    
url = 'https://background-removal4.p.rapidapi.com/v1/results?mode=fg-image'
    
headers = {
    'x-rapidapi-key': "MY_API_KEY",
    'x-rapidapi-host': "background-removal4.p.rapidapi.com"
    }
    
with open('test.jpg', 'rb') as img:
    response = requests.post(
        url, headers=headers, files={'image': ('test.jpg', img, 'image/jpeg',  {'Expires': '0'})})
    
print(response.text)

Ответ сервера:

{"results":[{"status":{"code":"ok""message":"Success"}"name":"test.jpg""md5":"feaba5b7b5c71463d1684d596d203208""entities":[{"kind":"image""name":"general-fg-image""image":"BASE64 encoded image"}]}]}
→ Ссылка
Автор решения: Vlad

О документации RapidAPI

RapidAPI сам автоматически генерирует примеры использования API для множества языков и библиотек. К сожалению авторы не могут редактировать эти примеры. Поэтому некоторые авторы пишут свою документацию и выкладывают в раздел about. Вот, например, авторская документация для сервиса, которым вы хотели воспользоваться: https://rapidapi.com/api4ai-api4ai-default/api/background-removal4/details

Как послать изображение

Что касается непосредственно использования Background Removal API, то там используется обычный POST запрос multipart/form-data (такой же, какой отправляет HTML форма) с изображением в поле image.

Примеры на bash

Проще всего воспользоваться curl. Эта утилита сама угадает MIME-тип по расширению. Поэтому часть header-ов можно не указывать.

Просто послать изображение с помощью curl:

curl -X POST -F"image=@PATH_TO_YOUR_IMAGE.JPG" \
https://background-removal4.p.rapidapi.com/v1/results \
--header 'x-rapidapi-key: YOUR_RAPIDAPI_KEY'

Если у вас в системе есть утилиты jq и base64, то можно сразу сохранить полученное png изображение на диск с помощью этой команды:

curl -X POST -F"image=@PATH_TO_YOUR_IMAGE.JPG" \
https://background-removal4.p.rapidapi.com/v1/results \
--header 'x-rapidapi-key: YOUR_RAPIDAPI_KEY' -s | \
jq -r '.results[0].entities[0].image' | \
base64 -Dd -o PATH_TO_OUTPUT.PNG

Пример на Python с использование requests и mimetypes

Для определения MIME типов в Python можно воспользоваться модулем mimetypes:

import os
import requests
import mimetypes

URL = 'https://background-removal4.p.rapidapi.com/v1/results'
YOUR_RAPIDAPI_KEY = ...
PATH_TO_YOUR_IMAGE = ...

with open(PATH_TO_YOUR_IMAGE, 'rb') as img:
    mt = mimetypes.guess_type(PATH_TO_YOUR_IMAGE)[0]
    response = requests.post(
        URL,
        headers={'x-rapidapi-key': YOUR_RAPIDAPI_KEY},
        files={'image': (os.path.basename(PATH_TO_YOUR_IMAGE), img, mt)})

print(response.text)
→ Ссылка