Skip to main content

Making web app with bottle and python Tutorial - part 4 - Extending your bottle knowledge

Previous Part: Making web app with bottle and python - part 3 - Creating a basic bottle application
In the previous part we have seen how to create a basic bottle web application and run the server. We have also seen on how to use template files with bottle. In this part we will use our knowledge and see some more concepts that we have not covered in the previous tutorial.  This part will be a smaller one!

Let us start off with how to change the content of the template depending on the user input. Here user input refers to the 'url' and not submitting the HTML forms. We will be using the dynamic url concept that we have learnt earlier in this section. Let's say I have the following tpl file written in HTML and CSS:
<!doctype html>
<html>
 <head>
  <title>Radius Of Circle</title>
  <meta charset='utf-8' />
  <style type="text/css">
  .heading{
   text-align: center;
  }
  </style>
 </head>
 <body>
  <div class="heading">
   <h1>Hello {{name}}</h1>
  </div>
  <div>
   Welcome to RADIUS OF CIRCLE's weave tutorial
   Have a happy and great day!
  </div>
 </body>
</html>

I have saved the above file as 'index.tpl'

If you have observed there is a {{name}} in the h1 tag of the heading class. In bottle it means that {{name}} is a variable and the python script will return the value of the variable. So when compiling {{name}} should be replaced with value of the variable. Okay now we will see the corresponding python script:
from bottle import run, route, template

@route('/<name>')
@route('/<name>/')
def a(name):
    return template('bottle_app',name=name)

#ROUTE For /
@route('/')
@route('')
def b():
    return template('bottle_app',name='Guest')

run(reloader=True)
Now go to command prompt, run the above code and visit the following url's:

  1. http://localhost:8080/Anivarth
  2. http://localhost:8080/

You will find something like this for the first url:
Generating Dynamic template with bottle.py and python
Bottle app Dynamic template
Try with new names and you will see the difference.

If you have surfed the internet before then, I'm sure that you have somewhere encountered the 404 error. 404 means that the file was not found on the server. There are many other error which occur on the internet. 

In conventional way when you see a 404 error it would look something like this:

Conventional 404 error page
Conventional 404 Error Source: Whatswp.com
But bottle shows it in a different way. It will look something like this:
404 Error example in bottle framework
404 Error in bottle Framework
Okay now you may have a doubt on why we are discussing all these stuff?

If you have visited some websites like Github, Google, Amazon etc, you will see 404 error in a way something like this:
An error 404 page in Github
Source: Github.com
Yes, you have guessed it right! We can do something like this with bottle also. We can handle all these errors in a neat and stylish way with bottle rather than using the conventional systems. 

Before we write our python code to handle our error we will first create a basic template that will be displayed when the error has occured:

<!doctype html>
<html lang="en">
 <head>
 <title>Radius of circle {{e}} page</title>
 <meta charset='utf-8' />
 </head>
 <body>
  <div class='text'>
   <h1>
    Oops! An Error Occured
   </h1>
   <h2>The server returned a '{{e}}'</h2>
   <p>Something is broken. Please let us know what you were doing when this error occured. We will fix the problem soon. </p>
  </div>

 </body>
</html>
I have saved this file as '404.tpl'. Here, after compiling the template file,{{e}} which represents the error that has occurred will be changed in both the  <title> and <h2> with corresponding error code.

Now lets see the python code:

from bottle import run, template, error, response

@error(404)
def error404(error):
    return template('404',e=response.status_code)

run(reloader=True)
In the above code we have imported run, template, error and response. While run, template, error are familiar to you I will tell you why I have imported the response object. According to the official documentation:
The Response class stores the HTTP status code as well as headers and cookies that are to be sent to the client.
As we are creating an error page and we don't know what kind the error our user may face we have imported the Response object. So when response.status_code is used it will give the server response

Now run the above python file and when you hit the error page you should see something like this:
Customized error page in bottle framework An example of 404 Error
Customized error pages in Bottle framework
Here in our case 404 error occurred and thus the we can see 404 error but if in case 504 error occurred then we will see 504 instead of 404. Remember that we can add CSS Javascript and many other things to this to make the customized 404.tpl look beautiful.

Till now we have been using inline CSS to style the HTML page. You may have a question on why we were using inline CSS instead of using external stylesheets?

If we had to use stylesheets or any other static files then we will have to tell bottle that there are stylesheets that are to be served when requested. Lets say you have saved your CSS file as style.css in the working directory. Then this will be the python code to serve your static file(style.css):

from bottle import run, static_file, route

@route('/style')
def style():
    return static_file('style.css',root='')

run(reloader=True)
In the above code we have imported static_file from bottle to use it.  While calling static_file we have added the file name style.css along with the extension and the place at which the file resides in the root parameter.

Okay now you may have a doubt that if the static file was in some other folder then? For this question I will give you a generalized answer so that you will understand on how to serve static files:

from bottle import run, static_file, route

@route('/style')
def style():
    return static_file('style.css',root='path/to/static/file')

run(reloader=True)
If you want to serve any other static file then replace the file name and the path in the root parameter. 

So you can add the code for each and every static file you will be serving. But this would make your code very untidy. To solve this problem first I will create folders in my working directory as follows:

`--weave.py
`--static
|  `--css
|  `--fonts
|  `--img
|  `--js

Then I will add the following code:

from bottle import run, static_file, route, get

# Static Routes
@get('/<filename:re:.*\.js>')
def javascripts(filename):
    return static_file(filename, root='static/js')

@get('/<filename:re:.*\.css>')
def stylesheets(filename):
    return static_file(filename, root='static/css')

@get('/<filename:re:.*\.(jpg|png|gif|ico)>')
def images(filename):
    return static_file(filename, root='static/img')

@get('/<filename:re:.*\.(eot|ttf|woff|svg)>')
def fonts(filename):
    return static_file(filename, root='static/fonts')

run(reloader=True)
With the above code you can use as many files as you want without any problem. The above code was written by Sanketh Katta here: Bottle Static Files.

Note: Serving of static files using bottle is not recommended in the production version. The above code is usually used only in the development server. But as our web app is small we will use it directly.


Congrats you have completed another part in the series. While I have tried to cover almost all the topics which are important in bottle I would have missed some or the other. Even if I have missed any topic I am sure that with this knowledge you will be able to create most of the bottle applications especially our weather web app weave

In the next tutorial we will start creating our weather web app weave.

I hope you have enjoyed this part. If you have any doubt or didn't understand anything then please comment in the comment box below or contact me. I will for sure come back to you as soon as possible. You can contact me from here: Contact me

Also please do comment on how I can improve this post such that everyone will be comfortable reading this or if I have made any mistake. Comment if you want me to add any topic in this section. Let us share the knowledge we have!

Thank you. Have a great day :)

The above code was highlighted using hilite.me.

Popular posts from this blog

Making a quiz web app with python and flask

Edit : When you are creating a web app with h tml templates, then y ou will have to sa ve the html file in templates folder in the Current Wor ki ng Directory( CWD). If you save the file in the C W D directl y you will get a TemplateNotFound error. Thank you Udhay for pointing it out.   In this post we will create a quiz website using python . I will be using the flask framework . After reading this tutorial you will learn form submission , flask templates , python code in flask templates , shuffling the questions and options with the random module and few others.  Please note that this tutorial is not big as it seems to be. Some of the code has been rewritten to maintain consistency and also font size is somewhat big so that your eyes won't get stressed reading this tutorial. Also the content has not occupied the full width of the page. In this tutorial I am assuming that you are having a very basic understanding of the flask framework . Please refer the documentation

Problem 11 Project Euler Solution with python

Largest product in a grid In the 20×20 grid below, four numbers along a diagonal line have been marked in red. 08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08 49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00 81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65 52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91 22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80 24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50 32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70 67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21 24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72 21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95 78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92 16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57 86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58 19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40 04 52 08 83 97 35 99 16 07

Problem 60 Project Euler Solution with python

Prime pair sets The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property. Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime. This problem is j u st a brute force problem. If you have come here because you don't know the limit upto which you will h ave to gener ate the prime numbers t hen go ahe ad and t r y with 10,000 . When I first start ed solving the problem I chose 1 million(beca use most of the problem s on project E uler have this limit ), but it took very long for the computer to fin d the solution. After searching on the internet then I found many people choosing 10, 000 so I have changed my in put f rom 1 million to 10000 and the output was f ast. He