-
-
Save agrawalo/4b149de5b73cee1ed6c2dd01d2e506a0 to your computer and use it in GitHub Desktop.
python = <<EOF | |
from batchutil import bazzinga | |
def foo(): | |
return f"foo: I am {self.name}" | |
def bar(): | |
return f"bar: I am {self.name}" | |
def baz(): | |
return bazzinga(self) | |
EOF | |
<batch> | |
name p&l_calulator | |
exec_str echo %foo()% | |
</batch> |
def bazzinga(batch): | |
return f"baz: I am {batch.name}" |
from apacheconfig import * | |
class BatchJobSpec: | |
def __init__(self, pythoncode , batch): | |
self.pythoncode = pythoncode | |
self.name = batch.get("name") | |
self._exec_str = batch.get("exec_str") | |
self.exec() | |
@property | |
def exec_str(self): | |
_exec = self._exec_str.split("%") | |
for i in range(len(_exec)): | |
if _exec[i].endswith('()'): | |
f = self.__getattribute__(_exec[i][:-2]) | |
_exec[i] = f() | |
return ''.join(_exec) | |
def exec(self): | |
locals_ = {'self': self} | |
exec(self.pythoncode, locals_) | |
_exec = [] | |
for attrib in locals_.keys(): | |
if not attrib in ['__builtins__', 'self']: | |
print('__setattr__({})'.format(attrib)) | |
self.__setattr__(attrib, locals_[attrib]) | |
with make_loader() as loader: | |
config = loader.load('batch.spec') | |
batchjobspec = BatchJobSpec(config.get("python"), config.get("batch")) | |
print(batchjobspec.pythoncode) | |
print(batchjobspec.name) | |
print(batchjobspec.exec_str) | |
print(batchjobspec.baz()) |
In batch.spec
line
"def foo():
return f"foo: I am {self.name}""
still looks weird to me because visually self is sort of not available in this block. To make it bit more intuitive I guess changing this to something like below will look good and intuitive.
"def foo(batch):
return f"foo: I am {batch.name}""
this will result in changing following line
"exec_str echo %foo()%"
to
"exec_str echo %foo(self)%"
is this possible?
In batch.spec
still looks weird to me because self is sort of not available in this block. To make it bit more intuitive I guess changing this to something like below will look good and intuitive."def foo(batch):
return f"foo: I am {batch.name}""
I recommend the following, as it becomes a indirect member of the class
and writing def function_name(self)
are common.
def foo(self):
return f"foo: I am {self.name}""
This needs to change the following line in def exec(self)
:
_exec[i] = f(self)
The drawback are, you can't call batchjobspec.baz()
any more you have to use batchjobspec.baz(batchjobspec)
.
You have to decide, more logic in batch.spec
or in Python code itself.
And second, you have to use this with all def ...
in batch.spec
even if not needed.
this will result in changing following line
"exec_str echo %foo(self)%"
Yes, but this complicate finding function parameter in exec string
I actually made it a staticmethod. Please review the code https://gist.github.com/agrawalo/407caf4dcd44687fae6989f46b54975a
I feel that
from batchutil import bazzinga
insidebatch.spec
will not work.Change
return bazzinga()
toreturn bazzinga(self.name)
to make it independent fromself
.Using
self.name
is the natural pythonic way and there are no side effects like usingglobal ...
.