How To Use the Bottle Micro Framework to Develop Python Web Apps

How To Use the Bottle Micro Framework to Develop Python Web Apps

Status: Deprecated

This article covers a version of Ubuntu that is no longer supported. If you are currently operate a server running Ubuntu 12.04, we highly recommend upgrading or migrating to a supported version of Ubuntu:

Reason: Ubuntu 12.04 reached end of life (EOL) on April 28, 2017 and no longer receives security patches or updates. This guide is no longer maintained.

See Instead: This guide might still be useful as a reference, but may not work on other Ubuntu releases. If available, we strongly recommend using a guide written for the version of Ubuntu you are using. You can use the search functionality at the top of the page to find a more recent version.


Python is an excellent language for web programming due to its flexibility and high-level functionality. Web frameworks can make programming web applications much simpler because they connect many of the components necessary for a robust web interface.

While some web frameworks attempt to provide everything that a user might want to use to develop an application, others try to stay out of the way while taking care of the important, difficult to implement issues. Bottle is a Python framework that falls into the second category. It is extremely lightweight, but makes it very easy to develop applications quickly.

In this guide, we will cover how to set up and use Bottle to create simple web applications on an Ubuntu 12.04 server.

How To Install Bottle

Python, the programming language that Bottle is built for, comes installed on Ubuntu by default.

Install and Activate a Virtual Environment

We will install the virtualenv package to isolate our Python project from the system’s Python environment.

We can install this easily from the repositories:

sudo apt-get update
sudo apt-get install python-virtualenv

The virtualenv software allows us to create a separate, contained environment for our Python projects that will not affect the entire OS. We are going to create a projects folder in our home directory and then create a virtual environment within this folder:

mkdir ~/projects
cd ~/projects
virtualenv --no-site-packages venv

This creates a directory called venv within the projects directory. It has installed some Python utilities within this folder and created a directory structure to install additional tools.

We must activate the virtual environment before beginning to work on our project:

source venv/bin/activate

The command prompt will change to reflect the fact that we are operating in a virtual environment now. If you need to exit the virtual environment, you can type this at any time:


Do not deactivate your virtual environment at this point.

Install Bottle

One of the tools that the virtualenv program installed was pip.

This tool allows us to easily install Python packages from the Python package index, an online repository.

If we want to search for Python packages that have to do with Bottle, we can run:

pip search bottle

We will start by just installing the Bottle package:

pip install bottle

After the process completes, we should have the ability to use the Bottle framework within our applications.

Create Your First Bottle Application

Bottle, like most frameworks, implements a version of the MVC software pattern. MVC stands for model, view, and controller, and it describes a decision to separate the different functions of a user interface.

The model is a representation of a set of data and is responsible for storing, querying, and updating data. The view describes how information should be rendered to the user. It is used to format and control the presentation of data. The controller is the main processing center of the app, which decides how to respond to user requests.

Bottle applications can be incredibly simple. In their most bare form, they can implement all of these components within a single file. We will create a “hello world” application to show how this is done.

With your editor, create a Python application called hello.py:

nano hello.py

Within this file, we are going to first import some functionality from the Bottle package. This will allow us to use the framework tools within our application:

from bottle import route, run

This line tells our program that we want to import the route and run modules from the Bottle package.

The run module that we are importing can be used to run the application in a development server, which is great for quickly seeing the results of your program.

The route module that we are importing is responsible for telling the application what URL requests get handled by which Python functions. Bottle applications implement routing by calling a single Python function for each URL requested. It then returns the results of the function to the user.

We can add a route right now that will match the URL patter /hello:

from bottle import route, run


This route decorator matches the URL /hello when that path is requested on the server. The function that directly follows will be executed when this matches:

from bottle import route, run

def hello():
    return "<h1>Hello World!</h1>"

This function is very simple, but it completes the only requirement of a routing function: it returns a value that can be displayed in the web browser. In this case, the value is a simple HTML string. We could remove the h1 header tags and the same information would be displayed in an undecorated fashion.

Finally, we need to run our application using the development server:

from bottle import route, run

def hello():
    return "<h1>Hello World!</h1>"

run(host='', port=8080)

This line will run the server instance. By passing the parameter host='', this will serve the content to any computer, not just the local machine. This is important since our application is being hosted remotely. The port parameter specifies the port that this will be using.

Save and close the file.

We can run this application by typing this:

python hello.py

You can visit this application in your web browser by going to your IP address, followed by the port we chose to run on (8080), followed by the route we created (/hello):

<pre> http://<span class=“highlight”>your_ip</span>:8080/hello </pre>

DigitalOcean Bottle hello world

You can stop the server at any time by typing “CTRL-C” in the terminal window.

Implement the MVC Design Paradigm

We have now implemented our first application. It was certainly simple, but it doesn’t really implement MVC principles, or do anything particularly interesting. Let’s try to make a more complicated application this time.

Create the Model

Let’s start with our model. This is the portion of our program that handles the data storage. Bottle can easily implement a variety of backends for data through the use of plugins.

We will use an SQLite database file for our database. This is an extremely simple database designed for lightweight tasks that our application can implement.

Install the SQLite software in Ubuntu to make sure we have the software available to create and interact with these databases:

sudo apt-get install sqlite

We also need to download and install the Bottle plugin that will allow us to use these databases:

pip install bottle-sqlite

Now that we have the components, we can create a simple database that we can store our data in. We will create a Python file that will generate a SQLite database with some data in it when we run the script. We could do this in the Python interpreter, but this way makes it easy to repeat.

nano picnic_data.py

Here, we import the SQLite package. Then, we can execute a command that creates our table and inserts data in our table. Finally, we commit the changes:

import sqlite3
db = sqlite3.connect('picnic.db')
db.execute("CREATE TABLE picnic (id INTEGER PRIMARY KEY, item CHAR(100) NOT NULL, quant INTEGER NOT NULL)")
db.execute("INSERT INTO picnic (item,quant) VALUES ('bread', 4)")
db.execute("INSERT INTO picnic (item,quant) VALUES ('cheese', 2)")
db.execute("INSERT INTO picnic (item,quant) VALUES ('grapes', 30)")
db.execute("INSERT INTO picnic (item,quant) VALUES ('cake', 1)")
db.execute("INSERT INTO picnic (item,quant) VALUES ('soda', 4)")

Save and close the file.

We can execute the file, which will create a database file called picnic.db within our current directory:

python picnic_data.py

Our model portion of our program is now fairly complete. We can see that our model will dictate a little bit how our control portion must function to interact with our data.

Create the Controller

Now that we have a database created, we can start to develop our main application. This will mainly implement our controller functionality. It will also be the file that most closely resembles our first application.

Create a file called picnic.py to store our main application:

nano picnic.py

Within this file, we need to import some things from the Bottle package, just like before. We need some additional modules that we haven’t used before. In addition, we need to import the SQLite functionality:

import sqlite3
from bottle import route, run, template

Next, we’ll define a route that matches the URL path /picnic:

import sqlite3
from bottle import route, run, template


We’ll implement the function that connects to our database, gets our data from the table, and calls our “view” to render the page. Finally, it returns to formatted output to our user.

import sqlite3
from bottle import route, run, template

def show_picnic():
    db = sqlite3.connect('picnic.db')
    c = db.cursor()
    c.execute("SELECT item,quant FROM picnic")
    data = c.fetchall()
    output = template('bring_to_picnic', rows=data)
    return output

Finally, we need to put our run command to run the actual server:

import sqlite3
from bottle import route, run, template

def show_picnic():
    db = sqlite3.connect('picnic.db')
    c = db.cursor()
    c.execute("SELECT item,quant FROM picnic")
    data = c.fetchall()
    output = template('bring_to_picnic', rows=data)
    return output

run(host='', port=8080)

Save and close the file.

We connect to the database with the db = sqlite3.connect('picnic.db') command. We query the database and select all of our values with the next four lines.

The line where we call the “view” to format our data is output = template('bring_to_picnic', rows=data). This calls a template (view) called bring_to_picnic.tpl to format the data. It passes the “data” variable as the template variable “rows”.

We will create this template file in the next section.

Create the View

Now that we have our model and controller, the only thing left to create is our view. This is handled easily using Bottle’s built-in template engine.

The application will search for a template matching the name given in the template function, ending with .tpl. This can either be in the project’s main directory, or in a directory called “view”.

Create a file matching the one we called with the template function:

nano bring_to_picnic.tpl

In this file, we can mix HTML and programming. Ours will be very simple. It will use a loop to create a table, which we will populate with our model data:

<h1>Things to bring to our picnic</h1>
%for row in rows:
    %for col in row:

This will render our page in HTML. The templating language that we see here is basically Python. The “rows” variable that we passed to the template is available to use when designing the output.

We can type lines of Python by preceding them with “%”. We can access variables within the HTML by using the “{{var}}” syntax.

Save and close the file.

Viewing the Results

Our application is now complete and we can start the program by calling Python on the main file:

python picnic.py

We can see the results by visiting our IP address and port followed by the URL route we created:

<pre> http://<span class=“highlight”>your_ip</span>:8080/picnic </pre>

DigitalOcean Bottle mvc example


By now, you should be able to see how you can build complex applications using a simple, bare-bones micro-framework like Bottle. While our examples were simple, it is easy to take advantage of more advanced functionality.

Bottle’s plugin system is also an important asset. Plugins are actively shared within the community and it is easy to implement more complex behavior through the plugin system. One easy way to find plugins is by using the pip search bottle command. This will give you an idea of some of the more popular options.

<div class=“author”>By Justin Ellingwood</div>

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Good tutorial! I loved how you also introduce to SQLite, which I was tempted to use. Just a dumb question, how I can let the server running after closing the ssh session?

Thanks for the great tutorial.

I noticed a small syntax error… or rather python noticed it for me.

The first time this line appears it’s missing a comma…

output = template(‘bring_to_picnic’ rows=data)

the second time it has it: output = template(‘bring_to_picnic’, rows=data)

Additionally the first set of sql commands under “We’ll implement the function that connects to our database, gets our data from the table, and calls our “view” to render the page. Finally, it returns to formatted output to our user.” has the line:

c.execute("SELECT task,quant FROM picnic")

it should read:

c.execute("SELECT item,quant FROM picnic")
Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
March 9, 2014

@daniel: Thanks! I’ll correct it.

Good tutorial… However, you have rogue "T"s in your SQL:

db.execute(“INSERT INTO picnic (item,quant) VALUTES (‘bread’, 4)”)

Should read “VALUES” instead :)

Thank you so much.

by linuxtip.net

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel