Currency Converter with Bottle: Python web framework!

Introduction

In my first python article I have explained how to build simple currency converter with python. Now I will use Bottle Python web framework to build web app with it. Why bottle? It's a simple, but fast and powerful Python micro-framework, perfect for small web applications. I also find it to be great tool for those just getting started with python web development, you will see in this example that you can build web app with almost same code that we have used in console version of currency converter. For more information about Bottle visit http://bottlepy.org. You might want to read article that lead to this post:

Prerequisites

For this tutorial you will need Python 2.7 and pip installed:

pip install virtualenv
pip install requests
pip install bottle

now lets create bottle directory:

mkdir /home/bottle
cd bottle
mkdir app
virtualenv venv

now to activate virtual environment:

. venv/bin/activate

or in some cases it's better with:

source venv/bin/activate

Its always good to create the requirements.txt file, which allows you to install the exact same modules and dependencies in case you want to use this app elsewhere:

pip freeze > requirements.txt

to use this file in another environment:

pip install -r requirements.txt

Currency Converter

Writing code in bottle is like writing code in Python, nothing new and special here, for start we will import modules and create new file app.py:

from bottle import get, post, run, request
import requests

HTTP protocol defines several request methods, if you look at code above you will see get and post. I could have used route and call method get or post later in code, but I have chosen this way of doing things, you can read more about this in official bottle documentation. Now lets define our get method, and add it to app.py:

@get('/'
def index():
    return '''
        <form action="/convert" method="post">
                Convert From: <input name="convert_from" type="text" />
                Convert to: <input name="convert_to" type="text" />
                Value to convert: <input name="value_to_convert" type="float" />
                <input value="Convert" type="submit" />
        </form>
    '''

This is just a function to return basic html form. I will use http://rate-exchange.appspot.com to convert data from our form but you can use another source to do this, it does not need to return data in JSON format, but you would need to change the code. You can find alternative source and method to get data from webpage in original currency converter article here on site. Now lets define post method to execute python code, which will return new template with result:

@post('/convert')
def convert():
    convert_from = request.forms.get('convert_from').upper()
    convert_to = request.forms.get('convert_to').upper()>
    value_to_convert = request.forms.get('value_to_convert')
    url = ('http://rate-exchange.appspot.com/currency?from=%s&to=%s&q=1') % (convert_from, convert_to)
    rate = requests.get(url).json()['v']
    converted = float(value_to_convert)*float(requests.get(url).json()['v'])

    return '''<p>Current exchange rate %s to %s is: <b>%s</b></p>
        <p>Exchange value is: <b>%s</b></p>''' % (convert_from, convert_to, rate, converted)

Final step is to run our app, you add this to app.py:

run(host='localhost', port=8080, debug=True)

if you want your app to listen from all IP addresses not only localhost, change last line to:

run(host='0.0.0.0', port=8080, debug=True)

you can also change port, for development leave debug True, but if you ever make your app public change that to False.

And now whole code together:

from bottle import get, post, run, request
import requests

@get('/'
def index():
    return '''
        <form action="/convert" method="post">
                Convert From: <input name="convert_from" type="text" />
                Convert to: <input name="convert_to" type="text" />
                Value to convert: <input name="value_to_convert" type="float" />
                <input value="Convert" type="submit" />
        </form>
    '''

@post('/convert')
def convert():
    convert_from = request.forms.get('convert_from').upper()
    convert_to = request.forms.get('convert_to').upper()>
    value_to_convert = request.forms.get('value_to_convert')
    url = ('http://rate-exchange.appspot.com/currency?from=%s&to=%s&q=1') % (convert_from, convert_to)
    rate = requests.get(url).json()['v']
    converted = float(value_to_convert)*float(requests.get(url).json()['v'])

    return '''<p>Current exchange rate %s to %s is: <b>%s</b></p>
        <p>Exchange value is: <b>%s</b></p>''' % (convert_from, convert_to, rate, converted)

run(host='localhost', port=8080, debug=True)

One more improvement would be to add drop-down list to select currencies to convert from and convert to. In bottle this is very simple its like writing html code, just replace our get method with code bellow and restart your application:

    @get('/index')
    def select():
    return '''
    <form action="/convert" method="post">
            <p>Convert From:<select name="convert_from">
            <option value="USD">US Dollar</option>
            <option value="EUR">Euro</option>
            <option value="GBP">British Pound</option>
            </select>
            </p>
            <p>Convert To:  <select name="convert_to">
            <option value="EUR">Euro</option>
            <option value="USD">US Dollar</option>
            <option value="GBP">British Pound</option>
            </select>
            </p>
            <p>Value to convert: <input name="value_to_convert" type="float" /></p>
        <input value="Convert" type="submit" />
</form>
'''

I have added only 3 currencies for example purposes, and made sure that default value in Convert From and Convert To are not same. You should get output like this:

Convert From:

Convert To:

Value to convert:

Next time I will add some template to this form.

Update

You can read part 2 of this post:

Comments !

social