Bottle
Bottle is an all-in-one software for meal delivery businesses, enhancing operational efficiency and customer management.
Websites Using Bottle
No websites detected yet. Analyze a website to contribute data.
What Is Bottle?
Bottle, often written as Bottle.py, is a fast, simple, and lightweight WSGI micro web framework for Python. Its defining trait is radical minimalism: the entire framework is distributed as a single Python file with no dependencies other than the Python standard library. That single-file design means you can drop bottle.py next to your application and start serving web pages with nothing else installed, which makes it a favorite for small applications, prototypes, embedded devices, internal tools, and learning projects.
Bottle is open source under the permissive MIT license and has been maintained for well over a decade as a community project. It deliberately occupies the "micro" end of the Python web-framework spectrum, the same neighborhood as Flask, in contrast to "batteries-included" full-stack frameworks like Django that bundle an ORM, an admin interface, authentication, and much more. Bottle bundles only the essentials: URL routing, a built-in development server, a small templating engine, and convenient helpers for handling requests and responses.
It is important to frame Bottle correctly relative to its peers. People often line up Django, Flask, and Bottle as three points on a single spectrum from heavy to light, and there is truth to that, but Bottle is best understood as the most stripped-down practical option. Where Flask is already minimal and relies on external libraries (Werkzeug and Jinja2) under the hood, Bottle goes further and depends on nothing at all beyond Python itself. That self-contained nature is precisely what makes it attractive for constrained environments, single-file utilities, and situations where adding dependencies is undesirable.
Bottle is a server-side framework, not a browser tool or a front-end library. It runs on a web server as a Python WSGI application, generating HTML, JSON, or other responses on the server and sending them to the browser. Because it is so minimal and is frequently deployed for small services and APIs, Bottle does not announce itself as loudly as a content management system would, which makes detecting it a matter of reading the subtler signals a Python WSGI app leaves behind rather than looking for an obvious brand fingerprint.
How Bottle Works
At its core, Bottle is a WSGI application. WSGI (the Web Server Gateway Interface) is the standard Python specification that sits between web servers and Python web applications, and Bottle implements it in a single file. You import Bottle, define routes, and run the app; in production, a WSGI server such as Gunicorn, uWSGI, or Waitress (or an adapter to a server like Apache via mod_wsgi) hosts the application and forwards requests to it.
Routing is Bottle's central feature and is built around decorators. You attach a route to a function with @route('/path') (or shortcuts like @get, @post, @put, and @delete), and Bottle calls that function whenever a matching URL is requested. Routes support dynamic segments and typed wildcards, for example /user/<name> or /item/<id:int>, so a single handler can serve a family of URLs. The return value of the function becomes the response body, and returning a Python dictionary automatically produces a JSON response, which makes Bottle convenient for small APIs.
Request and response handling is exposed through simple, thread-safe objects. A global request object provides access to query parameters, form data, cookies, headers, and the request body, while a response object lets you set status codes, headers, and cookies. Bottle includes helpers for redirects, static file serving, file downloads, aborting with an HTTP error, and reading or setting cookies, including signed cookies for lightweight session-like use.
Templating comes built in via the Simple Template Engine (SimpleTemplate), which lets you embed Python expressions and control flow directly in template files, typically with a .tpl extension. Bottle can also plug into popular external template engines such as Jinja2, Mako, or Cheetah through thin adapters, so teams that prefer those tools are not forced onto SimpleTemplate. Rendering is done with a template() helper or a @view() decorator on a route.
The development server ships in the box. Calling run() starts a built-in WSGI server suitable for development, and Bottle includes adapters for many production servers so you can switch hosts by changing a single argument. For larger applications, Bottle supports mounting multiple app instances and using plugins, small hooks that wrap route callbacks, to add cross-cutting behavior such as database connections or authentication. This plugin system is how Bottle stays tiny at its core while still being extensible when a project grows.
A useful way to picture the workflow is to follow a single request. A WSGI server receives an HTTP request and hands it to the Bottle application; Bottle matches the URL against its registered routes; the matched function runs, reading any parameters from the request object and returning a string, a dictionary, or a rendered template; Bottle wraps that return value in an HTTP response, applying any headers or status set on the response object, and the WSGI server sends it back to the client. The entire path, from routing to response, is implemented in that one compact file, which is the essence of Bottle's appeal.
How to Tell if a Website Uses Bottle
Detecting Bottle is harder than detecting a CMS, because a micro-framework deliberately adds little to the output and gives developers full control over the markup. There is no generator meta tag and no mandatory client-side script. StackOptic approaches this the same way you would by hand: inspecting HTTP response headers and the subtle structural clues that a small Python WSGI service tends to leave. The honest framing is that Bottle detection is usually inferential, you confirm "a Python WSGI app, very likely a micro-framework" and then look for the specific tells below.
The Server response header. This is the most useful signal. Bottle's built-in development server identifies itself in the Server header, and the default run() server is based on Python's WSGIRef, so you may see a header like Server: WSGIServer/... Python/.... If a site is running on Bottle's own dev server, that header is a strong hint. In production, however, the Server header usually reflects Gunicorn, uWSGI, Waitress, or a fronting Nginx, which masks the framework.
Default error pages. Bottle generates a recognizable HTML error page for uncaught exceptions and for 404s when running in its default configuration. The wording and structure of Bottle's stock error page (and its debug traceback page when debug mode is on) are distinctive, so triggering a 404 on a likely-Bottle site and reading the response can be revealing.
Header style and minimalism. Because Bottle is so lean, a Bottle response often carries a sparse, characteristic set of headers compared with a heavyweight framework. The absence of framework-specific cookies or headers (no Django csrftoken/sessionid, no Rails _session cookie, no X-Powered-By: Express) combined with a Python Server header points toward a Python micro-framework.
Content-Type and JSON behavior. Bottle automatically serializes returned dictionaries to JSON with the appropriate Content-Type: application/json header. An API that behaves this way, on a Python stack, is consistent with Bottle (though Flask behaves similarly, so this alone is not conclusive).
Here is how to check these signals yourself:
| Method | What to do | What it may reveal about Bottle |
|---|---|---|
| curl -I | curl -I https://example.com | The Server header (e.g. WSGIServer ... Python/...) and a sparse header set |
| Browser DevTools | Open the Network tab, inspect response headers | Same Server header, Content-Type, and absence of other frameworks' cookies |
| Trigger a 404 | Request a non-existent path and read the body | Bottle's distinctive default error-page markup |
| View Source | "View Page Source" | Hand-written, framework-agnostic HTML with no CMS generator tag |
| Wappalyzer / BuiltWith | Run on the live page / look up the domain | May report "Python" and sometimes "Bottle" if the server header is exposed |
A fast terminal check is curl -sI https://example.com | grep -i server to read the Server header, followed by requesting a missing path to inspect the error page. Because the back end is Python, the techniques in how to find out what programming language a website uses are directly relevant, and the general approach in how to find out what technology a website uses explains how to combine header and behavioral signals. The Server header and WSGI host are also closely tied to where the app runs, so how to find out where a website is hosted is a helpful companion when a reverse proxy is masking the framework.
A dose of realism helps here. In production, most Bottle apps sit behind a WSGI server and often a reverse proxy, both of which overwrite the Server header, so the framework's clearest fingerprint frequently disappears. Developers can also customize or disable the default error pages. As a result, definitively identifying Bottle from the outside is sometimes impossible, and the responsible conclusion is "a Python WSGI application, plausibly a micro-framework like Bottle or Flask." This is exactly why multi-signal, server-side analysis matters: by reading the raw headers, probing error responses, and ruling out the fingerprints of heavier frameworks, you can narrow the back end down with far more confidence than any single clue would allow, even when an exact name cannot be guaranteed. For a contrasting, easier-to-detect option on the same language, compare Bottle with Django, whose cookies and admin paths make it far more recognizable.
Key Features
- Single-file, zero-dependency core. The entire framework is one Python file that relies only on the standard library, making deployment and embedding trivial.
- Decorator-based routing. Clean
@route,@get, and@postdecorators with dynamic, typed URL segments for expressive URL handling. - Built-in development server. A WSGI dev server is included, with adapters for Gunicorn, uWSGI, Waitress, and other production servers.
- Simple templating. The built-in SimpleTemplate engine, plus optional adapters for Jinja2, Mako, and Cheetah.
- Convenient request/response helpers. Easy access to forms, query strings, cookies (including signed cookies), headers, file uploads, redirects, and static files.
- Automatic JSON. Returning a dictionary from a route produces a JSON response, which is handy for small APIs.
- Plugin system. Lightweight plugins wrap route callbacks to add database access, authentication, and other cross-cutting concerns without bloating the core.
Pros and Cons
Pros
- Extremely lightweight and fast to start with; no installation friction beyond a single file.
- No external dependencies, which simplifies deployment and is ideal for constrained or embedded environments.
- A gentle learning curve that makes it excellent for teaching, prototyping, and small tools.
- Permissively MIT-licensed and stable, with a small, well-understood surface area.
Cons
- Minimal by design, so it lacks built-in ORM, admin, authentication, and migrations that larger frameworks provide.
- Less suited to large, complex applications where a fuller framework's structure pays off.
- A smaller ecosystem and community than Flask or Django, meaning fewer ready-made extensions.
- The single-file approach, while elegant, can feel limiting once a project outgrows simple needs.
Bottle vs Alternatives
Bottle sits at the minimalist edge of Python web frameworks. The table below clarifies where it fits relative to common alternatives.
| Framework | Size/philosophy | Dependencies | Best for |
|---|---|---|---|
| Bottle | Micro, single file | None (stdlib only) | Tiny apps, prototypes, embedded/internal tools, learning |
| Flask | Micro, extensible | Werkzeug, Jinja2 | Small-to-medium apps wanting a larger ecosystem |
| FastAPI | Modern async API framework | Starlette, Pydantic | High-performance APIs with type hints and async |
| Django | Full-stack, batteries-included | Many built-in components | Large, database-driven applications and admin-heavy sites |
| Pyramid | Flexible, scales up or down | A handful | Apps that start small but may grow significantly |
If a site turns out to run a heavier stack, the same investigative techniques reveal it. Comparing Bottle with a full-stack option like Django is the clearest way to see the trade-off between minimalism and built-in features, and our guide on how to find out what programming language a website uses helps confirm the underlying language first.
Use Cases
Bottle is at its best for small, self-contained web services where simplicity and a tiny footprint matter more than a rich feature set. Developers reach for it to build quick prototypes and proofs of concept, since a working endpoint is only a few lines away and there is nothing to install. It is a popular choice for small internal tools and dashboards, the kind of utility a team runs on a single machine to expose a script or a status page over HTTP.
It also shines on embedded and resource-constrained systems. Because the whole framework is one dependency-free file, Bottle is well suited to single-board computers, IoT devices, and appliances where a lightweight HTTP interface is needed without dragging in a large dependency tree. Educators and self-learners use Bottle to teach the fundamentals of WSGI, routing, and request handling precisely because its small surface area is easy to read and understand in full. And developers building simple REST APIs or microservices appreciate that returning a dictionary yields JSON automatically, letting them stand up an endpoint quickly.
Consider a few concrete scenarios. A hardware hobbyist might run Bottle on a Raspberry Pi to serve sensor readings and accept control commands over a local network. A data engineer might wrap a Python analysis script in a handful of Bottle routes to expose it as an internal API for colleagues. An instructor might use Bottle in a course to demonstrate how HTTP requests map to functions, without the conceptual overhead of a full framework. In each case the common thread is a desire for the least possible ceremony between a Python function and an HTTP response.
From a technology-research perspective, identifying Bottle (or, more often, "a Python WSGI micro-framework") on a domain is a meaningful signal about the team behind it. It suggests a lean, Python-centric engineering approach, frequently an internal service, a developer tool, or a small specialized application rather than a large consumer site. For vendors and analysts profiling a stack, that context helps distinguish minimal, code-first projects from heavyweight platform-driven ones, and surfacing it automatically across many domains, rather than probing each one by hand, is exactly where automated detection earns its keep.
Frequently Asked Questions
Is Bottle still maintained and used in 2026?
Yes. Bottle remains an actively used, MIT-licensed open-source project with a long history and a stable, deliberately small codebase. It is not as widely adopted as Flask or as buzzed-about as FastAPI, but it retains a devoted user base for prototypes, embedded systems, teaching, and small services precisely because of its single-file, zero-dependency design. Its stability is part of the appeal: there is little churn in such a compact framework.
How can I tell if a website is running on Bottle?
It is harder than detecting a CMS, because Bottle adds almost nothing to the output. The most useful clue is the Server HTTP header, which on Bottle's built-in dev server reflects Python's WSGI reference server (e.g. WSGIServer ... Python/...). You can also trigger a 404 to inspect Bottle's distinctive default error page and rule out other frameworks by the absence of their cookies and headers. In production behind a WSGI server and proxy, the framework name is often masked, so the realistic conclusion is frequently "a Python WSGI app, plausibly Bottle."
What is the difference between Bottle and Flask?
Both are Python micro-frameworks with decorator-based routing, but Bottle is even more minimal: it is a single file with no external dependencies, bundling its own template engine and dev server. Flask is also lightweight but depends on the Werkzeug and Jinja2 libraries and has a substantially larger ecosystem of extensions and community resources. Bottle is ideal when you want absolute minimalism or a dependency-free deployment; Flask is often preferred when you expect to grow and want more ready-made tooling.
Is Bottle suitable for production?
It can be, for the right kind of application. For small services, internal tools, and embedded use, Bottle runs well in production behind a proper WSGI server such as Gunicorn, uWSGI, or Waitress, often with Nginx in front. What you should not do is rely on its built-in development server for production traffic. For large, complex, database-heavy applications, a fuller framework like Django typically pays off, but for focused, lightweight services Bottle is a perfectly reasonable production choice.
Does Bottle include a database or ORM?
No. Bottle is intentionally minimal and ships no ORM, no database layer, and no migrations. You are free to use any data library you like, the standard-library sqlite3 module, SQLAlchemy, or a NoSQL client, and Bottle's plugin system makes it easy to attach a database connection to your routes. This unopinionated approach keeps the core tiny but means you assemble the data layer yourself, in contrast to batteries-included frameworks that provide one out of the box.
Want to detect the framework, language, and hosting behind any site in seconds? Try StackOptic at https://stackoptic.com.
Alternatives to Bottle
Compare Bottle
Analyze a Website
Check if any website uses Bottle and discover its full technology stack.
Analyze Now