Global Functions
PyPositron provides several global functions that serve as the main entry points for creating and managing PyPositron applications. These functions handle window creation, event loop management, and utility operations.
openUI()
The primary function for creating and displaying a PyPositron window. This is the main entry point for most PyPositron applications.
Signature
openUI(html_path, main=None, after_close=None, width=900, height=700, title="Window",
functions=None, x=None, y=None, resizable=True, fullscreen=False,
min_size=(200, 100), hidden=False, frameless=False, easy_drag=True,
shadow=True, focus=True, minimized=False, maximized=False, on_top=False,
confirm_close=False, background_color='#FFFFFF', transparent=False,
text_select=False, zoomable=False, draggable=False, vibrancy=False,
gui=None, debug=False, http_server=False, http_port=None,
user_agent=None, private_mode=True, storage_path=None, icon=None) -> PositronWindowWrapper
Parameters
Required Parameters
html_path: str
: Path to the HTML file to load. This should be relative to your Python script or an absolute path.
Core Application Parameters
main: Callable[[PositronWindowWrapper], None] | None
: Function to run when the window opens. Receives a PositronWindowWrapper object as parameter. Default: Noneafter_close: Callable[[PositronWindowWrapper], None] | None
: Function to run when the window closes. Default: Nonefunctions: list | None
: List of Python functions to expose to JavaScript. These become available in<py>
tags and JavaScript. Default: None
Window Appearance
width: int
: Window width in pixels. Default: 900height: int
: Window height in pixels. Default: 700title: str
: Window title shown in the title bar. Default: "Window"background_color: str
: Window background color in CSS format. Default: '#FFFFFF'icon: str | None
: Path to window icon file. Only supported in Qt/GTK backends. Default: None
Window Position and Size
x: int | None
: X coordinate of the window position. Default: None (center)y: int | None
: Y coordinate of the window position. Default: None (center)min_size: tuple[int, int]
: Minimum window size as (width, height). Default: (200, 100)resizable: bool
: Whether the window can be resized. Default: True
Window State
hidden: bool
: Whether the window is initially hidden. Default: Falsefullscreen: bool
: Whether the window starts in fullscreen mode. Default: Falseminimized: bool
: Whether the window is initially minimized. Default: Falsemaximized: bool
: Whether the window is initially maximized. Default: Falsefocus: bool
: Whether the window has focus when created. Default: True
Window Behavior
frameless: bool
: Whether the window has no frame/border (no title bar, borders). Default: Falseeasy_drag: bool
: Whether frameless windows can be easily dragged. Default: Trueshadow: bool
: Whether the window has a drop shadow. Default: Trueon_top: bool
: Whether the window stays on top of other windows. Default: Falseconfirm_close: bool
: Whether to show confirmation dialog when closing. Default: Falsetransparent: bool
: Whether the window background is transparent. Default: Falsevibrancy: bool
: Whether the window has vibrancy effect on macOS. Default: False
Content Behavior
text_select: bool
: Whether text selection is enabled in the webview. Default: Falsezoomable: bool
: Whether content can be zoomed (Ctrl+/Ctrl-). Default: Falsedraggable: bool
: Whether the window can be dragged. Default: False
Browser Configuration
gui: webview.GUIType | None
: GUI toolkit to use. Options: 'qt', 'gtk', 'cef', 'mshtml', 'edgechromium', 'android'. Default: None (auto-select)debug: bool
: Whether to enable debug mode (developer tools). Default: Falseprivate_mode: bool
: Whether to run in private browsing mode. Default: Trueuser_agent: str | None
: Custom user agent string. Default: None
HTTP Server
http_server: bool
: Whether to serve local files using HTTP server instead of file:// protocol. Default: Falsehttp_port: int | None
: HTTP server port. Default: None (auto-select)
Storage
storage_path: str | None
: Path for storing browser data (cookies, localStorage, etc.). Default: None
Returns
PositronWindowWrapper
: A wrapper object providing access to the window and context.
Raises
RuntimeError
: If not called from the main threadFileNotFoundError
: If the HTML file is not found
Usage Examples
Basic Usage
import py_positron
def main(ui):
ui.document.getElementById("title").innerText = "Hello PyPositron!"
py_positron.openUI("index.html", main=main)
Customized Window
import py_positron
def main(ui):
# Your app logic here
pass
def on_close(ui):
print("Window is closing...")
py_positron.openUI(
"app.html",
main=main,
after_close=on_close,
width=1200,
height=800,
title="My PyPositron App",
resizable=True,
background_color="#f0f0f0"
)
Frameless Window
import py_positron
def main(ui):
# Create custom title bar since window is frameless
title_bar = ui.document.getElementById("titleBar")
close_btn = ui.document.getElementById("closeBtn")
def close_window():
ui.window.destroy()
close_btn.addEventListener("click", close_window)
py_positron.openUI(
"frameless.html",
main=main,
frameless=True,
easy_drag=True,
width=800,
height=600
)
Exposing Python Functions
import py_positron
def calculate_sum(a, b):
return a + b
def get_system_info():
import platform
return {
"system": platform.system(),
"python_version": platform.python_version()
}
def main(ui):
# Functions are now available in JavaScript and <py> tags
pass
py_positron.openUI(
"calculator.html",
main=main,
functions=[calculate_sum, get_system_info]
)
Development Mode
import py_positron
def main(ui):
pass
py_positron.openUI(
"debug.html",
main=main,
debug=True, # Enables developer tools
http_server=True, # Serves files via HTTP
http_port=8080
)
start()
Starts the webview event loop. This function is typically not needed as openUI()
handles this automatically, but it can be useful in advanced scenarios.
Signature
start() -> None
Usage
import py_positron
# This is usually handled automatically by openUI()
py_positron.start()
escape_js_string()
Escapes a string for safe use in JavaScript code. This is useful when dynamically generating JavaScript code or when passing Python strings that may contain special characters.
Signature
escape_js_string(string: str) -> str
Parameters
string: str
: The string to escape
Returns
str
: The escaped string safe for JavaScript
Usage Examples
import py_positron
def main(ui):
user_input = "Hello 'World' with \"quotes\" and \n newlines"
safe_string = py_positron.escape_js_string(user_input)
# Now safe to use in JavaScript
js_code = f"console.log('{safe_string}');"
# Or when setting element content
element = ui.document.getElementById("output")
element.innerText = safe_string
run_python_code_in_html()
Processes and executes Python code embedded in HTML <py>
tags. This function is used internally by PyPositron but can be called manually for advanced use cases.
Signature
run_python_code_in_html(html_content: str, context: PositronContext) -> str
Parameters
html_content: str
: HTML content containing<py>
tagscontext: PositronContext
: The execution context for Python code
Returns
str
: HTML content with<py>
tags processed and executed
Usage
This function is primarily used internally, but understanding it helps when working with <py>
tags:
<!-- This gets processed by run_python_code_in_html() -->
<py>
button = document.getElementById("myButton")
button.innerText = "Updated by Python!"
button.style.color = "blue"
</py>
Complete Application Examples
Simple Calculator
import py_positron
def add(a, b):
return float(a) + float(b)
def subtract(a, b):
return float(a) - float(b)
def multiply(a, b):
return float(a) * float(b)
def divide(a, b):
if float(b) == 0:
return "Error: Division by zero"
return float(a) / float(b)
def main(ui):
# Calculator logic
display = ui.document.getElementById("display")
buttons = ui.document.getElementsByClassName("calc-btn")
current_value = ""
operator = None
stored_value = None
def update_display():
display.value = current_value or "0"
def handle_number(num):
nonlocal current_value
current_value += str(num)
update_display()
def handle_operator(op):
nonlocal current_value, operator, stored_value
if current_value:
stored_value = float(current_value)
current_value = ""
operator = op
def calculate():
nonlocal current_value, operator, stored_value
if stored_value is not None and current_value and operator:
try:
if operator == "+":
result = add(stored_value, current_value)
elif operator == "-":
result = subtract(stored_value, current_value)
elif operator == "*":
result = multiply(stored_value, current_value)
elif operator == "/":
result = divide(stored_value, current_value)
current_value = str(result)
operator = None
stored_value = None
update_display()
except Exception as e:
current_value = "Error"
update_display()
# Set up button event handlers
for button in buttons:
value = button.getAttribute("data-value")
if value:
if value.isdigit() or value == ".":
button.addEventListener("click", lambda: handle_number(value))
elif value in ["+", "-", "*", "/"]:
button.addEventListener("click", lambda: handle_operator(value))
elif value == "=":
button.addEventListener("click", calculate)
elif value == "clear":
def clear():
nonlocal current_value, operator, stored_value
current_value = ""
operator = None
stored_value = None
update_display()
button.addEventListener("click", clear)
update_display()
py_positron.openUI(
"calculator.html",
main=main,
title="PyPositron Calculator",
width=300,
height=400,
resizable=False,
functions=[add, subtract, multiply, divide]
)
File Manager
import py_positron
import os
import json
def get_directory_contents(path):
try:
items = []
for item in os.listdir(path):
item_path = os.path.join(path, item)
items.append({
"name": item,
"path": item_path,
"is_directory": os.path.isdir(item_path),
"size": os.path.getsize(item_path) if os.path.isfile(item_path) else 0
})
return items
except Exception as e:
return []
def main(ui):
current_path = os.getcwd()
path_display = ui.document.getElementById("currentPath")
file_list = ui.document.getElementById("fileList")
def update_file_list():
nonlocal current_path
path_display.innerText = current_path
file_list.innerHTML = ""
contents = get_directory_contents(current_path)
# Add parent directory option
if current_path != os.path.dirname(current_path):
parent_item = ui.document.createElement("div")
parent_item.className = "file-item directory"
parent_item.innerText = ".."
parent_item.addEventListener("click", lambda: navigate_to(os.path.dirname(current_path)))
file_list.appendChild(parent_item)
# Add files and directories
for item in contents:
item_element = ui.document.createElement("div")
item_element.className = f"file-item {'directory' if item['is_directory'] else 'file'}"
item_element.innerText = item['name']
if item['is_directory']:
item_element.addEventListener("click", lambda: navigate_to(item['path']))
file_list.appendChild(item_element)
def navigate_to(path):
nonlocal current_path
if os.path.isdir(path):
current_path = path
update_file_list()
# Initial load
update_file_list()
py_positron.openUI(
"filemanager.html",
main=main,
title="PyPositron File Manager",
width=800,
height=600,
functions=[get_directory_contents]
)
Best Practices
-
Keep the main function focused: Use the main function primarily for UI setup and event binding.
-
Handle errors gracefully: Always wrap potentially failing operations in try-catch blocks.
-
Use appropriate window settings: Choose window parameters that make sense for your application type.
-
Expose only necessary functions: Only expose Python functions to JavaScript that are actually needed.
-
Clean up resources: Use the
after_close
callback to clean up any resources when the window closes. -
Test different backends: If you encounter issues, try different GUI backends using the
gui
parameter. -
Use debug mode during development: Enable debug mode to access developer tools for easier debugging.
# Good practice example
import py_positron
import logging
def safe_file_operation(filename):
try:
with open(filename, 'r') as f:
return f.read()
except Exception as e:
logging.error(f"File operation failed: {e}")
return f"Error: {str(e)}"
def main(ui):
try:
# Initialize UI components
setup_event_handlers(ui)
load_initial_data(ui)
except Exception as e:
ui.htmlwindow.alert(f"Initialization error: {e}")
def cleanup(ui):
# Clean up resources
logging.info("Application closing")
py_positron.openUI(
"app.html",
main=main,
after_close=cleanup,
debug=True, # Enable during development
functions=[safe_file_operation]
)
Related Documentation
- PositronWindowWrapper: The object returned by
openUI()
- Python in HTML: Using
<py>
tags and exposed functions - Document: DOM manipulation
- HTMLWindow: Browser window functionality