kblomqvist/yasha

Use Yasha by script directly instead of Command Line ?

virtualengineer opened this issue · 5 comments

Could the yasha cli.py script function be called directly ?
I have a unique problem where I can't call Yasha.exe from the command line.
I am trying to call the yasha cli function directly, but can't get it to work.
Can you explain how, if it is possible ?

def cli(
        template_variables, template, output, variables, extensions,
        encoding, include_path, no_variable_file, no_extension_file,
        no_trim_blocks, no_lstrip_blocks, remove_trailing_newline,
        mode, m, md)

my original call goes like this:
call(('yasha', '-v', variable_file_path, '-o', output_file_path, template_file_path))

Update 1:

I tried calling the function directly but got an error.

The code:
import yasha.cli as yasha_cli
...
template_variables = ()
template = open(template_file_path, "rb")
output = open(output_file_path, "wb")
variables = open(variable_file_path, "rb")
extensions = None
encoding = u'utf-8'
include_path = ()
no_variable_file = False
no_extension_file = False
no_trim_blocks = False
no_lstrip_blocks = False
keep_trailing_newline = False
mode = None
m = False
md = False

    yasha_cli.cli(template_variables, template, output, variables, extensions,
    encoding, include_path, no_variable_file, no_extension_file,
    no_trim_blocks, no_lstrip_blocks, keep_trailing_newline,
    mode, m, md)

The error:
my_proj\venv\Lib\site-packages\click\core.py", line 764, in call
return self.main(*args, **kwargs)
TypeError: main() takes at most 5 arguments (16 given)

Update 2:

If I include a non_cli version of the function without all the click decorators (click command, argument, option etc), then it can be called directly from script no-problem. This is very convenient for people who are supporting multiple systems like windows, linux and other systems.

The Code:

non cli python function for calling directly from script. no click decorators.

def yasha_non_cli(
template_variables, template, output, variables, extensions,
encoding, include_path, no_variable_file, no_extension_file,
no_trim_blocks, no_lstrip_blocks, keep_trailing_newline,
mode, m, md):
< all code same as cli function ... >

The call:
template_variables = () # tuple. empty.
template = open(template_file_path, "rb")
output = open(output_file_path, "wb")
variables = ( open(variable_file_path, "rb"), ) #tuple, variable file path, nothing else
extensions = None
encoding = u'utf-8'
include_path = () # tuple. empty.
no_variable_file = False
no_extension_file = False
no_trim_blocks = False
no_lstrip_blocks = False
keep_trailing_newline = False
mode = None
m = False
md = False

    yasha_non_cli(template_variables, template, output, variables, extensions,
    encoding, include_path, no_variable_file, no_extension_file,
    no_trim_blocks, no_lstrip_blocks, keep_trailing_newline,
    mode, m, md)

In yasha/scons.py file, I have used CliRunner from click.testing to call yasha.cli

The problem with using click.testing.CLIRunner to use yasha as a library in another python application is that it executes the yasha cli in an isolated subprocess for testing purposes. This means that the yasha code is running in a different interpreter. This causes a slight performance penalty, but more importantly it means that you cannot debug the yasha code from within your code or see any of the interactions between your code and the yasha code. it's essentially the same as running the yasha command through subprocess

here's another option which runs yasha on the same interpreter as your python code:

from yasha import cli as yasha_cli
yasha_cli(['-v', 'my-variable-file.json', 'my-template.j2'])

The problem with using click.testing.CLIRunner to use yasha as a library in another python application is that it executes the yasha cli in an isolated subprocess for testing purposes. This means that the yasha code is running in a different interpreter. This causes a slight performance penalty, but more importantly it means that you cannot debug the yasha code from within your code or see any of the interactions between your code and the yasha code.

Yeah, you're right. This has been bugging me too. To change the approach I would like to see Yasha being refactored heavily. I would prefer Yasha internals to have similar API that Jinja has (Environment class). If you like to do this I can review the PR(s). However, be prepared that it may not be smooth process and there can be many review rounds ;) My experience in Python has increased greatly since I wrote Yasha and there is quite much code I'm not happy anymore.