README.md (4506B)
1 # PYTML - Python in Your Browser 2 [](https://www.wikidata.org/wiki/Q140185675) 3 [](https://pytml.vercel.app/api/count) 4 [](https://pytml.js.org/) 5 [](https://github.com/NodeX-AR/Pytml) 6 [](https://github.com/NodeX-AR/Pytml/blob/main/LICENSE) 7 [](https://github.com/NodeX-AR/Pytml/issues) 8 [](https://github.com/NodeX-AR/Pytml/commits/main) 9 10 **Run Python in your browser with zero configuration — no server, just a script tag.** 11 12 Pytml 2.5 is a lightweight JavaScript bridge built on **Pyodide 314.0.7**. Write Python inside HTML, interact with ordinary DOM elements, and use the small numbered UI syntax supported by the 2.5 runtime. 13 14 --- 15 16 ## Quick Start 17 18 Add one line to your HTML: 19 20 ```html 21 <script src="https://pytml.vercel.app/pytml.js"></script> 22 ``` 23 24 Then write Python: 25 26 ```html 27 <py> 28 print("Hello, world!") 29 name = input("Your name? ") 30 print(f"Hi {name}!") 31 </py> 32 ``` 33 34 ## Pytml 2.5 UI Syntax 35 36 Inside a `<pyN>` block, Pytml 2.5 recognizes numbered UI tags such as: 37 38 ```html 39 <py1> 40 41 <btn1>1</btn1> 42 <btn2>2</btn2> 43 <txt1> 44 45 def show(e): 46 print("You clicked a button") 47 48 btn1.on("click", show) 49 50 </py1> 51 ``` 52 53 `<btnN>` becomes a real `<button id="btnN">`, while `<inputN>` and `<txtN>` become real text inputs. Python indentation is preserved before the source is passed to Pyodide. 54 55 ## Normal HTML + Python 56 57 Ordinary HTML IDs are available to Python: 58 59 ```html 60 <button id="hello">Click me</button> 61 <p id="result"></p> 62 63 <py> 64 def hello(event): 65 result.text = "Hello from Python!" 66 67 hello.on("click", hello) 68 </py> 69 ``` 70 71 ## Packages 72 73 Pytml keeps the Pyodide package workflow, including `micropip`: 74 75 ```python 76 import micropip 77 await micropip.install("numpy") 78 79 import numpy as np 80 print(np.mean([1, 2, 3])) 81 ``` 82 83 Packages available in the Pyodide environment can be used from Pytml, including common scientific packages such as NumPy, pandas and Matplotlib. 84 85 ## Multiple Programs 86 87 `<py1>`, `<py2>`, `<py3>`, and so on are identifiers, not filenames. Blocks with the same identifier belong to the same program: 88 89 ```html 90 <py1> 91 x = 10 92 </py1> 93 94 <py1> 95 print(x) 96 </py1> 97 98 <py2> 99 print("Another program") 100 </py2> 101 ``` 102 103 ## Local Files 104 105 Pytml supports local HTML files opened directly with `file://` when the Python code is inline: 106 107 ```html 108 <script src="https://pytml.vercel.app/pytml.js"></script> 109 110 <py> 111 print("Hello from a local file!") 112 </py> 113 ``` 114 115 No Python web server is required for this case. You can also use a local copy of `pytml.js` with `file://` by changing the script source to `./pytml.js`. 116 117 A relative external Python file such as `<py src="app.py">` cannot be fetched from `file://` by normal browser JavaScript because of browser security restrictions; use inline Python or an HTTPS Python source URL for that case. 118 119 See `local-file-test.html` for a ready-to-open example. 120 121 ## Features 122 123 - Zero config — one script tag 124 - Python in HTML 125 - DOM interaction 126 - Browser `input()` 127 - Numbered inline UI controls 128 - Mouse, pointer, touch, keyboard and scroll events 129 - Joystick and gamepad helpers 130 - Canvas, audio and video helpers 131 - Clipboard, storage, downloads and fullscreen helpers 132 - Package support through `micropip` 133 - NumPy, pandas and Matplotlib support through the Pyodide environment 134 - Privacy-first client-side execution 135 136 ## Links 137 138 Official Website → https://pytml.js.org/ 139 140 Demos → https://pytml.js.org/demo.html 141 142 GitHub → https://github.com/NodeX-AR/Pytml 143 144 ## License 145 146 Pytml is open-source under the Apache 2.0 License. 147 148 ## Support 149 150 **If you find Pytml useful, consider giving it a star on GitHub!** 151 152 ## Security Note: 153 Pytml defaults to using `element.text`, which uses the browser's textContent API. This means it is 100% secure against ***Cross-Site Scripting (XSS) attacks***. 154 If you must use element.html to render raw HTML, never pass untrusted user input directly into it. Use the built-in `pytml.escape()` helper to sanitize the input first.