• Как обрабатывать свои события?

    Я бы в первую очередь прибегнул к такому подходу, однако не могу утверждать, что call_later работает так как предполагается с такими временными рамками. Обычно использовал с временными рамками до 2 минут
    Пример кода
    import asyncio
    import concurrent.futures
    from datetime import datetime, timedelta
    import os
    import shutil
    
    
    def delete_func():
        # Удаление временных файлов и создание каталога заново
        shutil.rmtree('tempfiles/')
        print('Folder deleted')
        os.mkdir(path='tempfiles/')
        print('Folder created')
    
    
    def repeat_delete():
        _loop = asyncio.get_running_loop()
        with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
            # Выполнение функции delete_func в отдельном потоке
            _loop.run_in_executor(executor, delete_func)
        # Вычисляем время до 4 утра следующего дня
        now = datetime.now()
        tomorrow_4am = datetime(now.year, now.month, now.day) + timedelta(days=1, hours=4)
        delta = tomorrow_4am - now
    
        # Выполняем повторный запуск repeat_delete через вычисленное время
        _loop.call_later(delta.total_seconds(), repeat_delete)
    
    
    async def main():
        ...
    
    
    if __name__ == '__main__':
        # Создание нового цикла событий asyncio
        loop = asyncio.new_event_loop()
        # Вызов repeat_delete через 1 секунду
        loop.call_later(1, repeat_delete)
        # Запуск основной функции
        loop.run_until_complete(main())
    Ответ написан
    Комментировать
  • Автоматизация запроса по API в звуковую нейросеть из Excel через python?

    import os
    # import time
    
    import requests
    from openpyxl import load_workbook
    from dotenv import load_dotenv
    
    API_URL = 'https://api.edenai.run/v2/audio/text_to_speech'
    HEADERS = {"Authorization": f"Bearer {os.getenv('API_KEY')}"}
    DEFAULT_LANGUAGE = 'ru-RU'
    DEFAULT_OPTION = 'MALE'
    DEFAULT_VOICE = 'ru-RU_Alexei Syomin'
    
    
    def convert_text_to_speech(row_number: int, _id: int, text: str):
        payload = {
            'providers': 'lovoai',
            'language': DEFAULT_LANGUAGE,
            'option': DEFAULT_OPTION,
            'lovoai': DEFAULT_VOICE,
            'text': text
        }
    
        response = requests.post(API_URL, json=payload, headers=HEADERS)
        result = response.json()
    
        audio_url = result.get('lovoai', {}).get('audio_resource_url')
        if audio_url:
            audio_content = requests.get(audio_url).content
            with open(f'row_{row_number}_ID_{_id}.ogg', 'wb') as audio_file:
                audio_file.write(audio_content)
    
    
    def main(file_name: str):
        book = load_workbook(file_name)
        sheet = book.active
        for row in range(2, sheet.max_row + 1):
            _id = sheet[row][0].value
            text = sheet[row][1].value
            convert_text_to_speech(row, _id, text)
    
            # Установите задержку, если имеется ограничение на кол-во запросов в секунду
            # time.sleep(3)
    
    
    if __name__ == '__main__':
        load_dotenv()
        main('name.xlsx')
    Ответ написан
    3 комментария
  • Кому отправил криптовалюту отправитель?

    Как осуществляются биткойн-транзакции

    Почитайте о вводах и выводах
    Ответ написан
    Комментировать
  • Как правильно регистрировать хендлеры для импорта?

    1. Не нашел в вашем тексте упоминаемого файла update.py
    2. В файле main.py вы пытаетесь зарегистрировать хендлеры в хендлере
    main.py
    import logging
    
    
    async def on_startup(dispatcher):
        logging.basicConfig(
            level=logging.DEBUG,
            format=u'%(filename)s:%(lineno)d #%(levelname)-8s [%(asctime)s] - %(name)s - %(message)s',
        )
        logger.info("Starting bot")
    
        # Импортируем функции регистрации хендлеров
        from update_photo import register_new_photo
        # Регистрируем хендлеры
        register_new_photo(dispatcher)
    
    
    async def on_shutdown(dispatcher):
        logging.warning('Shutting down..')
        await dispatcher.storage.close()
        await dispatcher.storage.wait_closed()
        logging.warning('Bye!')
    
    
    if __name__ == '__main__':
        from aiogram.utils import executor
        from loader import dp
    
        executor.start_polling(dp,
                               skip_updates=True,  # Если нужно пропускаем апдейты
                               on_startup=on_startup,
                               on_shutdown=on_shutdown)

    loader.py

    import os
    
    from aiogram import Bot, Dispatcher
    from aiogram.contrib.fsm_storage.memory import MemoryStorage
    
    bot = Bot(token=os.getenv("TOKEN"))
    storage = MemoryStorage()
    dp = Dispatcher(bot=bot, storage=storage)

    Ответ написан
  • Не могу понять в чем проблема, сохраняет только последние полученные данные, в чем дело?

    Вы создали 3 цикла, в которых перезаписываете значение переменной до добавления в лист, именно поэтому у вас сохраняется последнее значение.
    Также вместо создания трех циклов можно обойтись одним. (Вывод сделан на основании одинаковых селекторов переменных cards_hrefs, titles, prices).

    Изначальный ответ
    for items in data:    
        cards = data.find_all("div", class_="card-body")
        for card in cards:
            catalog.append({
                "link to the product": "https://scrapingclub.com" + card.find("a").get("href"),
                "title": card.find("h4").text.strip(),
                "price": card.find("h5").text.strip()
            })

    С верным замечанием от AUser0
    Обновленный ответ
    data = soup.find("div", class_="row my-4")
    
    catalog = []
    cards = data.find_all("div", class_="card-body")
    for card in cards:
        catalog.append({
            "link to the product": "https://scrapingclub.com" + card.find("a").get("href"),
            "title": card.find("h4").text.strip(),
            "price": card.find("h5").text.strip()
        })
    Ответ написан
    2 комментария
  • Как показать пользователю, что бот отправляет видео или фото?

    Вы не указали какую библиотеку используете, вот реф на документацию Bot API.
    sendChatAction
    Ищите данный метод в используемой библиотеке
    Ответ написан
    2 комментария
  • FSMStorageWarning?

    При инициализации dispatcher нужно передать в него storage
    from aiogram import Bot, Dispatcher, types
    # from aiogram.contrib.fsm_storage.memory import MemoryStorage
    from aiogram.contrib.fsm_storage.redis import RedisStorage2
    
    storage = RedisStorage2()
    # storage = MemoryStorage()
    
    bot = Bot(token=c.tg_bot.token, parse_mode=types.ParseMode.HTML)
    dp = Dispatcher(bot, storage=storage)

    UPD. При использовании redis на windows рекомендую устанавливать Memurai, так как есть поддержка redis 6, в некоторых случаях это избавит вас от проблем при переносе кода на Unix системы
    Ответ написан
    Комментировать
  • Как подключить приватный прокси к яндекс музыке?

    Вы не указали протокол прокси. На гитхабе указаны следующие примеры
    Примеры proxy url:
    
    socks5://user:password@host:port
    http://host:port
    https://host:port
    http://user:password@host
    Ответ написан
    Комментировать
  • Telegram bot Как назначить время и уведомить через заданное время?

    По правилам ресурса код стоит выкладывать текстом, оборачивая тэгом code.
    Вам подойдут очереди сообщений (rq, Celery, queue, asyncio.Queue).
    Примитивно ставить задачу в цикл событий.
    P.S. Рекомендую очереди
    @dp.message_handler(commands=['some_command'])
    async def some_handler(message: Message):
        text = 'Текст для отправки '
        DELAY = 10
        _loop = asyncio.get_running_loop()
        _loop.call_later(DELAY, func, message.from_user.id, text)
    
    async def func(chat_id, text):
        await dp.bot.send_message(chat_id, text)

    UPD Рекомендации
    1. Избавьтесь от n = int(input()). Вызов input блокирует выполнение кода, как и time.sleep
    2. Ознакомьтесь с встроенной в aiogram машиной состояний (FSM). Меняя state отлавливайте введенное пользователем число.
    3. Избавьтесь от конструкции try: except: проверяя является ли message.text числом
    if message.text.isdigit():
        print('ok')
    else:
        print('Это не число')
    Ответ написан
    4 комментария
  • Как преобразовать такой список словарей в Python?

    Умножив d_list на 100.000 у меня выполнилось за 0.6868....
    Не знаю на сколько "быстрым" такой результат можно назвать
    Первый вариант
    res = []
    for dictionary in d_list:  # * 100_000:
        result_dict = {}
        for key in dictionary:
            if dictionary[key] is not None:
                result_dict[key] = dictionary[key]
        result_dict = {**result_dict, **{'qty1': False, 'fp1': False,
                                         'qty2': False, 'fp2': False,
                                         'qty3': False, 'fp3': False}}
        if isinstance(dictionary['b'], list):
            for z in range(1, len(dictionary['b']) - 1):
                result_dict[f'qty{z}'] = dictionary['b'][z - 1]['qty']
                result_dict[f'fp{z}'] = dictionary['b'][z - 1]['fp']
    
        res.append(result_dict)

    Если все таки вы не ожидаете в результате значение ключа b в исходном виде.
    Выполнилось за 0.3226
    UPD
    res = []
    for dictionary in d_list:  # * 100_000:
        result_dict = {'a': dictionary['a'],
                       'c': dictionary['c'],
                       'qty1': False, 'fp1': False,
                       'qty2': False, 'fp2': False,
                       'qty3': False, 'fp3': False
                       }
        if isinstance(dictionary['b'], list):
            for z in range(1, len(dictionary['b']) - 1):
                result_dict[f'qty{z}'] = dictionary['b'][z - 1]['qty']
                result_dict[f'fp{z}'] = dictionary['b'][z - 1]['fp']
    
        res.append(result_dict)
    Ответ написан
    1 комментарий
  • Как запустить асинхронную функцию по расписанию python?

    if __name__ == '__main__':
        loop = asyncio.new_event_loop()
        scheduler = AsyncIOScheduler(event_loop=loop)
        scheduler.add_job(main, 'interval', seconds=3)
        scheduler.start()
        try:
            loop.run_forever()
        except (KeyboardInterrupt, SystemExit):
            pass

    Описание проблемы. (Как я это понял)
    Пример из github репозитория библиотеки ошибочен по двум причинам
    вызывается функция start(), которая сама выполняет get_event_loop()
    После этого в текущем потоке создается цикл событий.
    Далее в примере эти строки
    try:
        asyncio.get_event_loop().run_forever()
    except (KeyboardInterrupt, SystemExit):
        pass
    в результате мы получаем второй запущенный цикл событий из-за чего мы получаем DeprecationWarning: There is no current event loop
    Ответ написан
    4 комментария
  • Как соединиться с mysql, используя SSL файл и флаг verify identity?

    import asyncio
    import ssl
    
    
    ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
    # the root CA path is dependent on your system. 
    ctx.load_verify_locations(cafile='/etc/ssl/cert.pem')
    
    async def test_example(loop):
        pool = await aiomysql.create_pool(host='', port=3306, user='redst', password='',
                                      db='aiodb', loop=loop, ssl=ctx)
    Ответ написан
    Комментировать
  • Почему следующий код может иногда падать с runtime error?

    Код [запускался на Python 3.8, 3.9, 3.10]
    import asyncio
    import datetime
    import random
    import colorama
    
    
    async def main():
        t0 = datetime.datetime.now()
        print(colorama.Fore.WHITE + "App started.", flush=True)
    
        data = asyncio.Queue()
    
        task1 = asyncio.ensure_future(generate_data(20, data))
        task2 = asyncio.ensure_future(generate_data(20, data))
        task3 = asyncio.ensure_future(process_data(40, data))
        # Переименовано из "final_task" в "gather_result" т.к. gather возвращает результат (Список значений объектов)
        # В данном коде ничего не возвращается и можно удалить print и саму переменную
        gather_result = await asyncio.gather(task1, task2, task3)
        print(gather_result)
        dt = datetime.datetime.now() - t0
        print(colorama.Fore.WHITE + f"App exiting, total time: {dt.total_seconds():,.2f} sec.", flush=True)
    
    
    async def generate_data(num: int, data: asyncio.Queue):
        for idx in range(1, num + 1):
            item = idx * idx  # equal idx ** 2 
            await data.put((item, datetime.datetime.now()))
    
            print(colorama.Fore.YELLOW + f" -- generated item {idx}", flush=True)
            await asyncio.sleep(random.random() + 0.5)
    
    
    async def process_data(num: int, data: asyncio.Queue):
        processed = 0
        while processed < num:
            item = await data.get()
    
            processed += 1
            value = item[0]
            t = item[1]
            dt = datetime.datetime.now() - t
    
            print(colorama.Fore.CYAN + f" +++ Processed value {value} after {dt.total_seconds():,.2f} sec.", flush=True)
            await asyncio.sleep(0.5)
    
    
    if __name__ == '__main__':
        asyncio.run(main())

    Asyncio "Running Tasks Concurrently" gather
    asyncio.gather на русском
    Приведенный вами код актуален для Python 3.6 (Пункт 18.5.3.5.1. документации asyncio Python 3.6.15), но не для 3.7+
    Ответ написан
    1 комментарий
  • Почему возникает ошибка?

    Вы можете создать подобный класс.
    Пример реализации
    import asyncio
    import ssl
    from typing import Optional, Type
    
    import aiohttp
    import certifi
    import ujson as json
    
    
    class Scrapper:
        def __init__(self, connections_limit: int = None) -> None:
            self._session: Optional[aiohttp.ClientSession] = None
            self._connector_class: Type[aiohttp.TCPConnector] = aiohttp.TCPConnector
            ssl_context = ssl.create_default_context(cafile=certifi.where())
            self._connector_init = dict(limit=connections_limit, ssl=ssl_context)
    
        async def get_new_session(self) -> aiohttp.ClientSession:
            return aiohttp.ClientSession(
                connector=self._connector_class(**self._connector_init),
                json_serialize=json.dumps
            )
    
        async def get_session(self) -> Optional[aiohttp.ClientSession]:
            if self._session is None or self._session.closed:
                self._session = await self.get_new_session()
    
            if not self._session._loop.is_running():
                await self._session.close()
                self._session = await self.get_new_session()
            return self._session
    
        async def make_request(self, session, url, post, **kwargs):
            try:
                if post:
                    async with session.post(url, data=None, headers=None, **kwargs) as response:
                        try:
                            return await response.json()
                        except:
                            return response.text
                else:
                    async with session.get(url, params=None, headers=None, **kwargs) as response:
                        try:
                            return await response.json()
                        except:
                            return response.text
            except aiohttp.ClientError as e:
                print(f"aiohttp client throws an error: {e.__class__.__name__}: {e}")
    
        async def request(self, url: str, post: bool = False, **kwargs):
            return await self.make_request(await self.get_session(), url, post, **kwargs)
    
        async def get_access(self) -> None:
            return await self.request("https://google.com", False)
    
    
    scrapper = Scrapper()
    
    
    async def main():
        await scrapper.get_access()
    
    
    asyncio.run(main())
    Ответ написан
    Комментировать
  • Почему бот на aiogram молчит, пока выполняет действия?

    asyncio sleeping
    sleep() always suspends the current task, allowing other tasks to run.

    Наглядный пример выполнения
    Код
    import asyncio
    import time
    
    
    async def test(delay: int, number: int):
        print(f"Задача: {number}\n"
              f"Начато выполнение в {time.strftime('%X')}\n"
              f"Ждем {delay} секунд")
        await asyncio.sleep(delay)
        print(f"Закончили задачу {number} в {time.strftime('%X')}")
    
    
    async def startup():
        delays = [10, 8, 14, 5]
        for i, x in enumerate(delays):
            await test(x, i + 1)
    
    
    if __name__ == '__main__':
        asyncio.run(startup())

    Вывод
    Задача: 1
    Начато выполнение в 01:47:05
    Ждем 10 секунд
    Закончили задачу 1 в 01:47:15
    Задача: 2
    Начато выполнение в 01:47:15
    Ждем 8 секунд
    Закончили задачу 2 в 01:47:23
    Задача: 3
    Начато выполнение в 01:47:23
    Ждем 14 секунд
    Закончили задачу 3 в 01:47:37
    Задача: 4
    Начато выполнение в 01:47:37
    Ждем 5 секунд
    Закончили задачу 4 в 01:47:42

    Можете считать, что в данном случае await asyncio.sleep(delay) является блокирующей функцией
    Ответ написан
  • Как сделать так чтобы инлайн кнопки не дублировались aiogram?

    Кнопки у вас добавляются лишние потому что вы просто каждый раз добавляете в InlineKeyboardMarkup кнопку, а keyboard_bar_inline_tarif_buy_status у вас глобальная переменная
    Нужно вынести создание клавиатуры в отдельную функцию.
    Также логику как-то переработать обращения к бд и самих кнопок, текста и callback'а
    @dp.message_handler(lambda message: message.text == ' Мои покупки')
    async def buy_status(message : types.Message):
        await bot.send_message(message.from_user.id, f' Ваши купленные паки:', reply_markup=keyboard_bar_inline_tarif_buy_status(), parse_mode='Markdown')
        
    def keyboard_bar_inline_tarif_buy_status():
        kb = InlineKeyboardMarkup(row_width=1)
        for i in range(1, 7):
            cur.execute(f'SELECT TARIF{i} FROM users')
            data_total = cur.fetchone()
            if data_total[0] == 'PAID':
                kb.add(InlineKeyboardButton(text=f'{i}', callback_data=f'pay{i}'))
        return kb
    Ответ написан
    Комментировать
  • Как вернуться к первому состоянию в Aiogram?

    У команды start нет состояния
    await state.finish()
    Либо назначайте состояние ввода имени
    await state.set_state(reg.name)
    Но не забудьте, что у пользователя должна быть возможность выйти из состояния самостоятельно
    Ответ написан
    4 комментария
  • Как остановить цикл при вводе последующей команы AIOGRAM (Python)?

    Не надо использовать цикл while в асинхронном коде, да и в целом если бот рассчитан на более чем одного пользователя
    Используйте storage
    from aiogram.contrib.fsm_storage.memory import MemoryStorage
    
    storage = MemoryStorage()

    from aiogram.dispatcher import FSMContext
    
    @dp.message_handler(commands=['start'])
    async def start(message: types.Message,  state=FSMContext):
        await message.answer('Вы ввели команду /start, введите команду /stop или /cancel чтобы выйти из меню')
        await state.set_state(YourState.name_state)
    
    @dp.message_handler(commands=['stop'], state=YourState.name_state)
    async def stop(message: types.Message,  state=FSMContext):
        await message.answer('Вы ввели команду /stop')
        await state.finish()
    
    @dp.message_handler(commands=['cancel'], state='*')
    async def cancel(message: types.Message,  state=FSMContext):
        current_state = await state.get_state()
        if current_state is None:
            return
        await state.finish()
        await message.answer('Вы ввели команду /cancel')
    Ответ написан
    Комментировать
  • Как обновить таблицу SQLite нажатием inline кнопки в телеграм боте?

    Замените
    @dp.callback_query_handler(text='testit')
    На
    @dp.callback_query_handler(lambda c: c.data == 'testit')

    Ваш декоратор был правильным для отслеживания KeyboardButton, но не для InlineKeyboardButton
    Ответ написан
    Комментировать