2014/02/26

Jinja2 template engine, simple basics.

Template engines will allow you to keep your HTML code outside of your code base. Managing and generating HTML in code is a bad practise. Templates will also give nice boost for performance and give you more secure system. this naturally depends how you are using your templates.

This is what Jinja2 is hyping in their features list:


  • Sandboxed execution
  • Powerful automatic HTML escaping system for XSS prevention
  • Template inheritance
  • Compiles down to the optimal python code just in time
  • Optional ahead of time template compilation
  • Easy to debug. Line numbers of exceptions directly point to the correct line in the template.
  • Configurable syntax

  • I was surprised to see how flexible Jinja2 for instance is. Variables can be modifier by filters you can see the full list of built in filters from here: http://jinja.pocoo.org/docs/templates/#builtin-filters

    Here is some basics, which are usually enough to get going.

    I'm passing this test data to Jinja2 (I'm using Python):

     template_data = {"page_title": "Testing templating",  
                      "page_text": "This is my Jinja2 rendered web page!",  
                      "loop_data": ["item1", "item2", "item3"]}  
    

    Data is in dict format. It consists title, text and some data for demonstrating looping. Loop data is placed inside a list.

    This is my template file:

     <html>  
     <head>  
     <title>{{ page_title }}</title>  
     </head>  
     <body>  
     <h1>{{ page_text }}</h1>  
     Loop data:  
     {% for row in loop_data %}  
      {% if row == "item2" %}  
       <font color="red">{{ row }}</font>  
      {% else %}  
       {{ row }}  
      {% endif %}}  
     {% endfor %}  
     </body>  
     </html>  
    

    Variables are referred with {{ var_name }}.

    For loop works like in any other programming language. Just loop list named loop_data and represent its data with variable row in the loop.

    There is also a example how simple IF works. Basically when row value hits "item2" in the loop, font color should be in red. You can also specify {% elif %} blocks.


    2013/05/11

    Python subprocess Popen Stdout and Stderr

    Python's cool subprocess module allows you to launch new processes and make stuff happen for you. You can easily catch Stdout and Stderr from these processes and do post processing as you like.

    You can redirect stdout and stderr into buffer by specifying stdout=subprocess.PIPE, stderr=subprocess.PIPE arguments into Popen. You can also ignore them be setting values to None. By default you are receiving Stdout and Stderr output normally.

    Python documentation states that you should not use PIPE with Popen since it can fill up OS Buffer, if your Stdout generates enough output. However this can be prevented by communicating with your process regularly by using communicate().

    In my script, I'm waiting for suprocess to complete in a while loop, I'm polling the status of the process and then communicating to get stdout and stderr from the OS pipe buffer. Its also wise to sleep during the while loop to save overhead on CPU :-)

    Here is a small script to demonstrate this:

     import subprocess
     import time
    
     # Bash command that will be executed
     cmd = "sudo apt-get upgrade"  
    
     # Launch subprocess  
     print "Launching command: " + cmd  
     sp = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
     sp_data = []  
     # Wait for process to finish  
     while sp.returncode is None:  
      print "Polling.."  
      sp.poll()  
      sp_data = sp.communicate()  
      time.sleep(1)  
     # Print results  
     print "Finished, returncode: " + str(sp.returncode)  
     print "Stdout:"  
     print "------------------------"  
     print str(sp_data[0])  
     print "Stderr:"  
     print "------------------------"  
     print str(sp_data[1])  
    

    Output from this command is following:
     Launching command: sudo apt-get upgrade  
     Polling..  
     Finished, returncode: 0  
     Stdout:  
     ------------------------  
     Reading package lists...  
     Building dependency tree...  
     Reading state information...  
     0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.  
     Stderr:  
     ------------------------  
    

    To test that Stderr is also working, lets try to execute same command without sudo:
     Launching command: apt-get upgrade  
     Polling..  
     Finished, returncode: 100  
     Stdout:  
     ------------------------  
     Stderr:  
     ------------------------  
     E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)  
     E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?  
    

    You might also want to look at my previous post about Popen, how to spawn parallel processes:
    Experimenting with Python subprocess Popen

    Install webmin on Ubuntu server (12.04 LTS)

    Webmin is powerful web-based application for administering your Unix based or Windows system. With webmin, you can modify basic configuration of your server, manage cron jobs, execute commands etc.

    Webmin is modular, which makes it very flexible. You can see list of standard modules of latest version from this link:
    http://www.webmin.com/standard.html

    First up, you should look up most recent version of webmin, you can check latest version from here:
    http://freefr.dl.sourceforge.net/project/webadmin/webmin/

    Download package with wget:
     wget http://freefr.dl.sourceforge.net/project/webadmin/webmin/1.620/webmin_1.620_all.deb  
    

    Webmin is going to need some dependencies in order to install, handy way to install all required packages is to use tool called gdebi. Run gdebi as sudo against your deb packet to install all dependencies.

    First you need to install packet gdebi-core:
     sudo apt-get install gdebi-core  

    Then you can run it against your .deb pakcage:
     sudo gdebi webmin_1.620_all.deb  
     Requires the installation of the following packages:  
     apt-show-versions libapt-pkg-perl libauthen-pam-perl libio-pty-perl libnet-ssleay-perl  
     web-based administration interface for Unix systems  
      Using Webmin you can configure DNS, Samba, NFS, local/remote filesystems  
      and more using your web browser. After installation, enter the URL  
      https://localhost:10000/ into your browser and login as root with your root  
      password.  
     Do you want to install the software package? [y/N]:y  
    

    Now everything should be set up and we can proceed with webmin install:

     sudo dpkg -i webmin_1.620_all.deb  
     ...  
     Webmin install complete. You can now login to https://ip-192-168-1-1:10000/  
     as root with your root password, or as any user who can use sudo  
     to run commands as root.  

    Now everything should be set! You can start configuring your server from https://<your server>:10000/