-
-
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()) |
Questions:
2. Note that I have also created batchutil.py, this will have shared functions that can be used across batchspec files. Can I load functions inside batchutil.py in the local context of batchjobspec too? This is needed because functions inside util may want to refer some of batchjobspec specific attributes. For example: function "bazzinga()" inside batchutil is referring to self.name.
I feel that from batchutil import bazzinga
inside batch.spec
will not work.
Change return bazzinga()
to return bazzinga(self.name)
to make it independent from self
.
- Is self.name a right way to access batchjobspec attributes inside functions of batchutil?
Is there some other better way to do this?
Using self.name
is the natural pythonic way and there are no side effects like using global ...
.
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
Updated incorporating comments from above.
Now batchjobspec.bar() throws following exception
NameError Traceback (most recent call last)
in
32 print(batchjobspec.name)
33 print(batchjobspec.exec_str)
---> 34 print(batchjobspec.baz())
in baz()
~/apacheconfig/batchutil.py in bazzinga()
1 def bazzinga(self):
----> 2 return f"baz: I am {self.name}"
NameError: name 'self' is not defined