Bottle Microframework — Core Concepts

What Bottle is

Bottle is a fast, simple, and lightweight WSGI micro web framework for Python. Created by Marcel Hellkamp in 2009, its defining characteristic is that it’s distributed as a single Python file with zero dependencies outside the Python standard library.

The entire framework — routing, templates, request/response handling, a built-in development server, and plugin system — fits in roughly 4,000 lines of code. You can read the entire source in an afternoon.

Core features

Routing uses decorators to map URLs to functions:

@route("/hello/<name>")
def hello(name):
    return f"Hello, {name}!"

Routes support type filters (<id:int>, <path:path>, <name:re:[a-z]+>) and multiple HTTP methods on the same route.

Built-in template engine called SimpleTemplate provides basic templating with Python expressions embedded in HTML. It also supports Mako, Jinja2, and Cheetah if you prefer.

Request and response objects are thread-local, giving you access to query parameters, form data, cookies, headers, and file uploads through a clean API.

Plugin system lets you extend Bottle with database connections, authentication, or any cross-cutting concern. Plugins hook into the request lifecycle without modifying your handler code.

The zero-dependency philosophy

Most Python packages have dependency trees — install one thing, and it pulls in five others. This creates:

  • Version conflicts between packages
  • Security vulnerability surface area
  • Deployment complexity
  • Reproducibility challenges

Bottle sidesteps all of this. Copy bottle.py into your project. Done. This is especially valuable in:

  • Embedded systems — Raspberry Pi, IoT devices with limited storage
  • Restricted environments — corporate networks without PyPI access
  • Education — students can start without understanding pip, virtualenvs, or package management
  • Scripting — add a web interface to an existing Python script with minimal friction

How Bottle compares

vs. Flask: Flask is Bottle’s closest relative. Both are micro-frameworks with decorator-based routing. Flask has a larger ecosystem (hundreds of extensions), better documentation, and wider adoption. Bottle has zero dependencies and a simpler mental model. For production web apps, Flask usually wins. For quick prototypes and embedded contexts, Bottle’s simplicity is unmatched.

vs. FastAPI: FastAPI targets async APIs with automatic validation and OpenAPI docs. It’s a different class of tool — heavier, more capable, designed for production API services. Bottle is for when FastAPI is overkill.

vs. Django: Django is a full-stack framework with ORM, admin, auth, and middleware. Comparing Django to Bottle is like comparing a restaurant kitchen to a camping stove. Different tools for different jobs.

Plugin architecture

Bottle’s plugin system is straightforward:

from bottle import install

def db_plugin(func):
    def wrapper(*args, **kwargs):
        db = create_connection()
        try:
            return func(db=db, *args, **kwargs)
        finally:
            db.close()
    return wrapper

install(db_plugin)

Several community plugins exist for SQLAlchemy, MongoDB, Redis, and CORS handling. But the ecosystem is much smaller than Flask’s — if you need lots of extensions, Flask is a better choice.

Limitations to understand

Bottle is intentionally minimal, which means:

  • No async support — Bottle is WSGI-only, synchronous. If you need async, look elsewhere.
  • No built-in ORM — you bring your own database layer
  • Small community — fewer Stack Overflow answers, fewer tutorials, fewer maintained plugins
  • Not for large apps — Bottle doesn’t have blueprints or app factories for organizing large codebases (though you can implement these patterns manually)

These aren’t bugs — they’re design decisions. Bottle optimizes for simplicity and self-containedness, not for scaling to large team projects.

Common misconception

People sometimes dismiss Bottle as a “toy” framework. While it’s true that Bottle isn’t designed for large production systems, “toy” implies it’s not reliable. Bottle has been stable for over 15 years, handles WSGI correctly, and works perfectly for its intended use cases: small APIs, prototypes, embedded interfaces, and educational projects.

The one thing to remember: Bottle’s power is radical simplicity — one file, zero dependencies, a complete web framework. Choose it when the overhead of a bigger framework would cost more than the features you’d gain.

pythonweb-frameworksmicroframeworkbottle

See Also

  • Python Aiohttp Client Understand Aiohttp Client through a practical analogy so your Python decisions become faster and clearer.
  • Python Api Client Design Why building your own API client in Python is like creating a TV remote that only has the buttons you actually need.
  • Python Api Documentation Swagger Swagger turns your Python API into an interactive playground where anyone can click buttons to try it out — no coding required.
  • Python Api Mocking Responses Why testing with fake API responses is like rehearsing a play with stand-ins before the real actors show up.
  • Python Api Pagination Clients Why APIs send data in pages, and how Python handles it — like reading a book one chapter at a time instead of swallowing the whole thing.