CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-bottle

Fast and simple WSGI micro web-framework for small web applications with no dependencies other than the Python Standard Library.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

static-utilities.mddocs/

Static Files and Utilities

Static file serving, HTTP utilities, and helper functions for common web development tasks including file serving, security utilities, and HTTP helper functions.

Capabilities

Static File Serving

Serve static files with proper MIME types, caching headers, and security features.

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 for text files
    
    Returns:
    HTTPResponse: file response with proper headers
    
    Raises:
    HTTPError: 404 if file not found, 403 if access denied
    """

Usage:

@route('/static/<filepath:path>')
def serve_static(filepath):
    return static_file(filepath, root='./static/')

@route('/downloads/<filename>')
def download_file(filename):
    return static_file(filename, root='./downloads/', download=True)

@route('/css/<filename>')
def serve_css(filename):
    return static_file(filename, root='./assets/css/', 
                      mimetype='text/css')

@route('/images/<filename>')
def serve_image(filename):
    return static_file(filename, root='./assets/images/',
                      mimetype='auto')

HTTP Response Utilities

Utility functions for common HTTP response patterns.

def abort(code=500, text='Unknown Error.'):
    """
    Raise HTTPError with specified status code and message.
    
    Parameters:
    - code: int, HTTP status code (400, 404, 500, etc.)
    - text: str, error message
    
    Raises:
    HTTPError: HTTP error response
    """

def redirect(url, code=None):
    """
    Raise HTTPResponse that redirects to the specified URL.
    
    Parameters:
    - url: str, redirect URL (absolute or relative)
    - code: int, HTTP redirect status code (302 default, 301 for permanent)
    
    Raises:
    HTTPResponse: redirect response
    """

Usage:

@route('/admin')
def admin_panel():
    if not user_is_admin():
        abort(403, 'Access denied - admin privileges required')
    return render_admin_panel()

@route('/old-url')
def old_url():
    redirect('/new-url', code=301)  # Permanent redirect

@route('/login-check')
def login_check():
    if not logged_in():
        redirect('/login?return_to=/dashboard')
    return dashboard()

@route('/api/not-found')
def api_not_found():
    abort(404, 'API endpoint not found')

Debug Mode

Enable debug mode for development.

def debug(mode=True):
    """
    Enable or disable debug mode.
    
    Parameters:
    - mode: bool, True to enable debug mode, False to disable
    """

Usage:

import bottle

# Enable debug mode
bottle.debug(True)

# Debug mode effects:
# - Detailed error pages with tracebacks
# - Auto-reload on file changes (with reloader=True)
# - Exception propagation for debugging tools

Date and Time Utilities

HTTP date formatting and parsing functions.

def http_date(value):
    """
    Format date/time for HTTP headers (RFC 2822 format).
    
    Parameters:
    - value: datetime, time tuple, or timestamp
    
    Returns:
    str: HTTP-formatted date string
    """

def parse_date(ims):
    """
    Parse HTTP date string to timestamp.
    
    Parameters:
    - ims: str, HTTP date string
    
    Returns:
    float: timestamp or None if parsing fails
    """

Usage:

from datetime import datetime
import bottle

@route('/api/timestamp')
def api_timestamp():
    now = datetime.now()
    bottle.response.set_header('Date', bottle.http_date(now))
    
    # Handle If-Modified-Since header
    ims = bottle.request.get_header('If-Modified-Since')
    if ims:
        ims_timestamp = bottle.parse_date(ims)
        if ims_timestamp and ims_timestamp >= now.timestamp():
            bottle.abort(304)  # Not Modified
    
    return {'timestamp': now.isoformat()}

Authentication Utilities

HTTP authentication parsing and basic auth decorator.

def parse_auth(header):
    """
    Parse HTTP Authorization header.
    
    Parameters:
    - header: str, Authorization header value
    
    Returns:
    tuple: (method, credentials) or None if invalid
    """

def auth_basic(check, realm="private", text="Access denied"):
    """
    HTTP Basic Authentication decorator.
    
    Parameters:
    - check: function, authentication check function (username, password) -> bool
    - realm: str, authentication realm
    - text: str, access denied message
    
    Returns:
    function: authentication decorator
    """

Usage:

def check_credentials(username, password):
    return username == 'admin' and password == 'secret'

@route('/admin')
@auth_basic(check_credentials, realm='Admin Area')
def admin():
    return 'Welcome to admin area!'

@route('/api/auth-info')
def auth_info():
    auth_header = request.get_header('Authorization')
    if auth_header:
        method, credentials = parse_auth(auth_header) or (None, None)
        return {'method': method, 'has_credentials': bool(credentials)}
    return {'authenticated': False}

Range Request Utilities

Support for HTTP range requests and partial content.

def parse_range_header(header, maxlen=0):
    """
    Parse HTTP Range header for partial content requests.
    
    Parameters:
    - header: str, Range header value
    - maxlen: int, maximum content length
    
    Returns:
    list: list of (start, end) tuples or empty list if invalid
    """

Usage:

@route('/video/<filename>')
def serve_video(filename):
    file_path = f'./videos/{filename}'
    if not os.path.exists(file_path):
        abort(404)
    
    range_header = request.get_header('Range')
    if range_header:
        ranges = parse_range_header(range_header, os.path.getsize(file_path))
        if ranges:
            # Handle range request
            start, end = ranges[0]
            response.status = 206  # Partial Content
            response.set_header('Content-Range', f'bytes {start}-{end}/{os.path.getsize(file_path)}')
    
    return static_file(filename, root='./videos/')

Security Utilities

Security-related helper functions for cookies and HTML.

def cookie_encode(data, key, digestmod=None):
    """
    Encode and sign cookie data.
    
    Parameters:
    - data: dict, cookie data to encode
    - key: str or bytes, signing key
    - digestmod: hashlib digest module (default: sha256)
    
    Returns:
    str: encoded and signed cookie value
    """

def cookie_decode(data, key, digestmod=None):
    """
    Decode and verify signed cookie data.
    
    Parameters:
    - data: str, encoded cookie value
    - key: str or bytes, signing key
    - digestmod: hashlib digest module (default: sha256)
    
    Returns:
    dict: decoded cookie data or None if invalid
    """

def cookie_is_encoded(data):
    """
    Check if cookie data is encoded/signed.
    
    Parameters:
    - data: str, cookie value
    
    Returns:
    bool: True if cookie appears to be encoded
    """

def html_escape(string):
    """
    Escape HTML entities in string.
    
    Parameters:
    - string: str, string to escape
    
    Returns:
    str: HTML-escaped string
    """

def html_quote(string):
    """
    Quote string for use in HTML attributes.
    
    Parameters:
    - string: str, string to quote
    
    Returns:
    str: quoted string safe for HTML attributes
    """

Usage:

# Secure cookie handling
@route('/set-secure-cookie')
def set_secure_cookie():
    data = {'user_id': 123, 'role': 'user'}
    cookie_value = cookie_encode(data, 'secret-key')
    response.set_cookie('secure_data', cookie_value)
    return 'Secure cookie set'

@route('/get-secure-cookie')
def get_secure_cookie():
    cookie_value = request.get_cookie('secure_data')
    if cookie_value and cookie_is_encoded(cookie_value):
        data = cookie_decode(cookie_value, 'secret-key')
        if data:
            return f'User ID: {data["user_id"]}, Role: {data["role"]}'
    return 'No valid secure cookie found'

# HTML escaping
@route('/safe-output/<user_input>')
def safe_output(user_input):
    safe_input = html_escape(user_input)
    return f'<p>You entered: {safe_input}</p>'

@route('/safe-attribute/<value>')
def safe_attribute(value):
    safe_value = html_quote(value)
    return f'<input type="text" value="{safe_value}">'

Path and Route Utilities

Utilities for path manipulation and route discovery.

def yieldroutes(func):
    """
    Extract routes from a function that contains route definitions.
    
    Parameters:
    - func: function, function containing route decorators
    
    Yields:
    Route: route instances defined in the function
    """

def path_shift(script_name, path_info, shift=1):
    """
    Shift path components between SCRIPT_NAME and PATH_INFO.
    
    Parameters:
    - script_name: str, current SCRIPT_NAME
    - path_info: str, current PATH_INFO  
    - shift: int, number of path components to shift
    
    Returns:
    tuple: (new_script_name, new_path_info)
    """

Data Conversion Utilities

Helper functions for data type conversion and validation.

def makelist(data):
    """
    Convert data to list format.
    
    Parameters:
    - data: any, data to convert to list
    
    Returns:
    list: data as list (wraps single items, preserves existing lists)
    """

def tob(s, enc='utf8'):
    """
    Convert string to bytes.
    
    Parameters:
    - s: str, string to convert
    - enc: str, encoding to use
    
    Returns:
    bytes: encoded bytes
    """

def touni(s, enc='utf8', err='strict'):
    """
    Convert to unicode string.
    
    Parameters:
    - s: str or bytes, data to convert
    - enc: str, encoding to use for bytes
    - err: str, error handling strategy
    
    Returns:
    str: unicode string
    """

Usage:

# Data conversion
@route('/api/data')
def api_data():
    # Ensure list format
    tags = makelist(request.query.get('tags', []))
    
    # Handle bytes/string conversion
    raw_data = request.body
    text_data = touni(raw_data, enc='utf8')
    
    return {
        'tags': tags,
        'data_length': len(text_data),
        'encoding': 'utf8'
    }

Install with Tessl CLI

npx tessl i tessl/pypi-bottle

docs

application-routing.md

index.md

plugin-system.md

request-handling.md

response-management.md

server-management.md

static-utilities.md

template-rendering.md

tile.json