{ "info": { "author": "Todor Todorov", "author_email": "ttodorov@null.net", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Topic :: Software Development :: Pre-processors", "Topic :: System :: Installation/Setup", "Topic :: System :: Systems Administration", "Topic :: Text Processing", "Topic :: Text Processing :: Filters" ], "description": "# Configuration Templating Language\n\nSimple to learn but yet powerful language for templating your configuration files. It is a 'slang' of the [web2py](http://www.web2py.com)'s templating language, written from scratch and optimized for textual non-html data.\n\n## Features\n\n* Simple to learn - a person who has some idea of the Python syntax could dive into conftl for 15 min.\n\n* Powerful - Python code in templating.\n\n* Command line tool for rendering.\n\n* Different methods for trigerring rendering from Python code.\n\n* Suitable for system administration, devops and similar roles.\n\n* Performance - minimal code base optimized for performance.\n\n* Platform independent - tested under Linux and Windows, should work on other Unix platforms as well, Python 2.7 compatible, Python 3.x compatible.\n\n## Getting Started\n\nInstall conftl using pip:\n\n```\npip install conftl\n```\n\nAlternatively download the source code:\n\n```\ngit clone https://github.com/ttt-fifo/conftl\ncd conftl\npython setup.py install\n```\n\nHello world from the command line:\n\n```bash\n$ render -c \"name='John Smith'\"\nHello, {{=name}}\nHello, John Smith\n```\n\nNOTE: Write ```Hello, {{=name}}``` on stdin, followed by Enter, Ctr+D\n\nHello world from the Python REPL:\n\n```python\n>>>\n>>> from conftl import render\n>>>\n>>> render(content='Hello, {{=name}}', context=dict(name='John Smith'))\n'Hello, John Smith'\n>>>\n```\n\n## Prerequisites\n\nLinux or other Unix distribution or Windows.\n\nPython 2.7 or Python 3.x\n\nPlease place an [issue](https://github.com/ttt-fifo/conftl/issues) in case the current implementation is not working with your platform and I will try to help.\n\nPython Modules: future\n\n## Templating Kickstart\n\n* **Clear text from the template is printed to the output as is**\n\n```\nlorem ipsum dolor sim amet\ntext clear lorem ipsum\n```\n\nwill go exactly the same into the output\n\n```\nlorem ipsum dolor sim amet\ntext clear lorem ipsum\n```\n\n* **Python code in template should be written using tags** ```{{ ...code... }}```\n\nFor example if you would like to assign a value ```3``` to ```i```, you can do it using the following syntax:\n\n```{{i = 3}}```\n\nYou could also write multiline Python code as well - like the following example:\n\n```\n{{\nimport sys\n\ndef one():\n return 1\n\ni = 3\n}}\n```\n\n* **Printing a variable value to the output** is done by tagging it and placing = sign in front of the variable like this ```{{=myvar}}```\n\nFor example if ```i``` has the value of ```3``` and you put in template:\n\n```{{=i}}```\n\nyou will receive in the output:\n\n```3```\n\n* **Combining a Python code block with clear text and variable outputs** - you should not indent the code block as you normally do with Python, but you should determine it with ```{{pass}}``` special keyword instead.\n\nWhenever you write a code block into the original Python interpreter you indent the code. Lets take the following example of original Python code block:\n\n```python\nfor i in range(0, 2):\n print('X', i)\n```\n\nThe equivalent of the above code would be:\n\n```\n{{for i in range(0, 2):}}\nX {{=i}}\n{{pass}}\n```\n\n* **You are able to pass values to template variables from outside of the template** - there are multiple methods to give 'context' to the template, e.g. assigning variable values outside of the template. Look the follow up sections.\n\n* **Advanced templating topics** could be found at [TEMPLATING.md](https://github.com/ttt-fifo/conftl/blob/master/TEMPLATING.md)\n\n## Examples\n\nTake a look at the [examples folder](https://github.com/ttt-fifo/conftl/tree/master/examples) from the project repository.\n\n## Command Line Tool for Rendering (render)\n\n* **The render command line tool works as follows:**\n\n```\nrender -i templatename.tmpl -o filename.conf\n```\n\nwill take the template from file ```templatename.tmpl``` and write the output to ```filename.conf```\n\nWARNING: filename.conf will be overwriten!!!\n\nIn case input template is not given by -i, you would be expected to place template code on stdin.\n\nNOTE: For Linux and other Unix systems write template code and finish it with Ctr + D\n\nNOTE: For Windows finish template code with with Ctr + Z and then hit ENTER\n\nIn case the output filename (-o) is not given, the output will be written to stdout.\n\n* **Giving context variables on the command line**\n\nYou want to give ```i``` value of ```4``` and use it in your template. Use -c flag:\n\n```\nrender -i templatename.tmpl -o filename.conf -c i=4\n```\n\nFor assigning values to multiple variables, just repeat -c flag multiple times:\n\n```\nrender -i templatename.tmpl -o filename.conf -c i=4 -c j=8 -c x=2\n```\n\nFor assigning complex variable datatypes, wrap assignment in double quote like this:\n\n```\nrender -i templatename.tmpl -o filename.conf -c \"mydict={'a': 1, 'b': 'string'}\"\n```\n\n* **Context from json file**\n\nThe json file format should be similar to:\n\n```json\n{\"myvar\": 4,\n \"otherthing\": [1, 3, 5],\n \"stringsomething\": \"hello world\"\n}\n```\n\nYou can invoke render by giving the -j option like this:\n\n```\nrender -i mytemplate.tmpl -j mycontext.ctx\n```\n\nNOTE: the command line variables have precedence over json file, e.g. if you assign i=2 in json file and i=3 on command line, the final value of i will be i=3.\n\n* **Environment in context for convenience**\n\nFor convenience the ENV dictionary is automatically included in the context and it contains the OS environment variables. The following example prints them on the screen:\n\n```\nrender\n{{for e in ENV:}}\n{{=e}} : {{=ENV[e]}}\n{{pass}}\n..................................\n... environment will come here ...\n..................................\n```\n\nNOTE: the ENV is included automatically in context only with the command line tool, rendering from Python (the next section) does not have ENV automatically in context.\n\n*How to use ENV in templates?*\n\nMany devops / sysadmin systems pass data to their underlying scripts via environment variables. As an example the following shell commands:\n\n```\n$ export SYSTEM=production\n$\n$ render\n{{if ENV['SYSTEM'] == 'production':}}\nListen 80\n{{elif ENV['SYSTEM'] == 'ci_cd':}}\nListen 8080\n{{elif ENV['SYSTEM'] == 'devel':}}\nListen 8081\n{{else:}}\n{{raise RuntimeError('wrong SYSTEM')}}\n{{pass}}\n```\n(Ctr+D at the end)\n\nwill give you the output based on the SYSTEM environment variable:\n\n```\nListen 80\n```\n\n* **Command line tool help**\n\nSee ```render -h```\n\n## Rendering Template from Python\n\nThere are three interfaces for rendering a template from Python: the function ```render(...)```, the class ```Render``` and the decorator ```@template(...)``` . Please see the explanation below:\n\n* **render(...) function**\n\nConsider the following example:\n\n```python\n>>>\n>>> from conftl import render\n>>> render(content='{{=i}}', context=dict(i=8))\n'8'\n>>>\n```\n\nAs you can see, you can give the context= value, which is a dict, containing your variable data.\n\nThe signature of the function follows:\n\n```python\nrender(infile=None,\n outfile=None,\n context=None,\n content=None,\n delimiters=None)\n```\n\nYou can use the function by giving infile= as argument (this is the template file). If not given, you should give the content= value - this would be a string with the template content.\n\nOutput file could be given by outfile= argument. If given, the output will be written to this file. On outfile= absence, the output is returned as string.\n\nIn case you need to use other delimiters than the default ```{{ }}```, you can change the delimiters like this:\n\n```python\n>>>\n>>> render(content='[[=i]]', context=dict(i=7), delimiters='[[ ]]')\n'7'\n>>>\n```\n\n* **template decorator**\n\nDefine a function which returns the context as a dict. Decorate your function with template decorator:\n\n```python\nfrom conftl import template\n\n# Define your function, which should output a dict\n# with the template context and decorate it with\n# template decorator\n\n@template(infile='mytemplate.tmpl', outfile='myconf.conf')\ndef template_myconf(*arg, **kwarg):\n\n # ...here your complex computations...\n i = ....\n j = ....\n x = '.....'\n\n return dict(i=i, j=j, templ_var=x)\n\nif __name__ == '__main__':\n\n # Here invoke your function and it should create\n # the needed myconf.conf\n\n template_myconf(... some args...)\n```\n\nThe possible arguments for template decorator are\n\n```python\n@template(infile=None,\n outfile=None,\n content=None,\n delimiters=None)\n```\n\nYou must give eihter infile= or content= as input. You can omit outfile= and in this case the decorated function will return the output as a string. Changing delimiters= is also possible. The function, decorated with template(...) must return dict, otherwise exception is raised.\n\nThis type of context computation is well know by the web2py users, because this is the layout of the web2py controller.\n\n* **Render object**\n\nAn object from Render class could be used in a long running processes. Load the object in memory once and use it multiple times for templating multiple files:\n\n\n```python\nfrom conftl import Render\n\nrndr = Render()\n\n# ... use it multiple times like this\nrndr.instream = open('filename.tmpl', 'r')\nrndr.outstream = open('otherfile.conf', 'w')\nrndr.context = dict(i=..., j=..., somevar='...')\n\nrndr()\n\nrndr.instream.close()\nrndr.outstream.close()\n# ....\n```\n\nThe ```instream``` and ```outstream``` should be file handles or StringIO objects.\n\n## Known Limitations\n\n* Arbitrary Python code is possible to be executed by the current templating language. I would advice against giving opportunity to the end-users to write template code, unless you know what you are doing. Multiple attack vectors could be used by a malicious end-user who has the possibility to execute arbitrary Python code.\n\n* In case you want to template a HTML output, you would be better off using the web2py's templating language (called [yatl](https://github.com/web2py/yatl)). Yatl has XML escaping switched on by default and also multiple HTML helper functions.\n\n## Contributing\n\nTesting implementation on different platforms.\n\nDo not hesitate to fork me on github.\n\nPlace [issue](https://github.com/ttt-fifo/conftl/issues) if you spot issues with this code.\n\n## Versioning\n\nSee the [tags](https://github.com/ttt-fifo/conftl/tags) on this repository.\n\n## Authors\n\n**Todor Todorov** - [ttt-fifo](https://github.com/ttt-fifo)\n\n## License\n\nBSD + other copyright credits\n\nSee [LICENSE](https://github.com/ttt-fifo/conftl/blob/master/LICENSE) for details.\n\n## Acknowledgments\n\nThanks to [Massimo Di Pierro](https://github.com/mdipierro) and the [web2py](https://github.com/web2py) team for the inspiration.\n\nLogo: [server](https://www.vrt.com.au/downloads/vrt-network-equipment), [icons](http://hawcons.com/), [arrow](https://longfordpc.com/)\n\n## See Also\n\nDifferences between conftl and yatl from the document [differences_yatl.txt](https://github.com/ttt-fifo/conftl/blob/master/docs/differences_yatl.txt)\n\n[web2py on github](https://github.com/web2py/web2py)\n\nweb2py templating language [yatl](https://github.com/web2py/yatl)\n\nAnother implementation of the same templating language may be found at the [weppy](https://github.com/gi0baro/weppy) project.\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ttt-fifo/conftl", "keywords": "templating configuration development sysadmin devops", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "conftl", "package_url": "https://pypi.org/project/conftl/", "platform": "", "project_url": "https://pypi.org/project/conftl/", "project_urls": { "Bug Reports": "https://github.com/ttt-fifo/conftl/issues", "Homepage": "https://github.com/ttt-fifo/conftl", "Source": "https://github.com/ttt-fifo/conftl/" }, "release_url": "https://pypi.org/project/conftl/0.5.3/", "requires_dist": [ "future" ], "requires_python": ">=2.7, <4", "summary": "Configuration Templating Language", "version": "0.5.3" }, "last_serial": 5691121, "releases": { "0.5.3": [ { "comment_text": "", "digests": { "md5": "4878c22b57fe7dad4dd945e65f7cfdf8", "sha256": "becc375209beed78b9d53399f97c36c18cb723320ac1a1f80294e68bfd2c9f93" }, "downloads": -1, "filename": "conftl-0.5.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4878c22b57fe7dad4dd945e65f7cfdf8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, <4", "size": 12779, "upload_time": "2019-08-17T09:31:20", "url": "https://files.pythonhosted.org/packages/74/1e/420908576de28f97f9c9b3db2d322ad0c4543d83c55282aefb4adca5d1b0/conftl-0.5.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "db99d132520b99d868369da00ba717ed", "sha256": "6f3e45a2fcd4c6dd3a507f8a4a6397e870f5aef4afe44e36a9c64ff81b654f1b" }, "downloads": -1, "filename": "conftl-0.5.3.tar.gz", "has_sig": false, "md5_digest": "db99d132520b99d868369da00ba717ed", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, <4", "size": 14866, "upload_time": "2019-08-17T09:31:23", "url": "https://files.pythonhosted.org/packages/78/02/7d65b50ed48a958bbbdec2b3d292fbe7ed1a45518d4a89770cdabbf8c5e5/conftl-0.5.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4878c22b57fe7dad4dd945e65f7cfdf8", "sha256": "becc375209beed78b9d53399f97c36c18cb723320ac1a1f80294e68bfd2c9f93" }, "downloads": -1, "filename": "conftl-0.5.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4878c22b57fe7dad4dd945e65f7cfdf8", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7, <4", "size": 12779, "upload_time": "2019-08-17T09:31:20", "url": "https://files.pythonhosted.org/packages/74/1e/420908576de28f97f9c9b3db2d322ad0c4543d83c55282aefb4adca5d1b0/conftl-0.5.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "db99d132520b99d868369da00ba717ed", "sha256": "6f3e45a2fcd4c6dd3a507f8a4a6397e870f5aef4afe44e36a9c64ff81b654f1b" }, "downloads": -1, "filename": "conftl-0.5.3.tar.gz", "has_sig": false, "md5_digest": "db99d132520b99d868369da00ba717ed", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7, <4", "size": 14866, "upload_time": "2019-08-17T09:31:23", "url": "https://files.pythonhosted.org/packages/78/02/7d65b50ed48a958bbbdec2b3d292fbe7ed1a45518d4a89770cdabbf8c5e5/conftl-0.5.3.tar.gz" } ] }