Reactive user interfaces with pure Python
—
JavaScript module integration system for incorporating client-side functionality. ReactPy's web module system enables seamless integration of JavaScript libraries and custom client-side code with Python components.
Create JavaScript modules from string templates:
def module_from_template(name: str, template: str, **params) -> Module: ...Parameters:
name: Module name/identifiertemplate: JavaScript template string with parameter placeholders**params: Template parameters for substitutionReturns: Module instance
Usage Examples:
from reactpy.web import module_from_template
# Simple JavaScript module
counter_js = module_from_template(
"counter",
"""
export function createCounter(initialValue = {initial}) {{
let count = initialValue;
return {{
get: () => count,
increment: () => ++count,
decrement: () => --count
}};
}}
""",
initial=0
)Create modules from JavaScript files:
def module_from_file(name: str, file: str | Path) -> Module: ...Parameters:
name: Module name/identifierfile: Path to JavaScript fileReturns: Module instance
Usage Examples:
from pathlib import Path
from reactpy.web import module_from_file
# Load from file
chart_module = module_from_file(
"charts",
Path("./static/js/charts.js")
)
# Or with string path
utils_module = module_from_file("utils", "./js/utilities.js")Create modules from remote JavaScript resources:
def module_from_url(name: str, url: str, dev: bool = False) -> Module: ...Parameters:
name: Module name/identifierurl: URL to JavaScript moduledev: Whether to use development versionReturns: Module instance
Usage Examples:
from reactpy.web import module_from_url
# Load external library
lodash = module_from_url(
"lodash",
"https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"
)
# Development version
react_dev = module_from_url(
"react",
"https://unpkg.com/react@18/umd/react.development.js",
dev=True
)Export Python objects to JavaScript modules:
def export(obj: Any, name: str | None = None) -> Any: ...Parameters:
obj: Python object to exportname: Optional export name (defaults to object name)Returns: The original object (for chaining)
Usage Examples:
from reactpy.web import export
# Export function
@export
def calculate_tax(amount, rate):
return amount * rate
# Export with custom name
@export("formatCurrency")
def format_money(amount):
return f"${amount:.2f}"
# Export data
config = export({
"api_base": "https://api.example.com",
"timeout": 5000
}, "appConfig")The Module class represents a JavaScript module:
class Module:
name: str
source: str
exports: dict[str, Any]
def __init__(self, name: str, source: str): ...
def add_export(self, name: str, obj: Any) -> None: ...
def get_export(self, name: str) -> Any: ...Integrate JavaScript modules with ReactPy components:
from reactpy import component, html, use_effect, use_state
from reactpy.web import module_from_template, export
# Create a chart module
chart_module = module_from_template(
"chart",
"""
import Chart from 'https://cdn.skypack.dev/chart.js';
export function createChart(canvas, data) {{
return new Chart(canvas.getContext('2d'), {{
type: 'bar',
data: data,
options: {{
responsive: true,
plugins: {{
title: {{
display: true,
text: '{title}'
}}
}}
}}
}});
}}
""",
title="Sales Data"
)
@component
def ChartComponent():
chart_ref = use_ref(None)
use_effect(
lambda: create_chart_instance(),
[]
)
def create_chart_instance():
if chart_ref.current:
# Call JavaScript function
chart_module.createChart(
chart_ref.current,
{
"labels": ["Jan", "Feb", "Mar"],
"datasets": [{
"label": "Sales",
"data": [100, 150, 200]
}]
}
)
return html.canvas({"ref": chart_ref})Integrate with WebSocket or real-time data:
from reactpy.web import module_from_template
websocket_module = module_from_template(
"websocket",
"""
export class WebSocketClient {{
constructor(url, onMessage) {{
this.ws = new WebSocket(url);
this.ws.onmessage = (event) => {{
onMessage(JSON.parse(event.data));
}};
}}
send(data) {{
this.ws.send(JSON.stringify(data));
}}
close() {{
this.ws.close();
}}
}}
"""
)
@component
def RealtimeComponent():
messages, set_messages = use_state([])
use_effect(
lambda: setup_websocket(),
[]
)
def setup_websocket():
def handle_message(data):
set_messages([*messages, data])
client = websocket_module.WebSocketClient(
"ws://localhost:8000/ws",
handle_message
)
return lambda: client.close()
return html.div(
html.h2("Real-time Messages"),
html.ul(
*[html.li(msg["text"]) for msg in messages]
)
)Integrate popular JavaScript libraries:
# D3.js integration
d3_module = module_from_url(
"d3",
"https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"
)
@component
def D3Visualization():
svg_ref = use_ref(None)
use_effect(
lambda: create_d3_chart(),
[]
)
def create_d3_chart():
if svg_ref.current:
svg = d3_module.select(svg_ref.current)
svg.selectAll("circle")
.data([10, 20, 30])
.enter()
.append("circle")
.attr("cx", lambda d, i: i * 50 + 25)
.attr("cy", 50)
.attr("r", lambda d: d)
.attr("fill", "blue")
return html.svg(
{"ref": svg_ref, "width": 200, "height": 100}
)
# React component integration
react_module = module_from_url(
"react",
"https://unpkg.com/react@18/umd/react.production.min.js"
)
@component
def ReactInterop():
container_ref = use_ref(None)
use_effect(
lambda: render_react_component(),
[]
)
def render_react_component():
if container_ref.current:
# Render React component in ReactPy
react_element = react_module.createElement(
"div",
{"className": "react-component"},
"This is a React component in ReactPy!"
)
react_module.render(react_element, container_ref.current)
return html.div({"ref": container_ref})Configure module loading and behavior:
from reactpy import config
# Configure web modules directory
config.REACTPY_WEB_MODULES_DIR = "./static/js"
# Configure URL prefix for modules
config.REACTPY_WEB_MODULES_URL_PREFIX = "/modules"
# Use in production
production_module = module_from_url(
"library",
"https://cdn.jsdelivr.net/npm/library@1.0.0/dist/library.min.js"
)Install with Tessl CLI
npx tessl i tessl/pypi-reactpy