V
V
Vast Nectarine2020-04-09 14:13:08
Python
Vast Nectarine, 2020-04-09 14:13:08

Why can't I upload a photo to VKontakte?

There is such a code. It works, it can upload images to the server asynchronously, but I don't want to create unnecessary files, so I use BytesIO

import ...

image_url = '...'
vk_session = vk_api.VkApi(token=TOKEN)
api = vk_session.get_api()

upload_url = api.photos.getMessagesUploadServer()['upload_url']

with open('/tmp/photo.jpg', 'wb') as f:
    f.write(httpx.get(image_url).content)
files = {'photo': open('/tmp/photo.jpg', 'rb')}

async def fetch(url, file):
    async with httpx.AsyncClient() as client:
        s = await client.post(url, files=file)
        return s.json()


async def main():
    responses = await asyncio.ensure_future(fetch(upload_url, files))
    print(responses)

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


But the code doesn't work with BytesIO, the 'photo' field is empty
import ...
image_url = '...'
vk_session = vk_api.VkApi(token=TOKEN)
api = vk_session.get_api()

upload_url = api.photos.getMessagesUploadServer()['upload_url']

files = {'photo': BytesIO(httpx.get(image_url).content)}

async def fetch(url, file):
    async with httpx.AsyncClient() as client:
        s = await client.post(url, files=file)
        return s.json()


async def main():
    responses = await asyncio.ensure_future(fetch(upload_url, files))
    print(responses)


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

The answer is not an error, but the 'photo' field is empty. Why is this happening? How to upload photos to VKontakte servers without creating temporary files?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitri, 2020-04-10
@dmitriy337

Isn't it easier to make a file, upload it and delete it right away?

D
Dev12345, 2020-04-27
@Dev12345

You can upload photos like this, using the VkUpload method:

from vk_api import VkUpload

upload = VkUpload(vk_session)
send = upload.photo_messages(photos='название фотографии')
attach = "photo{}_{}".format(send[0]["owner_id"], send[0]["id"])

In messages.send in attachments you pass attach.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question