kblomqvist / yasha

A command-line tool to render Jinja templates for great good
MIT License
244 stars 23 forks source link

Accept STDIN from command line as data input: example 'yasha -v - template.txt.j2' #50

Open tkuebler opened 6 years ago

tkuebler commented 6 years ago

This would allow for dynamically generated data to be passed via pipe.

kblomqvist commented 6 years ago

I'm afraid this would not be easy.

Do you have an idea when the rendering should happen? Should it wait pipe to close? Additionally, as STDIN is already supported for templates, it would need extra logic to decide whether it is for variables or template.

tkuebler commented 6 years ago

Low Priority.

I'll take a look at the code and think about it a bit. It should wait for pipe to close. The question about when rendering should happen is confusing to me, I might not be understanding something.

The use case is needing to dynamically create the data at generation time. This could be a script, a curl call to a web service, etc. It's completely possible for my data script to create a file during build that then gets consumed, I am just looking for something more elegant that doesn't leave poop all over.

example: curl https://api.coindesk.com/v1/bpi/currentprice.json | yasha -v static.yaml -v - mytemp.j2

PS: I can accomplish this now with named pipes but you can't put those in version control and it confuses the heck out of nubes.

mkfifo dynamic_data.yaml dynamicd.py > dynamic_data.yaml & # or daemon that writes the data to the fifo, then loops yasha -v static_data.yaml -v dynamic_data.yaml mytemplate.j2

kblomqvist commented 6 years ago

The question about when rendering should happen is confusing to me, I might not be understanding something.

Like after the pipe has been closed. I was just thinking that rendering in "real time" would be hard.

I understand your use case, and started to think which one is more useful 1) STDIN for variables or 2) STDIN for template. For now I have used STDIN to test some simple templates in unit tests. But it can be that reserving STDIN for data could make more sense in practice.

alextremblay commented 4 years ago

I think it makes more sense to reserve STDIN for templates.

If you want to dynamically populate variables at runtime without leaving stale data files all over the place, perhaps you could make use of environment variables?

Maybe yasha could be configured to evaluate python literals in environment variables the way it handles python literals as command-line arguments? (ie. yasha --lst="['foo', 'bar', 'baz']" template.j2)

grerrg commented 4 years ago

just my two cents.

other projects ( mattrobenolt/jinja2-cli, kolypto/j2cli, wrouesnel/p2cli ) do that by default. also it's kinda a natural workflow: the input stream reads variable data sources while when calling the program i already know which template i want to use.

edit: forgot the most important point. with an arbitrary number of files often pre-processing of the data itself is needed. if one has to specify the data as an argument instead of an input stream, the workflow breaks when a command is run in a container. i.e.

cat $(find . -type f -name '*.json') | \
jq <some pre-processing> | \ #this is an alias for ( docker run --rm -i jq "$@" )
yasha template.j2

i don't know how i would accomplish the pre-processing as an argument other than using a named pipe like @tkuebler demonstrated.

kblomqvist commented 4 years ago

I think it is ok to support STDIN for both variable files and template. If both are set to read STDIN then it is an error.

Regarding to the above example, I'm not sure how JSON parser can parse the input of multiple files written to STDIN. I assume that the parser assumes to see {...} only once.