Как сделать запуск функции каждый день в 08:00?

Если добавить команду, то функция через у команду работает. Как сделать чтобы эта функция запускалась, скажем, каждый день в 08:00?

def data_r_new(message):
    
    core.log(message.chat, message.text)
    conn = sqlite3.connect(settings.DATABASE)
    cursor = conn.cursor()
    sql = "SELECT * FROM dovidnyk WHERE strftime('%d-%m', data_r) = strftime('%d-%m', 'now')"
    cursor.execute(sql,)
    result = cursor.fetchall()

    for fn in result:
        sql = "SELECT user_id FROM user WHERE status = True"
        cursor.execute(sql,)
        result = cursor.fetchall()
        for i in result:
            dr = datetime.strptime(fn[6], '%Y-%m-%d %H:%M:%S').strftime('%d.%m.%Y')
            msg =  "<i>? <u>ПІБ</u></i>:  <b>{} {} {}</b>\n" \
                   "<i>? <u>Дата народження</u></i>:  <b>{}</b>\n".format(fn[3], fn[4], fn[5], dr)
            sent = bot.send_message(i[0], msg, reply_markup=keyboard, parse_mode='HTML')

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

Автор решения: Александр

Вы можете запускать свои скрипты в определенное время через python-rq. Эта библиотека довольно просто подключается:

from redis import Redis 
from rq import Queue 
q = Queue(connection=Redis())

И планируется:

q.enqueue_at(datetime(2021, 01, 20, 8, 0), data_r_new, message)

А с помощью функции enqueue_in можно задать интервал, через который функция будет выполняться

Библиотека имеет хорошую документацию, и не требует глубокого изучения. Является в какой-то степени альтернативой для известной celery.

Запускается так же отдельным процессом (для запуска с планировщиком необходимо задать дополнительный ключ):

rq worker --with-scheduler

P.S: В качестве альтернативы так же можете посмотреть в сторону dramatiq (поддерживает приоритеты задач и их запуск через заданный промежуток времени)

.

→ Ссылка
Автор решения: Vasyl Kolomiets

Как возможная альтернатива.

Первое. Вероятно, надо установить специальный модуль schedule. Он не входит в перечень стандартных модулей "из коробки".

$ pip install schedule

Второе. Добавить в программу следующее:

import schedule    
import time    
def job():    
    print("I'm working...")    
   
schedule.every().day.at("08:00").do(job) 

while True:
    schedule.run_pending()
    time.sleep(1)

Здесь - job - это ваша функцию, которую вы хотите выполнять в 8:00.

Есть еще модуль shed из стандартной библиотеки, но там время идет в секундах от начала эпохи и придется повозиться, с тем чтобы добавлять задачу на 8:00. Однако это может оказаться полезным упражнением и ничего дополнительно не надо устанавливать...

=== Альтернатива альтернативе ===
Используем модуль строенный модуль тайм time и смекалку :-).

import time

time.localtime()
Out[42]: time.struct_time(tm_year=2021, tm_mon=1, tm_mday=18, tm_hour=13, tm_min=7, tm_sec=22, tm_wday=0, tm_yday=18, tm_isdst=0)

time.localtime().tm_hour
Out[43]: 13

Как видите, несложно узнать текущее время, используя

.tm_hour .tm_min .tm_sec

например так:

import time

...
while True:
    time.sleep(1)
    z = time.localtime()    
    if z.tm_hour == 8  and z.tm_min == 0  and tm_sec == 0:
        print("Бимба")
→ Ссылка
Автор решения: 13_Voin

Первый вариант: Работает нормально с polling, но с flask не работает.

from multiprocessing import *
import schedule

def start_process():
    p1 = Process(target=P_schedule.start_schedule, args=()).start()

def start_schedule():
   schedule.every().day.at("08:00").do(data_r_new)
    
   while True:
        schedule.run_pending()
        time.sleep(1)

def data_r_new():
    ...... 

if __name__ == '__main__':
    start_process()
    bot.polling(none_stop=True)

Второй вариант: Работает нормально с flask.

from flask_apscheduler import APScheduler

def data_r_new():
    ...... 

scheduler = APScheduler()

if __name__ == '__main__':
    if not app.debug or os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
        scheduler.add_job(id ='data_r_mess_new', func = data_r_mess_new, trigger = 'cron', hour = 8, minute = 0, second = 0)
        scheduler.start()

ПС. Строка if not app.debug or os.... нужна для того чтобы не приходило сообщение два раза, когда во flask включен debug=True. Если debug не включен, эту строчку можно убрать.

→ Ссылка