Introduction
You might wonder, "Why did the Bottle framework become popular among web developers?"
The Bottle web framework has a 4% market share among Python web frameworks and is ranked fifth in popularity. It is excellent for rapid development, personal web applications, and prototyping.

Read the following article to understand how to deal with Common Use Cases in the Bottle Framework in Python.
Common Use Cases in Bottle Framework
This is a collection of code samples and Common Use Cases in the Bottle Framework.
Keeping Track of Sessions
Due to the lack of a recommended method, there is no built-in support for sessions (in a micro framework). You could either utilize beaker middleware with a suitable backend or write it yourself, depending on the circumstances and environment. An illustration of a beaker session with a file-based backend in this Common Use Cases in the Bottle Framework is shown below:
import bottle
from beaker.middleware import SessionMiddleware
session_opts = {
'session.type': 'file',
'session.cookie_expires': 300,
'session.data_dir': './data',
'session.auto': True
}
app = SessionMiddleware(bottle.app(), session_opts)
@bottle.route('/test')
def test():
s = bottle.request.environ.get('beaker.session')
s['test'] = s.get('test',0) + 1
s.save()
return 'Test counter: %d' % s['test']
bottle.run(app=app)
Caution⚠️ SessionMiddleware from Beaker is not thread-safe. One of the updates may be lost if two requests edit the same session simultaneously. Sessions should be handled as a read-only store after their initial populating. Consider using an actual database instead of session middleware packages if you frequently update sessions and don't want to lose any updates in this Common Use Cases in the Bottle Framework.
Debugging with Style: Debugging Middleware
Bottle catches any Exceptions raised in your app code to prevent the failure of your WSGI server. You can disable this behavior if the built-in debug() mode is insufficient, and you require exceptions to propagate to a debugging middleware:
import bottle
app = bottle.app()
app.catchall = False #Most bottle exceptions are raised again.
myapp = DebuggingMiddleware(app) #Replace it with a middleware of your choosing (see below)
bottle.run(app=myapp)
Now that your middleware can handle the rest, Bottle only catches its exceptions (HTTPError, HTTPResponse, and BottleException).
The werkzeug and paste libraries have fairly powerful WSGI middleware for debugging. Take a look at werkzeug.debug.DebuggedApplication for paste and werkzeug in paste.evalexception.middleware.EvalException when trying to paste. Please do not use them in production because they allow you to inspect the stack and even run Python code inside the stack context.
Unit Testing Bottle Applications
A WSGI environment is typically not operating during unit testing against methods defined in your web application’s Common Use Cases in the Bottle Framework.
An easy illustration with Nose:
import bottle
@bottle.route('/')
def index():
return 'Hello'
if __name__ == '__main__':
bottle.run()
A test script:
import mywebapp
def test_webapp_index():
assert mywebapp.index() == 'Hello'
Only index() is tested in the example; the Bottle route() method is never used.
You can use Boddle to simulate bottle.request if the code being tested needs access to it:
import bottle
@bottle.route('/')
def index():
return 'HELLO %s!' % bottle.request.params['name']
A test script:
import mywebapp
from boddle import boddle
def test_webapp_index():
with boddle(params={'name':'CodingNinjas'}):
assert mywebapp.index() == 'HELLO CodingNinjas'
Functional Testing of Bottle Application
One of the most frequent Common Use Cases in the Bottle Framework can be used with any HTTP-based testing system. However, some testing frameworks have a closer relationship with WSGI and offer the ability to call WSGI apps in a controlled environment with tracebacks and full access to debugging tools. An excellent place to begin is by Testing the tools for WSGI.

An illustration using WebTest and Nose:
from webtest import TestApp
import mywebapp
def test_functional_login_logout():
app = TestApp(mywebapp.app)
app.post('/login', {'user': 'foo', 'pass': 'bar'}) #recieve cookie by logging in
assert app.get('/admin').status == '200 OK' # successfully retrieve a page.
assert app.get('/logout').status_code == 200 # logout
app.reset() # Set the cookie down
# attempt to obtain the same page in vain
assert app.get('/admin', expect_errors=True).status == '401 Unauthorized error'

Embedding other WSGI Applications
You can access other WSGI applications from within your bottle and let the bottle operate as pseudo-middleware. At the same time, this is not the recommended method (you should use middleware in front of the bottle to do this). Here's an illustration of this Common Use Cases in the Bottle Framework:
from bottle import request, response, route
subproject = SomeWSGIApplication()
@route('/subproject/<subpath:re:.*>', method='ANY')
def call_wsgi(subpath):
new_environ = request.environ.copy()
new_environ['SCRIPT_NAME'] = new_environ.get('SCRIPT_NAME','') + '/subproject'
new_environ['PATH_INFO'] = '/' + subpath
def start_response(status, headerlist):
response.status = int(status.split()[0])
for key, value in headerlist:
response.add_header(key, value)
return app(new_environ, start_response)
Once more, it is not advised to implement subprojects in this manner. It is just present because many people requested it to demonstrate how bottle maps to WSGI.
Ignore Trailing Slashes
It is one of the most Common Use Cases in the Bottle Framework. Both /example and /example/ are distinct routes in Bottle. The following two @route decorators can be added to treat both URLs equally:
@route('/test')
@route('/test/')
def test(): return 'Slash? no?'
A WSGI middleware that removes trailing slashes from all URLs should be added:
class StripPathMiddleware(object):
def __init__(self, app):
self.app = app
def __call__(self, e, h):
e['PATH_INFO'] = e['PATH_INFO'].rstrip('/')
return self.app(e,h)
app = bottle.app()
myapp = StripPathMiddleware(app)
bottle.run(app=myapp)
Alternatively, provide a before_request hook to remove the trailing slashes:
@hook('before_request')
def strip_path():
request.environ['PATH_INFO'] = request.environ['PATH_INFO'].rstrip('/')
Footnote📝 Since they are Take a look at <http://www.ietf.org/rfc/rfc3986.txt>.
Keep Alive Request
When used with the response header "Connection: keep-alive," specific "push" techniques, such as XHR multipart, require the ability to write response data without terminating the connection. Although WSGI does not naturally support this behavior, Bottle still allows it by utilizing the gevent async framework. The following sample can be used with either the paste HTTP server or the gevent HTTP server. To operate the paste server, change server='gevent' to server='paste':
from gevent import monkey; monkey.patch_all()
import gevent
from bottle import route, run
@route('/stream')
def stream():
yield 'BEGIN'
gevent.sleep(3)
yield 'MID'
gevent.sleep(5)
yield 'END'
run(host='0.0.0.0', port=8080, server='gevent')
When you visit http://localhost:8080/stream, the words "START," "MIDDLE," and "END" should appear one after the other (rather than waiting 8 seconds to see them all at once).
GZIP Compression in Bottle
Gzip compression, is a Common Use Cases in the Bottle Framework that speeds up websites by condensing static resources (such as CSS and JS files) during a request. Supporting Gzip compression is complicated because several corner cases constantly arise. An appropriate Gzip implementation must:
⭐ Be quick while compressing on the fly.
⭐ For browsers without Support, avoid compressing.
⭐ Do not compress already compressed files (images, videos).
⭐ Dynamic files shouldn't be compressed.
⭐ Support for two distinct compression techniques (gzip and deflate).
⭐ Files that don't change regularly should be cached.
⭐ If one of the files changed despite this, de-validate the cache.
⭐ Be careful the cache doesn't grow too large.
⭐ Avoid caching small files since on-the-fly compression is faster than a disc seek.
The Bottle project advises that the WSGI server that Bottle runs on top of handle Gzip compression best due to these needs. GzipFilter middleware is offered by WSGI servers like CherryPy and can be used to do this.
Using the Hooks Plugin
For instance, you may enable Cross-Origin Resource Sharing for the information provided by all of your URLs by using the hook decorator and a callback function:

from bottle import hook, response, route
@hook('after_request')
def enable_cors():
response.headers['Access-Control-Allow-Origin'] = '*'
@route('/foo')
def say_foo():
return 'foo!'
@route('/bar')
def say_bar():
return {'type': 'friendly', 'content': 'HELLO'}
Additionally, you may use before_request to do a task before each function is invoked.
Using Bottle with Heroku
Python applications can now be executed on Heroku architecture's well-known cloud application platform. The Write Your App section of the Getting Started with Python on Heroku/Cedar guide has been replaced with Bottle-specific code in this recipe, which is based on the Heroku Quickstart:
import os
from bottle import route, run
@route("/")
def hello_world():
return "Hello World"
run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))
Using the os.environ dictionary, Heroku's app stack passes the port on which the application must listen for requests in this Common Use Cases in the Bottle Framework.
You can also practice with the help of Online Python Compiler






