Ошибка в коде [bot telegram]

У меня есть бот телеграмм который генерирует qr коды , но проблема в том что он не может переслать мне фотографию этого qr кода Вот сам код:

import os
from typing import Union

from PIL import Image

from utils.make_data.qrcode import make_image_qrcode


def make_emulator(code: Union[str, int]):

    if code[0] == 'E':
        code = code[1:]
    qrcode_img_dir = make_image_qrcode(f'E{code}')
    qrcode_img = Image.open(qrcode_img_dir)
    emulator_app = Image.open('./data/emulator/image.jpg')

    x1 = emulator_app.size[0] // 2 - qrcode_img.size[0] // 2
    x2 = emulator_app.size[0] // 2 + qrcode_img.size[0] // 2
    y1 = 590 - qrcode_img.size[1] // 2
    y2 = 590 + qrcode_img.size[1] // 2

    emulator_app.paste(qrcode_img, (x1, y1, x2, y2))
    emulator_dir = f'./data/tmp/emulator_{code}.png'
    emulator_app.save(emulator_dir)
    os.remove(qrcode_img_dir)
    return emulator_dir

А вот код самой ошибки:

qrcode None
[WinError 32] Процесс не может получить доступ к файлу, так как этот файл занят другим процессом: './data/tmp/emulator_1044680001.png'


код отправки сообщения:

import os
from asyncio import sleep
from random import randrange

from aiogram.types import Message, InputFile
from loguru import logger

from filters.private.content_message import DataCards
from loader import dp
from utils.database_api.schemes.card import DBCommandsCard
from utils.database_api.schemes.user import User
from utils.make_data.emulator_magnit import make_emulator
from utils.misc import rate_limit
from utils.parse_data.card import get_list_cards, get_code


@dp.message_handler(DataCards())
async def send_emulator(message: Message, user: User):
    data = message.text
    cards = get_list_cards(data)

    if len(cards) > 100:
        await message.answer(text='Слишком много , за раз бот может сгенерировать не больше 100 штрихов')
        return

    i = 0

    for card in cards:
        if i % 10 == 0 and i != 0:
            await message.answer(
                text=f'Сгенерировано: {i}/{len(cards)} \nПодождите 3 секунды :)'
            )
            await sleep(3)
        try:
            await sleep(0.4)
            i += 1
            data = card
            code = get_code(card)
            card = await DBCommandsCard.get_card(code=code)
            if card:
                await message.answer_photo(
                    photo=card.emulator,
                    caption=f'{card.code}'
                )
                continue
            emulator_dir = make_emulator(code)
            emulator = InputFile(emulator_dir)
            os.remove(emulator_dir)
            bot_message = await message.answer_photo(
                photo=emulator,
                caption=code
            )
            await DBCommandsCard.add_card(
                code=int(code),
                data=data,
                emulator=bot_message.photo[-1].file_id,
                user_id=user.id,
            )

        except Exception as err:
            await message.answer(
                text='Бот готов к работе\n'
                     'Подождите 1 секунду перед генерацие следующей карты'
                     f'Удалось сгенерировать qrcode {card}\n'
                     f'{err}'
            )
            await sleep(.7)

    await message.answer(
        text=f'Удалось сгенерировать {i} из {len(cards)} qrcode.'
    )

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

Автор решения: Andy Pavlov

Попробуйте вот так обернуть (только предварительно все процессы python у себя перезапустите):

import os
from typing import Union

from PIL import Image

from utils.make_data.qrcode import make_image_qrcode


def make_emulator(code: Union[str, int]):
    if code[0] == 'E':
        code = code[1:]
    qrcode_img_dir = make_image_qrcode(f'E{code}')
    with Image.open(qrcode_img_dir) as qrcode_img, Image.open('./data/emulator/image.jpg') as emulator_app:
        x1 = emulator_app.size[0] // 2 - qrcode_img.size[0] // 2
        x2 = emulator_app.size[0] // 2 + qrcode_img.size[0] // 2
        y1 = 590 - qrcode_img.size[1] // 2
        y2 = 590 + qrcode_img.size[1] // 2

        emulator_app.paste(qrcode_img, (x1, y1, x2, y2))
        emulator_dir = f'./data/tmp/emulator_{code}.png'
        emulator_app.save(emulator_dir)
    os.close(emulator_app.fileno())
    os.remove(qrcode_img_dir)
    return emulator_dir

Другой вариант создания qr-кода:

from typing import Union
from PIL import Image

import qrcode


def make_emulator(code: Union[str, int], background_filename: str = None):
    if code[0] == 'E':
        code = code[1:]

    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
    )
    qr.add_data(f'E{code}')
    qr.make(fit=True)
    qrcode_img = qr.make_image(fill_color=(55, 95, 35), back_color="transparent")  # создаем qr-код и его цвета

    emulator_dir = f'./data/temp/emulator_{code}.png'
    if background_filename:  # если задана подложка. Должна быть того же размера
        with Image.open(background_filename) as background:  # открываем подложку
            qrcode_img = Image.alpha_composite(background.convert("RGBA"), qrcode_img)  # совмещаем
    qrcode_img.save(emulator_dir)
    return emulator_dir


print(make_emulator('E600', 'адрес любой подложки того же размера.png'))  # с подложкой
print(make_emulator('E700'))  # без подложки
→ Ссылка