How to make python apscheduler trigger a function inside a class instance - apscheduler

I have a class which has BaseScheduler as an attribute, nothing fancy, no frameworks etc.
class MyClass(object):
def __init__(self, ...):
...
self.Scheduler = BackgroundScheduler()
...
Later on I define methods that a) schedule jobs based on a schedule definition passed as kwargs, and b) handle the jobs when they are triggered:
def _schedule_Events(self, *args, **kwargs):
try:
Schedule_Def = kwargs.copy()
Schedule_Def['func'] = self._handle_scheduled_Event
job = self.Scheduler.add_job(**Schedule_Def)
self.Scheduled_Events.append(job)
except Exception as e:
self.Logger.exception('%s: exception in schedule_Events, details: %s' %(self.Name, e))
def _handle_scheduled_Event(self, Event_Action):
""" Callback function for scheduled jobs """
try:
.... do stuff ....
However, adding jobs with _schedule_Events fails with:
File "/usr/local/lib/python3.4/dist-packages/apscheduler/util.py", line 381, in check_callable_args
', '.join(unsatisfied_args))
ValueError: The following arguments have not been supplied: Event_Action
The reason is apparently that the 'func' argument must be globally callable, ie. not within a class instance scope. I also don't see how using a 'textual reference' as described in the documentation will help.
If I replace the 'func' callable with a function defined at the module level then it works, but I need to make it call a method within my instance object. Any ideas how to make this work ? Custom trigger ? Wrapping APS Scheduler inside another class and pass the callback ? Other ideas ?
Many thanks in advance.

Related

Pika: How to get a return value from a callback function?

I have a callback function in my program that I need to check success/failure. How can I do this?
In my example below, where does failure_code go?
My snippet:
def mq_callback(job_id, ch, method, body):
# Do some stuff. But if the stuff fails...
return failure_code
channel.basic_consume(
queue='some queue',
on_message_callback=lambda ch, method, properties, body: mq_callback(job_id, ch, method, body),
auto_ack=False
)
channel.start_consuming()
All in this link: https://www.rabbitmq.com/tutorials/tutorial-six-python.html
We create a class for calling requests then wait until the response id equal to the correlation_id that was sent before.

initializing basic stack, but errors i do not comprehend

i am trying to initialize a basic stack - with push, and pop function.
the problems comes in while testing. you will notice in the code that i have pushed 2 times, so a print of the stack should display [5,5] whereas it is displaying None. I could tinker with the code to make it work eventually, but then i will not fully understand the underlying concepts and the error of my ways. so i ask for advice and pointers.
please check out these codes and tell me what i am doing wrong.
this is the code with the class with all it's functions, it is named stack_class:
class Stack:
def __init__(self):
self._values = []
print ('Stack initialized...')
return
def push(self, var):
ok = self._values.append(var)
return ok
def pop(self):
self.stack.pop()
def __str__(self):
output = "{0}".format(self.ok)
return output
this is the testing code:
from stack_class import Stack
ob_1 = Stack()
ob_1.push(5)
print(ob_1.push(5))
What happens is that append method doesn't return anything.
print [].append(1)
>>> None
It does its job, but doesn't return anything, that's why you are getting None in variable ok. I think you want to return the _values instead:
def push(self, var):
self._values.append(var)
return self._values
Output:
Stack initialized...
[5, 5]
Also, it's the first time I read about empty return convention. It's not necessary.

Following calls to static methods with indexing when importing classes

I have a class file myClass.m in a package folder +myPack that's on the path. A simple example of the class file is:
classdef myClass
properties
prop
end
methods
function obj = myClass(x)
obj.prop = x;
end
end
end
Now if I directly call the method and access the property using the full package name, i.e.:
x = myPack.myClass(2).prop;
returns x = 2 correctly. Now, if I try the same by importing this class (and not use the package name):
import myPack.myClass
y = myClass(2).prop
it gives me the following error:
Static method or constructor invocations cannot be indexed.
Do not follow the call to the static method or constructor with
any additional indexing or dot references.
Why does this work in the first case and not the second? As far as I understood, importing a class mainly allowed one to use the class name without the long package name (among other considerations). What is the difference in these two that causes this error and how can I work around it?
Here is some more weird for you: the behavior is different if you are running in the command window, from a script, or from a function!
1) command prompt (1st: ok, 2nd: error)
This is what you've already shown
>> x = myPack.myClass(2).prop
x =
2
>> import myPack.myClass; y = myClass(2).prop
Static method or constructor invocations cannot be indexed.
Do not follow the call to the static method or constructor with
any additional indexing or dot references.
2) Script (1st: error, 2nd: error)
testMyClassScript.m
x = myPack.myClass(2).prop
import myPack.myClass; y = myClass(2).prop
and
>> testMyClassScript
Static method or constructor invocations cannot be indexed.
Do not follow the call to the static method or constructor with
any additional indexing or dot references.
Error in testMyClassScript (line 1)
x = myPack.myClass(2).prop
(the second line would also throw the same error)
3) Function (1st: ok, 2nd: ok)
testMyClassFunction.m
function testMyClassFunction()
x = myPack.myClass(2).prop
import myPack.myClass; y = myClass(2).prop
end
and
>> testMyClassFunction
x =
2
y =
2
I would definitely call that a bug :) The expected behavior is to give an error in all cases.

fileinput usage with openbook=hook_compressed

I'm trying fileinput to read some compressed files, and I tried the following three methods, however, none of them really works.
file=os.join.path(path+filename)
for i,line in enumerate(fileinput([file], openhook=gzip.open)):
for i,line in enumerate(fileinput.input(openhook=fileinput.hook_compressed(file1,'r'))):
for i,line in enumerate(fileinput.FileInput(openhook=fileinput.hook_compressed(file1,'r'))):
For the first command, errors are like:
'module' object is not callable
For the third command, errors like:
Traceback (most recent call last):
File "read_file.py", line 15, in <module>
for i,line in enumerate(fileinput.input(openhook=fileinput.hook_compressed(file1,'r'))):
File "/share/lib/python2.6/fileinput.py", line 103, in input
_state = FileInput(files, inplace, backup, bufsize, mode, openhook)
File "/share/lib/python2.6/fileinput.py", line 230, in __init__
raise ValueError("FileInput openhook must be callable")
ValueError: FileInput openhook must be callable
I don't understand why openhook cannot be callable here?
Can anyone help me with this?
thx
You should pass in the function object as the hook parameter, not call the function.
for i, line in enumerate(fileinput.input(openhook=fileinput.hook_compressed)):
sys.stdout.write("%-6i %s" % (i, line))
In more detail, if function is a function object (something somebody declared with def or lambda), then
variable = function()
calls the function, and stores the result in variable. When instead you say
variable = function
you assign (a reference to) the function object to variable, so that you now can use
variable()
as effectively a synonym for
function()
This usage is relatively rare otherwise, but definitely the norm for hook variables (and indeed, the whole point of hook variables - they offer a "hook" where you can place your own function inside the flow of another class or function. They are alse known as callbacks, if this term should be more familiar).

WxPython - Dialog, module object is not Callable

i have a custom Dialog class in file Dialog1.py
class Dialog1(wx.Dialog):
def __init__(self, prnt):
wx.Dialog.__init__(self, id=wxID_DIALOG1, name='Dialog1', parent=prnt,
pos=wx.Point(110, 140), size=wx.Size(400, 498),
style=wx.DEFAULT_DIALOG_STYLE, title='Dialog1')
in other file Frame - wx.Frame with button
self.button1.Bind(wx.EVT_BUTTON, self.Dec, id=wxID_FRAME3BUTTON1)
and method to show Dialog
def Dec(self, event):
import Dialog1
self.dialog = Dialog1(self)
self.dialog.ShowModal()
#dialog.Destroy()
return True
and When I Push this Button i have a error;
TypeError: 'module' is not Callable
Why?, please Help Me
Edit: Ok is work now, to much copy-paste method ... Sorry
REMOVE THIS QUESTION
"'module' is not Callable" errors typically mean you did something like this:
import Foo
...
foo = Foo()
... when you should have done something like:
from Foo import Foo
...
foo = Foo
In other words, you've got a bad import statement somewhere, where you're importing a whole library rather than a class or function from that module.
My guess is, you have a file named Dialog1.py that has the class Dialog1 in it. Which means you need to do:
from Dialog1 import Dialog1
...
self.dialog = Dialog1(self)