Fast and simple WSGI micro web-framework for small web applications with no dependencies other than the Python Standard Library.
npx @tessl/cli install tessl/pypi-bottle@0.13.0A fast, simple and lightweight WSGI micro web-framework for Python distributed as a single file module with no dependencies other than the Python Standard Library. Bottle provides comprehensive web application functionality including request dispatching with URL parameter support, a built-in template engine, convenient utilities for handling form data, file uploads, cookies, and HTTP metadata, and a built-in HTTP development server.
pip install bottleimport bottleCommon usage patterns:
from bottle import Bottle, route, run, request, responseApplication shortcut functions:
from bottle import route, get, post, put, delete, patchfrom bottle import route, run, template
@route('/hello/<name>')
def index(name):
return template('<b>Hello {{name}}</b>!', name=name)
run(host='localhost', port=8080)Object-oriented approach:
from bottle import Bottle
app = Bottle()
@app.route('/hello')
def hello():
return "Hello World!"
if __name__ == '__main__':
app.run(host='localhost', port=8080)Bottle follows a minimalist design philosophy with several key components:
This design enables rapid development of small to medium web applications while maintaining the flexibility to scale and integrate with the broader Python web ecosystem.
Core application management and URL routing functionality including the main Bottle class, route decorators, and URL parameter handling.
class Bottle:
def __init__(self, **kwargs): ...
def route(self, path=None, method='GET', callback=None, **options): ...
def get(self, path=None, method='GET', **options): ...
def post(self, path=None, method='POST', **options): ...
def put(self, path=None, method='PUT', **options): ...
def delete(self, path=None, method='DELETE', **options): ...
def patch(self, path=None, method='PATCH', **options): ...
def run(self, **kwargs): ...
# Module-level shortcuts for default app
def route(path=None, method='GET', callback=None, **options): ...
def get(path=None, callback=None, **options): ...
def post(path=None, callback=None, **options): ...
def put(path=None, callback=None, **options): ...
def delete(path=None, callback=None, **options): ...
def patch(path=None, callback=None, **options): ...Request object providing access to HTTP request data including headers, query parameters, form data, file uploads, cookies, and JSON data.
class BaseRequest:
@property
def method(self) -> str: ...
@property
def path(self) -> str: ...
@property
def query(self) -> FormsDict: ...
@property
def forms(self) -> FormsDict: ...
@property
def files(self) -> FormsDict: ...
@property
def json(self) -> Any: ...
@property
def headers(self) -> HeaderDict: ...
@property
def cookies(self) -> SimpleCookie: ...
def get_header(self, name, default=None): ...
def get_cookie(self, key, default=None, secret=None): ...
# Global request instance
request: LocalRequestResponse object for setting HTTP response properties including status codes, headers, cookies, and content type.
class BaseResponse:
@property
def status(self) -> int: ...
@property
def headers(self) -> HeaderDict: ...
@property
def content_type(self) -> str: ...
def set_header(self, name, value): ...
def add_header(self, name, value): ...
def get_header(self, name, default=None): ...
def set_cookie(self, key, value, **options): ...
def delete_cookie(self, key, **kwargs): ...
# Global response instance
response: LocalResponseBuilt-in template engine with support for external template systems and template rendering functions.
def template(name, **kwargs):
"""
Render a template with keyword arguments.
Parameters:
- name: str, template name or template string
- **kwargs: template variables
Returns:
str: rendered template
"""
def view(tpl_name, **defaults):
"""
Decorator that renders a template with the return value of the wrapped function.
Parameters:
- tpl_name: str, template name
- **defaults: default template variables
Returns:
function: decorator function
"""
class SimpleTemplate:
def __init__(self, source, **options): ...
def render(self, **kwargs): ...Static file serving, HTTP utilities, and helper functions for common web development tasks.
def static_file(filename, root, mimetype='auto', download=False, charset='UTF-8'):
"""
Serve static files with proper MIME types and caching headers.
Parameters:
- filename: str, file name to serve
- root: str, root directory path
- mimetype: str, MIME type ('auto' for automatic detection)
- download: bool, force download with Content-Disposition header
- charset: str, character encoding
Returns:
HTTPResponse: file response
"""
def abort(code=500, text='Unknown Error.'):
"""Raise an HTTPError with specified status code and message."""
def redirect(url, code=None):
"""Raise an HTTPResponse that redirects to the specified URL."""Development server and production server adapter support for various WSGI servers.
def run(app=None, server='wsgiref', host='127.0.0.1', port=8080, debug=False, reloader=False, **kwargs):
"""
Start a development server.
Parameters:
- app: Bottle or WSGI application
- server: str, server adapter name
- host: str, server host
- port: int, server port
- debug: bool, enable debug mode
- reloader: bool, enable auto-reload
- **kwargs: additional server options
"""
class ServerAdapter:
def __init__(self, host='127.0.0.1', port=8080, **options): ...
def run(self, handler): ...Plugin architecture for extending Bottle functionality with custom middleware and request/response processing.
class Bottle:
def install(self, plugin): ...
def uninstall(self, plugin): ...
def hook(self, name): ...
# Module-level shortcuts
def install(plugin): ...
def uninstall(plugin): ...
def hook(name): ...class FormsDict(MultiDict):
"""Dictionary for form data with multiple values per key and unicode handling."""
def get(self, key, default=None, index=-1, type=None): ...
def getall(self, key): ...
def getunicode(self, name, default=None, encoding=None): ...
class MultiDict:
"""Dictionary allowing multiple values per key."""
def get(self, key, default=None, index=-1, type=None): ...
def getall(self, key): ...
def append(self, key, value): ...
class HeaderDict(MultiDict):
"""Case-insensitive dictionary for HTTP headers."""
class ConfigDict(dict):
"""Configuration dictionary with validation and change listeners."""
def load_config(self, filename): ...
def load_dict(self, source, namespace=''): ...
def load_module(self, path, namespace='', squash=True): ...
def meta_get(self, key, metafield, default=None): ...
def meta_set(self, key, metafield, value): ...
class FileUpload:
"""File upload wrapper with save functionality."""
@property
def name(self) -> str: ...
@property
def filename(self) -> str: ...
@property
def file(self): ...
@property
def headers(self) -> HeaderDict: ...
def save(self, destination, overwrite=False, chunk_size=65536): ...
class HTTPResponse(Exception):
"""HTTP response that can be raised as an exception."""
def __init__(self, body='', status=None, headers=None, **more_headers): ...
class HTTPError(HTTPResponse):
"""HTTP error response exception."""
class Route:
"""Individual route mapping with callback and configuration."""
def __init__(self, app, rule, method, callback, **options): ...
def get_undecorated_callback(self): ...
def get_callback_args(self): ...
class WSGIHeaderDict(dict):
"""Dict-like wrapper for WSGI environ HTTP headers."""
class ResourceManager:
"""Manages search paths for application files and resources."""
def add_path(self, path): ...
def lookup(self, name): ...
def open(self, name, mode='r'): ...class BottleException(Exception):
"""Base class for all Bottle-specific exceptions."""
class RouteError(BottleException):
"""Base class for all routing related exceptions."""
class RouteReset(RouteError):
"""Forces route reset and plugin re-application when raised."""
class RouteSyntaxError(RouteError):
"""Raised when route parser encounters unsupported syntax."""
class RouteBuildError(RouteError):
"""Raised when route URL cannot be built."""
class PluginError(BottleException):
"""Raised for plugin-related errors."""
class MultipartError(ValueError):
"""Raised for multipart form data parsing errors."""
class TemplateError(BottleException):
"""Base class for template-related errors."""__version__: str
"""Framework version string."""
DEBUG: bool
"""Global debug flag."""
TEMPLATE_PATH: list
"""Default template lookup paths."""
HTTP_CODES: dict
"""HTTP status code to message mappings."""
# Global objects
request: LocalRequest
"""Thread-local request object available in route handlers."""
response: LocalResponse
"""Thread-local response object available in route handlers."""
local: threading.local
"""Thread-local namespace for custom data."""
app: AppStack
"""Default application stack."""
ext: object
"""Virtual package namespace for extensions."""