Monthly Archives: November 2013

Indentation in Python; Sometimes it’s creepy



Yesterday, I was working on my next patch i.e. Patch Number 3. While doing that, I came across a very unusual thing with my system that it was showing me indentation error. I made it correctly indented in terminal but it still shows indentation error. When i opened it with gedit it was again not properly indented. So after searching a lot, I came to know about a cool  feature that is autopep8. It automatically indents your code.
here is, how you can install it via pip.
$ pip install --upgrade autopep8

It will auto-format the code not only indentation but also spacing styles. So it makes the python script to conform  PEP8 style guide.
Use:

$ autopep8 your_code.py 
# to auto-format your code
After solving this somehow,  i made a new pull request and create a new commit. But then i realized that there were few things that were i need to change. Also, the problem of indentation error was not resolved.
 
So first thing i had to do was to delete my git commit. I learned few commands that i would like to share with you.
 
To know which commit is the head pointing to:
$ git reset --hard HEAD~1

The HEAD~1 means the commit before head.
If you want to move you head to some earlier commit,then

$ git log

This will list all the commits made by you along with their commit id. You can find the commit-id of the commit you want to move your head to

$ git reset --hard <sha1-commit-id>

If you want to delete the commit that you have already pushed, then:

$ git push origin HEAD --force
After doing this, I again made commit after making changes in the code. But my problem was still there. There were indentation errors and also trailing white-spaces errors. Then pypingou asked me to make changes in the ~/.vimrc file and it really worked for me.
 
They are:
set list
set listchars=tab:→\ ,trail:·
This will allow you to quickly check your trailing spaces or when it uses tab/spaces. So, finally my problem was solved 🙂 


Advertisements

Interesting results with fedmsg.meta

The next task my mentor gave me was to convert the messages that were in json dictionary like format into something that is good looking and in human readable form. For that, he asked me to read documentation on fedmsg. Fedmsg is a python package that can be used to send and receive messages to and from applications. After reading it, I found fedmsg.meta module very interesting and something that could solve my problem. It has beautiful functions that can be used to produce nice html and can convert messages into some beautiful string representations, icons, secondary_icon, link, title and subtitle. Also I liked it because it produced interesting results and is easy to learn and use.

I had message in json-dict format

  I wanted to have output like this.

The first thing i do is to convert the messages(dict format) into string.I used

       fedmsg.meta.msg2repr(msg, legacy=False, **config)


You will have to implement this code

>>> import fedmsg.config
>>> import fedmsg.meta
>>> config = fedmsg.config.load_config([], None)
>>> fedmsg.meta.make_processors(**config)
>>> text = fedmsg.meta.msg2repr(msg_in_dict, legacy=False, **config)                        

To get the desired output, I wrote request_wants_html function in this way

# return HTML content else json
if request_wants_html():
# convert string into python dictionary
obj = json.loads(body)
# extract the messages
messageList = obj["raw_messages"]
#using fedmsg.meta function
config = fedmsg.config.load_config([], None)
fedmsg.meta.make_processors(**config)

finalMessageList = []

for msg in messageList:
d = {}
# create primary icon associated with message
icon = fedmsg.meta.msg2repr(msg,legacy=False,**config)
d['icon'] = icon
# create URL associated with message
link = fedmsg.meta.msg2link(msg, legacy=False, **config)
d['link'] = link
# create title associated with message
title = fedmsg.meta.msg2title(msg, legacy=False, **config)
d['title'] = title
# create secondary icon associated with message
secondary_icon = fedmsg.meta.msg2secondary_icon(msg, legacy=False, **config)
d['secondary_icon'] = secondary_icon
subtitle = fedmsg.meta.msg2subtitle(msg, legacy=False, **config)
d['subtitle'] = subtitle

finalMessageList.append(d)

return flask.render_template("raw.html", response=finalMessageList)
To render the title, subtitle, icon, link and secondary_icon, i used the html file this way
{% for dict in response %}
<pre>
<div>
<p><b>{{dict['title']}}</b></p> </br>
<p> {{dict['subtitle']}} </p> </br>
<A HREF={{dict['link']}}><Img SRC= {{dict['icon']}} WIDTH=30 HEIGHT=40></A>
<Img SRC={{dict['secondary_icon']}} WIDTH=30 HEIGHT=40></A>
</div>
</pre>
{% endfor %}

So, this was my patch 2. In my coming blogs I will be sharing with you a short introduction to jinja2 framework.

Happy learning 🙂

My First Patch: Cool Coding


My first patch was to differentiate between the accept headers using flask’s methods and returns content accordingly. It means that if the accept header is in “application/json” it should return the content in JSON format and in case of “text/html”, it should return “HTML” format and for other cases it should return ‘JSON’ by default.
 
I was given a link to use it as reference. There is a function request_wants_json that returns true if accept header is “application/json”. otherwise it returns false. By default  an HTTP request is rendered as html in browser. But, we can provide accept header on our wish and can give preference to other mimetype. I came to know that there are 17 mimetypes in total and many more are coming.

Initially i thought why not check for “text/html” header’s type using flask method i.e. flask.request.headers.get(‘Accept’) and then return content according that. But my mentor suggested not to use that as they wanted codes in more engineered way and extensible one 🙂

So I moved on the flask accept header snippet and modified ‘request_wants_json’ function to ‘request_wants_html’ so as to put html on  higher quality than ‘application/json’ and ‘text/plain’.So, it returns true in case of “text/html” and false otherwise.
def request_wants_html():     
    best = flask.request.accept_mimetypes.best_match(['application/json',\
             'text/html','text/plain'])     
    return best=='text/html' and flask.request.accept_mimetypes[best]\ 
             > (flask.request.accept_mimetypes['application/json'] or
             \ (flask.request.accept_mimetypes['text/plain']) 
I also made the following changes in the /datagrepper/app.py. It uses request_wants_html to obtain the desired output.
# return HTML content else json
if request_wants_html():         
   return "HTML Format"     
else:         
   return flask.Response(response=body,                
                         status=status,                
                         mimetype=mimetype) 
It returns the “HTML Format” in case if accept header  is “text/html” otherwise it returns the JSON format. Later on i will have to add something in this HTML part to make it return some beautiful HTML content. 
 
This is how I submitted my first patch. It was a nice beginning. 
Cheers!

Working with Python Flask

Datagrepper is a web application that is build on the top of flask. Here, i am sharing with you how you can develop web applications in python using Flask framework.

I liked it because it was easy to learn and simple to use. Also many of you will have question why flask? And answer is

  • Extensive documentation
  • Easy to understand
  • Decoupled code
  • No ORM so you can use SQLAlchemy or storm
  • Support other templates like genshi, mako
  • Pocoo team
  • Testing support
  • Blueprint
  • Extensions
  • Module level integration
  • Code base small you can check the source code.
  • 100% WSGI compliant.
  • Integration with gevent, twisted, tornado is possible.
  • Useful snippets in the pocoo site.
  • You can deploy with cherrypy.
  • No inbuilt form so you can use wtforms or any other.
  • Code by Armin Ronacher 🙂
  • Supports REST


So, to dive into code, First you will have to do the installation.

Installation:
 
First install virtualenv. virtualenv will let you create an isolated environment for your project with its own installation directories, will let you install all dependencies into the virtualenv without affecting the system site-packages.
$ sudo easy_install virtualenv
or
$ sudo pip install virtualenv
# Mac OS X or Linux
$ sudo apt-get install python-virtualenv 
# ubuntu

After installing virtualenv, you will have to create your environment by creating a folder. 

$ mkdir flask-learn
$ cd flask-learn
$ mkvirtualenv flask
$ workon flask
$ pip install Flask

Now, we will have to create directory structure like way.

$ mkdir app
$ cd app
$ mkdir static
# holds all css, JavaScript files
$ mkdir templates
# store web app templates
My first Hello World program in flask
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'Hello, World!'

if  __name__ == '__main__':
    app.run()

Save this program as hello_world.py .Now run it.

$ python hello_world.py
* Running on http://127.0.0.1:5000/
127.0.0.1 - - [03/Nov/2013 23:28:42] "GET / HTTP/1.1" 200 -

Open http://localhost:5000 to see the results.

 
To learn more, you can refer this link.
 
Now, lets do add some html file.
$ cd templates
$ vi layout.html

add the following lines to layout.html

<!DOCTYPE html>
  <html>
  <head>
    <h1>Flask</h1>
  </head>
  <body>
    <header>
      <div>
        <h2><font color="red">Happy Learning! </font></h2>
      </div>
    </header>

    <div>
    {% block content %}
      <h3> This is the home page for Flask App</h3>
    {% endblock %}
    </div>

  </body>
</html>

 
Change the hello_world.py to this.

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def hello_world():
    return render_template('layout.html')

if __name__ == '__main__':
    app.run()

Now, run hello_world.py

 

You will get output 🙂 like this

 

To gain a good knowledge in flask and to try writing some codes on it- read this tutorial. It will provide you road-map for various web-app development using flask.

I will be updating more about database models, various methods, error handling etc. in future blogs. till then

Happy Coding!

Create a new Pull request on Github

The next step is to make contributions to the project you are interested in. This is a interesting step as today most of the patches are submitted through pull request and It is one of the best way to collaborate in decentralize manner. So how will you start collaborating with mentor and submit your patches? I am going to write down each step as clear as possible.So the first step would be to contact your mentor and ask them “How can you start contributing to the project”. They will give you some simple task like making small changes in code or fixing some bugs etc. Now you know what you have do. So before start jumping on the code you will have to configure git in your local machine and send a pull request. It was my first hand experience of making contribution to an FOSS project and using github pull request. I will be giving step by step procedure to create a new pull request and make a commit which i have done for my project datagrepper.     


Check whether git is installed in your machine or not

$ git --version


if it returns string like “git version X.X.X.X” then it is installed if not; then type the command

 $ sudo yum install -y git (fedora) or sudo apt-get install git (Ubuntu)

 

Now If you have not configured your git, first do that with these commands.
$ git config --global user.name "Your name here"
$ git config --global user.email "your_email@example.com"
Steps to make a new commit:
 
As you will make contribution to someone’s else project, so you will first have to ‘fork’ that repository.
 
To fork the project, click on the “fork” button on the github repository.

 
Then you will have to clone your fork. This will clone the project on your local machine and now, you can make changes to it.
$ git clone https://github.com/fedora-infra/datagrepper.git
$ cd datagrepper
# changes the active directory in the prompt to the newly cloned "datagrepper" directory.
 
Now, you will have to add the file in which you have made changes to the git.
 
For the first patch i have made changes in /datagrepper/app.py and /datagrepper/util.py
$ cd datagrepper
$ git add app.py
$ git commit app.py
# write the changes you have made in app.py in the new window that opens up.
$ git add util.py
$ git commit util.py
# write the changes that you have made in util.py.
$ cd ..
$ git push origin
# here you can add branches like master

this will ask you to enter your user-name and password.

Hurray!    you have created a new commit.Now your commit has been made on the forked repository. To create pull request click on the pull requests link on the project repository page.

Now click on the new pull request tab.

Thereafter click on the compare across forks and select the forks accordingly.

Then change the branch range and destination repository across forks

Now review the changes made.
Click Click to create a pull request for this comparison.

Enter a title and description for your pull request.
Click Send pull request
Happy Learning 🙂