Brython Documentation

repository·master·Indexed 27 days ago

https://github.com/brython-dev/brython

Brython (Browser Python) is an implementation of Python 3 that runs in the browser, providing a direct interface to DOM elements and events. It allows developers to write web applications using Python instead of JavaScript. The library includes a browser-compatible asynchronous module (browser.aio) for Ajax requests and provides tools for DOM manipulation, such as the document object for element access and specialized operators for tree structure management.

Tokens
35K
Snippets
81
Records
217
Agent score
91%

What's inside Brython

  1. Understand Brython's Python-to-JavaScript Translation

    master

    Brython translates Python syntax into JavaScript code to run Python in the browser. This translation involves mapping Python constructs to specific JavaScript patterns, such as using getattr and setattr for attribute access, and managing namespaces via __BRYTHON__.vars.

    Key translation behaviors include:

    • Variable Assignment: Python variables are mapped to a $globals or $locals object to maintain scope.
    • Attribute Access: foo.bar becomes getattr(foo, "bar"), and foo.bar = x becomes setattr(foo, "bar", x).
    • Item Access: foo[bar] is translated using __getitem__ and __setitem__ methods.
    • Operators: Arithmetic and logical operators are often implemented via getattr(x, "__add__")(y) to support Python's operator overloading.
    • Function Calls: Python function calls use the __call__ method, and keyword arguments are wrapped using the $Kw function.
  2. Understand the Brython compilation and execution process

    master

    Brython converts Python source code into JavaScript through a multi-step process involving parsing, tree transformation, and code generation.

    Compilation Steps

    1. Reading Python source: The brython(_debug_mode_) function in __py2js.js__ reads the source (via Ajax if external). It initializes the __BRYTHON__ environment object.
    2. Tree Creation: The __BRYTHON__.py2js(_source, module_) function performs syntax analysis using $tokenize(), builds a tree, and applies transform() to prepare for JavaScript conversion. If debug > 0, $add_line_num() is called.
    3. Generating JavaScript: The to_js() method of the generated tree recursively converts syntax elements into a JavaScript string. If debug mode is set to 2, this string is printed to the browser console.
    4. Execution: The resulting JavaScript is executed using the browser's eval() function.
  3. Understand the email package architecture

    master

    The email package is organized into four primary components that work together to manage email messages:

    1. Model: Represented by the email.message.Message class. It provides an API to create, query, and modify messages. It treats the message as two parts: a header section (accessed via a pseudo-dictionary interface) and a payload (the body).
    2. Parser: Converts sequences of characters or bytes into a Message model.
    3. Generator: Converts a Message model back into a sequence of characters or bytes (either printable Unicode or bytes suitable for transmission).
    4. Policy: An object that controls behavioral settings, such as how headers are parsed, fetched, stored, or folded during the message lifecycle.
  4. Quickstart: Use Brython in an HTML page

    master

    To use Brython, you need to perform three steps:

    1. Load the brython.js script in your <head>.
    2. Execute the brython() function on page load using <body onload="brython()">.
    3. Write your Python code inside <script type="text/python"> tags.

    Brython provides an interface to DOM elements and events, allowing you to interact with the browser using Python 3 syntax.

    <html>
        <head>
            <script type="text/javascript" src="/path/to/brython.js"></script>
        </head>
    
        <body onload="brython()">
    
            <script type="text/python">
            from browser import document, alert
    
            def echo(event):
                alert(document["zone"].value)
    
            document["mybutton"].bind("click", echo)
            </script>
    
            <input id="zone"><button id="mybutton">click !</button>
    
        </body>
    </html>
  5. Use the browser.html module to create HTML elements

    master

    The browser.html module allows you to create and manipulate HTML elements using Python classes. Each class corresponds to an HTML tag (e.g., html.DIV, html.A, html.TABLE).

    Basic Syntax

    To create an element, use the tag class name. You can pass content and attributes directly to the constructor:

    Tag(content, **attributes)

    • Content: Can be a string, a number, or another HTML object. If it is a string, it is interpreted as HTML code. To set plain text, use the .text property instead.
    • Attributes: Passed as keyword arguments. Because hyphens (-) are not valid in Python identifiers, replace them with underscores (_). For example, http-equiv becomes http_equiv.
    • Complex Attributes: For attributes containing colons (like Vue.js directives), use a dictionary: html.BUTTON("hello", **{"v-on:click": "count++"}).
    • Iterables: If content is an iterable (like a generator), all items become child nodes.

    Managing Children and Attributes

    • Add children: Use the += or <= operator.
    • Add attributes: Use object.attrs[key] = value or direct assignment for standard DOM properties.
    • Combine elements: Use the + operator to group elements at the same level.
    • Cloning: Since an HTML instance represents a single DOM object, you cannot use the same instance in multiple places. Use .clone() to reuse an element.
  6. Load external Python files in Brython

    master

    For larger programs, you can load Python code from an external file using the src attribute on the <script> tag.

    Important Considerations:

    1. Same-Origin Policy: The Python script is loaded via an Ajax call, so it must reside on the same domain as the HTML page.
    2. File Extensions: If your server attempts to execute .py files as server-side scripts (e.g., via CGI), change the file extension to something else, such as .bry, to ensure it is treated as a static asset for Brython to fetch.
    <head>
    <script src="/src/brython.js"></script>
    <script src="/src/brython_stdlib.js"></script>
    </head>
    
    <body>
    <script type="text/python" src="test.bry"></script>
    </body>
  7. Set up a Brython environment

    master

    To run Python in the browser, create an HTML file and include the Brython engine (brython.min.js) and the standard library (brython_stdlib.js) via a CDN. You can then embed Python code within <script type="text/python"> tags.

    To view your work, you can either use the browser's File/Open menu or launch a local web server using Python's built-in module:

    python -m http.server

    Then navigate to localhost:8000/index.html.

    <!doctype html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <script type="text/javascript"
            src="https://cdn.jsdelivr.net/npm/brython@{implementation}/brython.min.js">
        </script>
        <script type="text/javascript"
            src="https://cdn.jsdelivr.net/npm/brython@{implementation}/brython_stdlib.js">
        </script>
    </head>
    
    <body>
    
    <script type="text/python">
    from browser import document
    
    document <= "Hello !"
    </script>
    
    </body>
    
    </html>
  8. Access the DOM using the browser module

    master

    Brython provides a language-independent interface to the browser's Document Object Model (DOM) through the browser module. All standard DOM operations are performed using two primary objects: document and window.

    • document: Implements the standard Document interface.
    • window: Provides access to the browser window object.
  9. Read file content with Ajax and timeouts

    master

    For more control, such as handling errors or implementing timeouts, use the browser.ajax.Ajax object. This allows you to bind to the complete event to process the response and set a timeout function that executes if the server does not respond within a specified duration.

    import time
    from browser import ajax, document 
    
    def on_complete(req):
        if req.status == 200 or req.status == 0:
            document["zone"].value = req.text
        else:
            document["zone"].value = "error " + req.text
    
    def err_msg():
        document["zone"].text = "server didn't reply after %s seconds" % timeout
    
    timeout = 4
    
    def go(url):
        req = ajax.Ajax()
        req.bind("complete", on_complete)
        req.set_timeout(timeout, err_msg)
        req.open('GET', url, True)
        req.send()
    
    go('file.txt?foo=%s' % time.time())
  10. Store and retrieve JSON objects in Local Storage

    master

    Since browser.local_storage only stores string values, you must use the json module to serialize Python objects (like dictionaries) before storing them, and deserialize them when retrieving them.

    Note: The json module converts all dictionary keys to strings. When retrieving data, you must access keys using their string representation (e.g., b['1515'] instead of b[1515]).

    from browser.local_storage import storage
    import json
    
    a = {'foo': 1, 1515: 'Marignan'}
    
    # Serialize and store
    storage["brython_test"] = json.dumps(a)
    
    # Retrieve and deserialize
    b = json.loads(storage['brython_test'])
    
    # Accessing keys (keys are converted to strings by JSON)
    alert(b['foo'])
    alert(b['1515'])