CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-lona

Write responsive web apps in full python

Pending
Overview
Eval results
Files

core-framework.mddocs/

Core Application Framework

Essential classes and patterns for building Lona web applications. The core framework provides the fundamental components needed to create interactive web applications entirely in Python, including application setup, view handling, request processing, and routing.

Capabilities

Application Class

The main application class that serves as the entry point for Lona web applications, managing routes, middleware, templates, static files, and server configuration.

class App:
    def __init__(self, script_path: str):
        """
        Initialize a Lona application.
        
        Args:
            script_path (str): Path to the main script file (__file__)
        """

    def route(self, raw_pattern: str | int, name: str = '', interactive: bool = True, 
              http_pass_through: bool = False, frontend_view=None):
        """
        Decorator for registering view routes.
        
        Args:
            raw_pattern (str | int): URL pattern to match or MATCH_ALL constant
            name (str): Optional route name for reverse URL generation
            interactive (bool): Whether the route supports interactivity
            http_pass_through (bool): Pass HTTP requests directly to view
            frontend_view: Optional frontend view function
            
        Returns:
            Decorator function
        """

    def middleware(self):
        """
        Decorator for registering middleware functions.
        
        Returns:
            Decorator function
        """

    def frontend_view(self):
        """
        Decorator for registering frontend views.
        
        Returns:
            Decorator function
        """

    def error_403_view(self):
        """
        Decorator for registering 403 error views.
        
        Returns:
            Decorator function
        """

    def error_404_view(self):
        """
        Decorator for registering 404 error views.
        
        Returns:
            Decorator function
        """

    def error_500_view(self):
        """
        Decorator for registering 500 error views.
        
        Returns:
            Decorator function
        """

    def add_template(self, name: str, string: str = '', path: str = ''):
        """
        Add a template to the application.
        
        Args:
            name (str): Template name
            string (str): Template content as string
            path (str): Path to template file
        """

    def add_static_file(self, name: str, string: str = '', path: str = ''):
        """
        Add a static file to the application.
        
        Args:
            name (str): Static file name
            string (str): File content as string  
            path (str): Path to static file
        """

    def add_route(self, route: 'Route'):
        """
        Programmatically add a route to the application.
        
        Args:
            route (Route): Route object to add
        """

    def run(self, host: str = 'localhost', port: int = 8080, 
            loop_class=None, **kwargs):
        """
        Run the application development server.
        
        Args:
            host (str): Server host address
            port (int): Server port number
            loop_class: Optional event loop class
            **kwargs: Additional server arguments
        """

    def setup_server(self, host: str = 'localhost', port: int = 8080):
        """
        Setup the server without running it.
        
        Args:
            host (str): Server host address
            port (int): Server port number
            
        Returns:
            Server instance
        """

Usage Example

from lona import App, View
from lona.html import HTML, H1

app = App(__file__)

@app.route('/')
class IndexView(View):
    def handle_request(self, request):
        return HTML(H1('Hello World'))

# Add middleware
@app.middleware()
def my_middleware(request):
    request.custom_data = 'processed'
    return request

# Add template
app.add_template('base', '''
<html>
<head><title>{{ title }}</title></head>
<body>{{ content }}</body>
</html>
''')

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

View Class

Base class for creating views that handle HTTP requests and user interactions. Views can be stateless (for simple HTTP responses) or stateful (for interactive applications with real-time user interaction).

class View:
    def handle_request(self, request: 'Request'):
        """
        Main request handler method - override this in subclasses.
        
        Args:
            request (Request): The HTTP request object
            
        Returns:
            Response object, HTML content, or None for interactive views
        """

    def show(self, html=None, template: str = None, title: str = None):
        """
        Display HTML content to the user and enter interactive mode.
        
        Args:
            html: HTML content to display
            template (str): Template name to render
            title (str): Page title
        """

    def set_title(self, title: str):
        """
        Set the page title.
        
        Args:
            title (str): New page title
        """

    def await_input_event(self, *nodes, html=None, timeout=None) -> 'InputEvent':
        """
        Wait for any input event on specified nodes.
        
        Args:
            *nodes: HTML nodes to monitor for events
            html: Optional HTML to show before waiting
            timeout: Optional timeout in seconds
            
        Returns:
            InputEvent object containing event details
        """

    def await_click(self, *nodes, html=None, timeout=None) -> 'InputEvent':
        """
        Wait for click events on specified nodes.
        
        Args:
            *nodes: HTML nodes to monitor for clicks
            html: Optional HTML to show before waiting
            timeout: Optional timeout in seconds
            
        Returns:
            InputEvent object containing click details
        """

    def await_change(self, *nodes, html=None, timeout=None) -> 'InputEvent':
        """
        Wait for change events on specified nodes.
        
        Args:
            *nodes: HTML nodes to monitor for changes
            html: Optional HTML to show before waiting
            timeout: Optional timeout in seconds
            
        Returns:
            InputEvent object containing change details
        """

    def await_focus(self, *nodes, html=None, timeout=None) -> 'InputEvent':
        """
        Wait for focus events on specified nodes.
        
        Args:
            *nodes: HTML nodes to monitor for focus
            html: Optional HTML to show before waiting
            timeout: Optional timeout in seconds
            
        Returns:
            InputEvent object containing focus details
        """

    def await_blur(self, *nodes, html=None, timeout=None) -> 'InputEvent':
        """
        Wait for blur events on specified nodes.
        
        Args:
            *nodes: HTML nodes to monitor for blur
            html: Optional HTML to show before waiting
            timeout: Optional timeout in seconds
            
        Returns:
            InputEvent object containing blur details
        """

    def send_str(self, string: str, broadcast: bool = False):
        """
        Send a string message to the frontend.
        
        Args:
            string (str): Message to send
            broadcast (bool): Whether to broadcast to all connected clients
        """

    def fire_view_event(self, name: str, data=None):
        """
        Fire a custom view event.
        
        Args:
            name (str): Event name
            data: Event data payload
        """

    def subscribe(self, topic: str, handler):
        """
        Subscribe to a channel topic.
        
        Args:
            topic (str): Channel topic name
            handler: Function to handle messages
        """

    def unsubscribe(self, topic: str = None):
        """
        Unsubscribe from channel topics.
        
        Args:
            topic (str): Specific topic to unsubscribe from, or None for all
        """

    def sleep(self, delay: float):
        """
        Async sleep for the specified delay.
        
        Args:
            delay (float): Sleep duration in seconds
        """

    def is_daemon_view(self) -> bool:
        """
        Check if this view runs as a daemon.
        
        Returns:
            bool: True if view is a daemon
        """

    def is_interactive(self) -> bool:
        """
        Check if this view supports interactivity.
        
        Returns:
            bool: True if view is interactive
        """

    # Properties
    request: 'Request'  # Current request object
    server: object      # Server instance
    logger: object      # Logger instance

Usage Example

from lona import App, View
from lona.html import HTML, H1, Button, P
from lona.responses import JsonResponse

app = App(__file__)

# Simple HTTP view
@app.route('/api/status')
class StatusView(View):
    def handle_request(self, request):
        return JsonResponse({'status': 'ok'})

# Interactive view
@app.route('/counter')
class CounterView(View):
    def handle_request(self, request):
        count = 0
        button = Button('Increment')
        counter_text = P(f'Count: {count}')
        
        html = HTML(
            H1('Interactive Counter'),
            counter_text,
            button
        )
        
        self.show(html)
        
        while True:
            self.await_click(button)
            count += 1
            counter_text.set_text(f'Count: {count}')

Request Class

Represents an HTTP request with additional Lona-specific functionality for handling interactive applications, user sessions, and routing information.

class Request:
    # Request data
    GET: dict           # GET parameters
    POST: dict          # POST parameters  
    method: str         # HTTP method (GET, POST, etc.)
    url: str           # Request URL
    
    # User and session
    user: object        # User object (if authentication middleware used)
    
    # Routing information
    route: 'Route'      # Matched route object
    match_info: dict    # URL pattern match information
    
    # Lona-specific
    interactive: bool   # Whether request supports interactivity
    connection: object  # Connection object for interactive features
    view: 'View'       # Associated view instance (set during processing)
    
    # Headers and metadata
    headers: dict       # Request headers
    content_type: str   # Content type header
    content_length: int # Content length
    
    # Session data (if session middleware enabled)
    session: dict       # Session data dictionary

Usage Example

@app.route('/user/<int:user_id>')
class UserProfileView(View):
    def handle_request(self, request):
        # Access URL parameters
        user_id = request.match_info['user_id']
        
        # Access GET/POST data
        search_query = request.GET.get('q', '')
        
        # Check request method
        if request.method == 'POST':
            # Handle form submission
            name = request.POST.get('name', '')
            
        # Access user (if authenticated)
        if request.user:
            username = request.user.username
            
        # Check if interactive
        if request.interactive:
            # Can use interactive features
            self.show(HTML(H1(f'User {user_id}')))
        else:
            # Return static response
            return HtmlResponse(f'<h1>User {user_id}</h1>')

Route Class

Defines URL routing patterns and associates them with view classes or functions, supporting both interactive and non-interactive routes with optional HTTP pass-through.

class Route:
    def __init__(self, raw_pattern: str, view, name: str = '', 
                 interactive: bool = True, http_pass_through: bool = False, 
                 frontend_view=None):
        """
        Create a new route definition.
        
        Args:
            raw_pattern (str): URL pattern (supports placeholders like <int:id>)
            view: View class or function to handle requests
            name (str): Optional route name for reverse URL generation
            interactive (bool): Whether route supports interactive features
            http_pass_through (bool): Pass HTTP requests directly to view
            frontend_view: Optional frontend view function
        """

    # Properties
    raw_pattern: str    # Original URL pattern string
    view: object        # View class or function
    name: str          # Route name for reverse lookups
    interactive: bool   # Interactive support flag
    http_pass_through: bool  # HTTP pass-through flag
    frontend_view: object    # Frontend view function

Usage Example

from lona import App, Route, View
from lona.html import HTML, H1

app = App(__file__)

# Using decorator (recommended)
@app.route('/users/<int:user_id>', name='user_profile', interactive=True)
class UserView(View):
    def handle_request(self, request):
        user_id = request.match_info['user_id']
        return HTML(H1(f'User {user_id}'))

# Programmatic route creation
class ApiView(View):
    def handle_request(self, request):
        return JsonResponse({'api': 'v1'})

api_route = Route('/api/v1', ApiView, name='api', interactive=False)
app.add_route(api_route)

# Route matching constant
from lona import MATCH_ALL

@app.route(MATCH_ALL, name='catch_all')  # Matches any URL
class CatchAllView(View):
    def handle_request(self, request):
        return HTML(H1('Page not found'))

Types

from typing import Union, Optional, Dict, List, Callable, Any, Type

# Core framework types
ViewClass = Type['View']
ViewFunction = Callable[['Request'], Any]
ViewHandler = Union[ViewClass, ViewFunction]
MiddlewareHandler = Callable[['Request'], 'Request']
RoutePattern = Union[str, int]  # int for MATCH_ALL constant
Settings = Union[object, Dict[str, Any]]

Install with Tessl CLI

npx tessl i tessl/pypi-lona

docs

channel-communication.md

core-framework.md

events-interactivity.md

exception-handling.md

file-management.md

html-system.md

index.md

response-system.md

routing-urls.md

static-files-assets.md

tile.json