Of course! The combination of Python, the Bottle web framework, and HTTPS is a very common and practical scenario for building secure web services or small applications.

Here’s a comprehensive guide covering everything from the basics to production deployment.
The Core Concepts
- Python: The programming language.
- Bottle: A lightweight, single-file WSGI web framework for Python. It's great for small projects, APIs, and microservices because it has no external dependencies.
- HTTPS (HTTP Secure): The secure version of HTTP. It encrypts the communication between the client (browser) and the server using an SSL/TLS certificate. This is essential for protecting sensitive data like passwords, tokens, and user information.
The Problem: Why Bottle's Default Server Isn't Enough
Bottle comes with a simple, built-in development server (run()). This server is not suitable for production, and crucially, it does not support HTTPS out of the box.
To use HTTPS, you need a more capable WSGI server. The most popular and recommended choice for Python is Gunicorn.
The Solution: Gunicorn + SSL Certificates
The standard approach is to:

- Use Gunicorn as the production WSGI server.
- Configure Gunicorn to use an SSL certificate and key to handle the encryption.
Step-by-Step Guide: Running a Bottle App with HTTPS
Let's walk through creating a simple Bottle app and running it with HTTPS.
Step 1: Install Necessary Packages
You'll need bottle and gunicorn. It's also highly recommended to use a virtual environment.
# Create and activate a virtual environment python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # Install the packages pip install bottle gunicorn
Step 2: Create a Simple Bottle App
Create a file named app.py:
# app.py
from bottle import route, run, request, response, static_file
# A simple route
@route('/')
def index():
return "Hello, HTTPS World! Your request was secure: {}".format(request.url.startswith('https'))
# A route that demonstrates secure cookie handling
@route('/login')
def login():
response.set_cookie("user_session", "secure_token_1234", secure=True, httponly=True)
return "Logged in! Check your cookies for a 'user_session'."
# A route to serve a static file (e.g., an HTML page)
@route('/static/<filename>')
def server_static(filename):
return static_file(filename, root='./static')
if __name__ == '__main__':
# This is the development server (HTTP only)
run(host='0.0.0.0', port=8080, debug=True)
Step 3: Get SSL Certificates
You need two files:

cert.pem: Your SSL certificate.key.pem: Your private key.
Option A: For Development (Self-Signed Certificate)
This is not for production but is perfect for local testing. You can generate one using the openssl command.
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes
This command will prompt you for some information (Country, State, etc.). You can just press Enter for all of them. It will create cert.pem and key.pem in your current directory.
Option B: For Production (Let's Encrypt)
For a public-facing site, you should use a free certificate from Let's Encrypt. Tools like Certbot make this process automatic.
Step 4: Run the App with Gunicorn and HTTPS
Now, instead of running python app.py, you'll use Gunicorn. The key is to use the --keyfile and --certfile options.
Open your terminal in the same directory as app.py and run:
gunicorn --bind 0.0.0.0:443 --keyfile key.pem --certfile cert.pem app:app
Let's break that command down:
gunicorn: The command to run the server.--bind 0.0.0.0:443: Binds the server to all available network interfaces on port 443 (the standard HTTPS port).--keyfile key.pem: Specifies the path to your private key.--certfile cert.pem: Specifies the path to your SSL certificate.app:app: Tells Gunicorn to find the WSGI application namedappinside the module namedapp.py. The firstappis the filename (app.py), and the secondappis the variable holding the Bottle application instance.
Important: Your browser will now show a security warning for a self-signed certificate. This is expected and normal. You can click "Advanced" and "Proceed" to access the site. You should see "Hello, HTTPS World! Your request was secure: True".
Production Considerations: Reverse Proxy
While Gunicorn can handle SSL directly, a more robust and common production architecture uses a reverse proxy like Nginx or Apache.
Why use a reverse proxy?
- SSL Termination: The proxy handles the heavy lifting of SSL encryption/decryption, passing unencrypted traffic to the faster Gunicorn workers. This simplifies your application server setup.
- Load Balancing: You can run multiple Gunicorn instances and have Nginx distribute traffic between them.
- Static Files: Nginx is much more efficient at serving static files (CSS, JS, images) than Gunicorn.
- Security & Caching: Nginx provides an extra layer of security and can handle caching.
Simplified Nginx Configuration Example
Here’s a snippet of what your Nginx configuration (/etc/nginx/sites-available/myapp) might look like:
server {
listen 80;
server_name your_domain.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name your_domain.com;
# SSL configuration
ssl_certificate /path/to/your/fullchain.pem; # From Let's Encrypt
ssl_certificate_key /path/to/your/privkey.pem; # From Let's Encrypt
# Proxy settings to pass requests to Gunicorn
location / {
proxy_pass http://127.0.0.1:8000; # Gunicorn runs on port 8000
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
In this setup:
- Nginx listens on port 80 (HTTP) and redirects all traffic to port 443 (HTTPS).
- Nginx listens on port 443, terminates the SSL connection using the certificates from Let's Encrypt.
- Nginx forwards the unencrypted request to Gunicorn, which runs on a non-privileged port like
8000. - You would then run Gunicorn without the SSL flags:
gunicorn --bind 127.0.0.1:8000 app:app
Summary & Best Practices
| Scenario | Recommended Server | Command/Configuration | Use Case |
|---|---|---|---|
| Local Development | Bottle's run() |
python app.py |
Quick testing, no security needed. |
| Local HTTPS Development | Gunicorn with self-signed certs | gunicorn --bind 0.0.0.0:443 --keyfile key.pem --certfile cert.pem app:app |
Testing HTTPS functionality locally. |
| Simple Production | Gunicorn with real certs | gunicorn --bind 0.0.0.0:443 --keyfile key.pem --certfile cert.pem app:app |
Small projects, no complex traffic needs. |
| Robust Production (Highly Recommended) | Nginx (Reverse Proxy) + Gunicorn | Nginx handles SSL on port 443 and proxies to Gunicorn on a local port (e.g., 8000). Gunicorn runs without SSL flags. | Standard, scalable, and secure deployment. |
