Использование Python для загрузки аватара (Discourse API)

Привет :waving_hand:,

Я прочитал эти полезные посты (1, 2), однако мне всё ещё чего-то не хватает, из-за чего не удаётся успешно загрузить аватар из Python в Discourse через API. Я являюсь администратором своего сайта Discourse.

Хорошая новость: В Postman всё работает, как показано ниже.

Не очень хорошая новость: Мне не удалось перенести это в Python (получаю ошибки 400 или 422 в зависимости от того, что пытаюсь сделать). Я пробовал следующее:

img_data = requests.get("my_image_url").content

data={
"type": "avatar",
"user_id": user_id,
"synchronous": True,
"file":  img_data
}

url = "<my site>/uploads.json"

response = requests.request("POST", url, headers=headers, data=data)

Это выдаёт ошибку 400. Также я пробовал использовать локальное изображение, чтобы проверить, получится ли это сделать:

with open('my_local_image.jpg', "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode("utf8")

data={
"type": "avatar",
"user_id": user_id,
"synchronous": True,
"file":  image_b64
}

url = "<my site>/uploads.json"

response = requests.request("POST", url, headers=headers, data=data)

Это выдаёт ошибку 422:

"failed":"FAILED","message":"undefined method `tempfile\' for #\\u003cString:0x00007f5befda7af8\\u003e"

:folded_hands: Чувствую, что я уже близко к решению, но я ещё новичок в работе с API. Любая подсказка в правильном направлении будет очень кстати!

О! Я обнаружил здесь, что можно использовать параметр “url” следующим образом:

data={
"type": "avatar",
"user_id": user_id,
"synchronous": True,
"url":  "url_to_my_image"
}

url = "<my_site>/uploads.json"

response = requests.request("POST", url, headers=headers, data=data)

Наконец-то я получил ответ 200!

Теперь я знаю, что есть второй шаг, который нужно выполнить, чтобы завершить этот процесс :thinking:, давайте посмотрим, что можно сделать…

Да! Я разобрался со вторым шагом!

url = "<my_site>/users/<username>/preferences/avatar/pick.json"

data={
"upload_id": '<id_from_the_1st_step>',
"type":  'uploaded'
}

response = requests.request("PUT", url, headers=headers, data=data)

Отлично! :heart: