파이썬에서 스케줄러와 같은 Cron을 얻는 방법은 무엇입니까? [닫은]

기능 을 제공 at하고 cron좋아할 파이썬 라이브러리를 찾고 있습니다.

상자에 설치된 도구에 의존하기보다는 순수한 파이썬 솔루션을 원합니다. 이 방법으로 나는 cron이없는 컴퓨터에서 실행합니다.

익숙하지 않은 사람들을 위해 다음 cron과 같은 표현을 기반으로 작업을 예약 할 수 있습니다.

 0 2 * * 7 /usr/bin/run-backup # run the backups at 0200 on Every Sunday
 0 9-17/2 * * 1-5 /usr/bin/purge-temps # run the purge temps command, every 2 hours between 9am and 5pm on Mondays to Fridays.

cron 시간 표현 구문은 덜 중요하지만 이러한 종류의 유연성을 가진 것을 원합니다.

기본적으로 나를 위해 이것을 수행하는 것이 없다면 빌딩 블록이 이와 같은 것을 만들기위한 제안은 감사하게받을 것입니다.

편집
프로세스 시작에 관심이없고 파이썬으로 작성된 “작업”-파이썬 함수에 관심이 있습니다. 필연적으로 나는 이것이 다른 스레드 일 것이라고 생각하지만 다른 프로세스에는 없습니다.

이를 위해 cron 시간 표현의 표현력을 찾고 있지만 Python에서는 찾고 있습니다.

Cron 수년 동안 사용되어 왔지만 가능한 한 휴대하기 위해 노력하고 있습니다. 나는 그 존재에 의존 할 수 없습니다.



답변

가벼운 결제 일정을 찾고 있다면 :

import schedule
import time

def job():
    print("I'm working...")

schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)

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

공개 : 나는 그 도서관의 저자입니다.


답변

일반 Python 인수 전달 구문을 사용하여 crontab을 지정할 수 있습니다. 예를 들어, 아래와 같이 Event 클래스를 정의한다고 가정하십시오.

from datetime import datetime, timedelta
import time

# Some utility classes / functions first
class AllMatch(set):
    """Universal set - match everything"""
    def __contains__(self, item): return True

allMatch = AllMatch()

def conv_to_set(obj):  # Allow single integer to be provided
    if isinstance(obj, (int,long)):
        return set([obj])  # Single item
    if not isinstance(obj, set):
        obj = set(obj)
    return obj

# The actual Event class
class Event(object):
    def __init__(self, action, min=allMatch, hour=allMatch,
                       day=allMatch, month=allMatch, dow=allMatch,
                       args=(), kwargs={}):
        self.mins = conv_to_set(min)
        self.hours= conv_to_set(hour)
        self.days = conv_to_set(day)
        self.months = conv_to_set(month)
        self.dow = conv_to_set(dow)
        self.action = action
        self.args = args
        self.kwargs = kwargs

    def matchtime(self, t):
        """Return True if this event should trigger at the specified datetime"""
        return ((t.minute     in self.mins) and
                (t.hour       in self.hours) and
                (t.day        in self.days) and
                (t.month      in self.months) and
                (t.weekday()  in self.dow))

    def check(self, t):
        if self.matchtime(t):
            self.action(*self.args, **self.kwargs)

(참고 : 철저히 테스트되지 않았습니다)

그런 다음 CronTab을 일반적인 파이썬 구문으로 다음과 같이 지정할 수 있습니다.

c = CronTab(
  Event(perform_backup, 0, 2, dow=6 ),
  Event(purge_temps, 0, range(9,18,2), dow=range(0,5))
)

이렇게하면 파이썬의 인수 역학을 최대한 활용할 수 있습니다 (위치 및 키워드 인수를 혼합하고 주 및 월 이름에 기호 이름을 사용할 수 있음)

CronTab 클래스는 분 단위로 잠자고 각 이벤트에서 check ()를 호출하는 것으로 정의됩니다. (아마도 일광 절약 시간 / 시간대에주의해야 할 미묘한 부분이 있습니다). 빠른 구현은 다음과 같습니다.

class CronTab(object):
    def __init__(self, *events):
        self.events = events

    def run(self):
        t=datetime(*datetime.now().timetuple()[:5])
        while 1:
            for e in self.events:
                e.check(t)

            t += timedelta(minutes=1)
            while datetime.now() < t:
                time.sleep((t - datetime.now()).seconds)

주의해야 할 몇 가지 사항 : 파이썬의 주중 / 월은 0으로 색인화되며 (크론과 달리) 해당 범위는 마지막 요소를 제외하므로 “1-5″와 같은 구문은 range (0,5)가됩니다. 즉 [0,1,2, 3,4]. cron 구문을 선호한다면 구문 분석이 너무 어렵지 않아야합니다.


답변

아마도 이것은 질문을 한 후에 만 ​​났을 것입니다. 나는 완전성을 위해 그것을 언급했다고 생각했습니다 : https://apscheduler.readthedocs.org/en/latest/


답변

필자가 찾은 것 중 하나는 파이썬 sched모듈인데, 이것은 당신이 찾고있는 종류 일 수 있습니다.


답변

“… crontab 파일을 읽고 쓰고 Crontab 파일을 자동적이고 간단하게 직접 API를 사용하여 시스템 cron에 액세스하기위한 Crontab 모듈 …”

http://pypi.python.org/pypi/python-crontab

또한 파이썬 패키지 인 APScheduler도 있습니다. 이미 작성 및 디버깅되었습니다.

http://packages.python.org/APScheduler/cronschedule.html


답변

위와 다소 비슷하지만 gevent :)를 사용하여 동시에

"""Gevent based crontab implementation"""

from datetime import datetime, timedelta
import gevent

# Some utility classes / functions first
def conv_to_set(obj):
    """Converts to set allowing single integer to be provided"""

    if isinstance(obj, (int, long)):
        return set([obj])  # Single item
    if not isinstance(obj, set):
        obj = set(obj)
    return obj

class AllMatch(set):
    """Universal set - match everything"""
    def __contains__(self, item):
        return True

allMatch = AllMatch()

class Event(object):
    """The Actual Event Class"""

    def __init__(self, action, minute=allMatch, hour=allMatch,
                       day=allMatch, month=allMatch, daysofweek=allMatch,
                       args=(), kwargs={}):
        self.mins = conv_to_set(minute)
        self.hours = conv_to_set(hour)
        self.days = conv_to_set(day)
        self.months = conv_to_set(month)
        self.daysofweek = conv_to_set(daysofweek)
        self.action = action
        self.args = args
        self.kwargs = kwargs

    def matchtime(self, t1):
        """Return True if this event should trigger at the specified datetime"""
        return ((t1.minute     in self.mins) and
                (t1.hour       in self.hours) and
                (t1.day        in self.days) and
                (t1.month      in self.months) and
                (t1.weekday()  in self.daysofweek))

    def check(self, t):
        """Check and run action if needed"""

        if self.matchtime(t):
            self.action(*self.args, **self.kwargs)

class CronTab(object):
    """The crontab implementation"""

    def __init__(self, *events):
        self.events = events

    def _check(self):
        """Check all events in separate greenlets"""

        t1 = datetime(*datetime.now().timetuple()[:5])
        for event in self.events:
            gevent.spawn(event.check, t1)

        t1 += timedelta(minutes=1)
        s1 = (t1 - datetime.now()).seconds + 1
        print "Checking again in %s seconds" % s1
        job = gevent.spawn_later(s1, self._check)

    def run(self):
        """Run the cron forever"""

        self._check()
        while True:
            gevent.sleep(60)

import os
def test_task():
    """Just an example that sends a bell and asd to all terminals"""

    os.system('echo asd | wall')

cron = CronTab(
  Event(test_task, 22, 1 ),
  Event(test_task, 0, range(9,18,2), daysofweek=range(0,5)),
)
cron.run()

답변

나열된 솔루션 중 어느 것도 복잡한 cron 일정 문자열을 구문 분석하지 않습니다. 그래서 여기 croniter를 사용하는 내 버전이 있습니다. 기본 요지 :

schedule = "*/5 * * * *" # Run every five minutes

nextRunTime = getNextCronRunTime(schedule)
while True:
     roundedDownTime = roundDownTime()
     if (roundedDownTime == nextRunTime):
         ####################################
         ### Do your periodic thing here. ###
         ####################################
         nextRunTime = getNextCronRunTime(schedule)
     elif (roundedDownTime > nextRunTime):
         # We missed an execution. Error. Re initialize.
         nextRunTime = getNextCronRunTime(schedule)
     sleepTillTopOfNextMinute()

도우미 루틴 :

from croniter import croniter
from datetime import datetime, timedelta

# Round time down to the top of the previous minute
def roundDownTime(dt=None, dateDelta=timedelta(minutes=1)):
    roundTo = dateDelta.total_seconds()
    if dt == None : dt = datetime.now()
    seconds = (dt - dt.min).seconds
    rounding = (seconds+roundTo/2) // roundTo * roundTo
    return dt + timedelta(0,rounding-seconds,-dt.microsecond)

# Get next run time from now, based on schedule specified by cron string
def getNextCronRunTime(schedule):
    return croniter(schedule, datetime.now()).get_next(datetime)

# Sleep till the top of the next minute
def sleepTillTopOfNextMinute():
    t = datetime.utcnow()
    sleeptime = 60 - (t.second + t.microsecond/1000000.0)
    time.sleep(sleeptime)