So - the schedule library does not support this.
So the simplest way is for you to simply schedule the task for every Friday, and place a filter code on the function entry: if the current date is not the last Friday of the month, then return without executing.
Of course at first glance this seems to imply paste code for calculating dates and etc. inside your tarfea, which may have nothing to do with it, and still repeat that code in various tasks in which you want to do something similar .
That's where "decorators" come in - decorators are function modifiers that have a specific syntax in Python: basically they can "collapse" the code from their original function and optionally run some code before or after - code of the decorator is separate from its main function, and you use only one line to modify the behavior of your function. I explain your usage well in this answer: How do decorators work in Python?
So you can create a decorator like this:
import datetime
from functool import wraps
def only_on_last_friday(func):
@wraps(func)
def wrapper(*args, **kwargs):
today = datetime.date.today()
if today == last_friday_of_month(year=today.year, month=today.month):
return func(*args, **kwargs)
return None
return wrapper
Ready - in combination with its function of finding the last Friday of the month, it will only execute the call the final function if it is called last Friday.
You can either apply the decorator to its final function, or simply decorate it when calling the scheduler - so the function remains normal for the rest of your code, and only the scheduler gets the modified function to run only on the date chosen:
@only_on_last_friday
def job(string):
print(string)
schedule.every().friday.at("11:49").do(job, "I'm working...")
or:
def job(string):
print(string)
schedule.every().friday.at("11:49").do(only_on_last_friday(job), "I'm working...")
(I do not know if you're using dateutils
for other things, but if it's not, I have a version of last_friday using only the default datetime:)
from datetime import date, timedelta
def last_friday(year, month):
minus_one_day = timedelta(days = 1)
next_month = date(year, month, 27) + timedelta(days=7)
result = date(next_month.year, next_month.month, 1)
while True:
result -= minus_one_day
if result.weekday() == 4: # Friday
return result
Taking advantage of the opportunity, if you are using this code it is important for you to have something in place that ensures the program is running even after several days on. There is a very cool Python project for this called supervisor
- which can guarantee this with very little work - it's worth looking at:
link