34

I am using apscheduler and I am trying to pass in parameters to the handler function that gets called when the scheduled job is launched:

from apscheduler.scheduler import Scheduler
import time

def printit(sometext):
    print "this happens every 5 seconds"
    print sometext

sched = Scheduler()
sched.start()

sometext = "this is a passed message"
sched.add_cron_job(printit(sometext), second="*/5")

while True:
    time.sleep(1)

Doing this gives me the following error:

TypeError: func must be callable

Is it possible to pass parameters into the function handler. If not, are there any alternatives? Basically, I need each scheduled job to return a string that I pass in when I create the schedule. Thanks!

still.Learning
  • 1,185
  • 5
  • 13
  • 18

3 Answers3

41

printit(sometext) is not a callable, it is the result of the call.

You can use:

lambda: printit(sometext)

Which is a callable to be called later which will probably do what you want.

Ali Afshar
  • 40,967
  • 12
  • 95
  • 109
  • Sweet it works! Do you think you can quickly explain why this works/ how this fixes the error? Thanks! – still.Learning Sep 13 '12 at 18:48
  • It is explained. You need to pass a function, i.e. something that can be called. def foo(): pass "foo" is the function "foo()" is the return value of calling that function. – Ali Afshar Sep 13 '12 at 20:11
  • @still.Learning Python supports the creation of anonymous functions (i.e. functions that are not bound to a name) at run time, using a construct called "lambda". This is a normal function -> def f (h): return h**10, and this is a lambda functin -> g = lambda h: h**10, notice the difference ;) – light-blue May 02 '14 at 07:12
  • NOTE: You cannot use lambdas as the callable if you're using a persistent jobstore with apscheduler (like PostgreSQL, Redis, etc). You'll get this error: "ValueError: This Job cannot be serialized since the reference to its callable could not be determined. Consider giving a textual reference instead." – Preston Badeer Aug 31 '21 at 21:20
39

Since this is the first result I found when having the same problem, I'm adding an updated answer:

According to the docs for the current apscheduler (v3.3.0) you can pass along the function arguments in the add_job() function.

So in the case of OP it would be:

sched.add_job(printit, "cron", [sometext], second="*/5")
Niel
  • 1,856
  • 2
  • 23
  • 45
  • 7
    If you do named arguments you should have preceded job function arguments with arg. Example: args= [arg1, arg2] – Mcmil May 23 '17 at 06:04
  • 2
    Latest link: https://apscheduler.readthedocs.io/en/3.x/modules/schedulers/base.html#apscheduler.schedulers.base.BaseScheduler.add_job – Preston Badeer Aug 31 '21 at 21:19
1

Like Niel mention, with the current apscheduler you can use:
args (list|tuple) – list of positional arguments to call func with. See doc

Example:

sched.add_job(printit, args=[sometext], trigger='cron', minutes=2)

aldwinp35
  • 109
  • 1
  • 7