Skip to main content
LiveCodes supports Python execution in the browser using Brython (lightweight) and Pyodide (full CPython with scientific libraries).

Configuration

Language Name: python (Brython) or python-wasm (Pyodide)
File Extensions: .py
Editor: Script editor
Compiler: Brython (transpiler) or Pyodide (WebAssembly)
Script Type: text/python

Python with Brython

Brython is a Python-to-JavaScript transpiler that runs Python code in the browser:
import math

# Basic Python syntax
name = "World"
print(f"Hello, {name}!")

# Functions
def greet(name, greeting="Hello"):
    return f"{greeting}, {name}!"

print(greet("Alice"))
print(greet("Bob", "Hi"))

# List comprehensions
numbers = [1, 2, 3, 4, 5]
squared = [n ** 2 for n in numbers]
print(f"Squared: {squared}")

# Dictionary
user = {
    "name": "John Doe",
    "age": 30,
    "email": "[email protected]"
}
print(user["name"])

# Classes
class Counter:
    def __init__(self, initial=0):
        self.count = initial
    
    def increment(self):
        self.count += 1
    
    def get_value(self):
        return self.count

counter = Counter(10)
counter.increment()
print(f"Count: {counter.get_value()}")

DOM Manipulation

Access the browser DOM directly:
from browser import document, html, alert

# Create elements
div = html.DIV("Hello from Python!")
div.attrs["class"] = "container"

button = html.BUTTON("Click me")

def handle_click(event):
    alert("Button clicked!")
    event.target.textContent = "Clicked!"

button.bind("click", handle_click)

# Add to document
document.body <= div
document.body <= button

# Query selectors
element = document.querySelector("#app")
if element:
    element.textContent = "Updated from Python"

Event Handling

from browser import document, html

count = 0

def create_counter():
    global count
    
    display = html.DIV(f"Count: {count}")
    display.id = "display"
    
    def increment(event):
        global count
        count += 1
        document["display"].textContent = f"Count: {count}"
    
    def decrement(event):
        global count
        count -= 1
        document["display"].textContent = f"Count: {count}"
    
    inc_btn = html.BUTTON("Increment")
    inc_btn.bind("click", increment)
    
    dec_btn = html.BUTTON("Decrement")
    dec_btn.bind("click", decrement)
    
    document.body <= display
    document.body <= inc_btn
    document.body <= dec_btn

create_counter()

Standard Library

Brython includes many Python standard library modules:
import random
import datetime
import json
import math

# Random numbers
print(random.randint(1, 100))
print(random.choice(["apple", "banana", "cherry"]))

# Datetime
now = datetime.datetime.now()
print(f"Current time: {now}")

# JSON
data = {"name": "Alice", "age": 25}
json_str = json.dumps(data)
print(json_str)

parsed = json.loads(json_str)
print(parsed["name"])

# Math
print(math.sqrt(16))
print(math.pi)

Imports

Import from standard library:
from datetime import datetime, timedelta
from collections import defaultdict, Counter
from itertools import chain, combinations
from functools import reduce

# defaultdict
word_count = defaultdict(int)
words = ["apple", "banana", "apple", "cherry"]
for word in words:
    word_count[word] += 1

print(dict(word_count))

# Counter
counts = Counter(words)
print(counts.most_common(2))

# reduce
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda a, b: a + b, numbers)
print(f"Sum: {total}")

Python with Pyodide (WASM)

For full CPython support with scientific libraries, use python-wasm:
import numpy as np
import pandas as pd

# NumPy arrays
arr = np.array([1, 2, 3, 4, 5])
print(f"Mean: {arr.mean()}")
print(f"Std: {arr.std()}")

# Matrix operations
matrix = np.array([[1, 2], [3, 4]])
print(f"Determinant: {np.linalg.det(matrix)}")

# Pandas DataFrames
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [25, 30, 35],
    'city': ['New York', 'London', 'Paris']
})

print(df)
print(df.describe())
Pyodide loads the full CPython runtime (~10MB), which may take a moment to initialize.

Configuration Options

Configure Python settings:
{
  "customSettings": {
    "python": {
      "autoloadStdlib": true,
      "requireMap": {
        "custom_module": "https://cdn.example.com/module.js"
      }
    }
  }
}

Auto-load Standard Library

By default, Brython auto-loads the standard library when imports are detected:
{
  "customSettings": {
    "python": {
      "autoloadStdlib": true
    }
  }
}
Set to false to disable auto-loading for faster startup.

Example Projects

Interactive Form

from browser import document, html

def create_form():
    form_html = html.DIV()
    
    # Name input
    name_label = html.LABEL("Name: ")
    name_input = html.INPUT(type="text", id="name")
    
    # Email input
    email_label = html.LABEL("Email: ")
    email_input = html.INPUT(type="email", id="email")
    
    # Submit button
    submit = html.BUTTON("Submit")
    
    # Result div
    result = html.DIV(id="result")
    
    def handle_submit(event):
        name = document["name"].value
        email = document["email"].value
        
        document["result"].textContent = f"Welcome, {name}! ({email})"
    
    submit.bind("click", handle_submit)
    
    form_html <= name_label
    form_html <= name_input
    form_html <= html.BR()
    form_html <= email_label
    form_html <= email_input
    form_html <= html.BR()
    form_html <= submit
    form_html <= result
    
    document.body <= form_html

create_form()

Fetch API

from browser import document, html, aio
import json

async def fetch_users():
    # Show loading
    loading = html.DIV("Loading...")
    document.body <= loading
    
    try:
        # Fetch data
        response = await aio.get("https://jsonplaceholder.typicode.com/users")
        users = json.loads(response.data)
        
        # Remove loading
        loading.remove()
        
        # Display users
        user_list = html.UL()
        for user in users:
            item = html.LI(f"{user['name']} - {user['email']}")
            user_list <= item
        
        document.body <= user_list
    
    except Exception as e:
        loading.textContent = f"Error: {e}"

# Run async function
aio.run(fetch_users())

Canvas Drawing

from browser import document, html
import math

canvas = html.CANVAS(width=400, height=400)
document.body <= canvas

ctx = canvas.getContext("2d")

# Draw circle
def draw_circle(x, y, radius, color):
    ctx.fillStyle = color
    ctx.beginPath()
    ctx.arc(x, y, radius, 0, 2 * math.pi)
    ctx.fill()

# Animation
angle = 0

def animate():
    global angle
    
    # Clear canvas
    ctx.clearRect(0, 0, 400, 400)
    
    # Calculate position
    x = 200 + 100 * math.cos(angle)
    y = 200 + 100 * math.sin(angle)
    
    # Draw
    draw_circle(x, y, 20, "#3b82f6")
    
    angle += 0.05
    
    # Continue animation
    document.window.requestAnimationFrame(animate)

animate()

List Operations

# List comprehensions
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Filter even numbers
even = [n for n in numbers if n % 2 == 0]
print(f"Even: {even}")

# Square all numbers
squared = [n ** 2 for n in numbers]
print(f"Squared: {squared}")

# Nested comprehension
matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
for row in matrix:
    print(row)

# Filter and transform
result = [n * 3 for n in numbers if n > 5]
print(f"Greater than 5, tripled: {result}")

# Dictionary comprehension
squares = {n: n**2 for n in range(1, 6)}
print(f"Squares dict: {squares}")

Comparison: Brython vs Pyodide

Pros:
  • Fast startup (~500KB)
  • Direct DOM access
  • Python-like syntax
  • Good for simple scripts
Cons:
  • Not full CPython
  • Limited stdlib
  • No NumPy/SciPy
  • Some Python features missing

Best Practices

For basic DOM manipulation and simple logic, use Brython:
from browser import document, html

# Quick and lightweight
button = html.BUTTON("Click me")
button.bind("click", lambda e: print("Clicked!"))
document.body <= button
For scientific computing, use python-wasm:
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10, 100)
y = np.sin(x)
plt.plot(x, y)
Use async/await for network requests:
from browser import aio

async def fetch_data():
    response = await aio.get(url)
    return response.data

aio.run(fetch_data())

Limitations

No File System: Cannot access local files or write to disk (browser security).
Brython Differences: Brython is not 100% compatible with CPython. Some features may work differently.
For full CPython compatibility and scientific libraries, use python-wasm (Pyodide).

JavaScript

Alternative scripting language

Ruby

Another dynamic language

Go

Statically-typed alternative

WebAssembly

Low-level compilation target

Build docs developers (and LLMs) love