|
| 1 | +# Call Python from JavaScript Example |
| 2 | +# pip install --upgrade webui2 |
| 3 | +from webui import webui |
| 4 | + |
| 5 | +html = """<!DOCTYPE html> |
| 6 | +<html> |
| 7 | + <head> |
| 8 | + <meta charset="UTF-8"> |
| 9 | + <script src="webui.js"></script> |
| 10 | + <title>Call Python from JavaScript Example</title> |
| 11 | + <style> |
| 12 | + body { |
| 13 | + font-family: 'Arial', sans-serif; |
| 14 | + color: white; |
| 15 | + background: linear-gradient(to right, #507d91, #1c596f, #022737); |
| 16 | + text-align: center; |
| 17 | + font-size: 18px; |
| 18 | + } |
| 19 | + button, input { |
| 20 | + padding: 10px; |
| 21 | + margin: 10px; |
| 22 | + border-radius: 3px; |
| 23 | + border: 1px solid #ccc; |
| 24 | + box-shadow: 0 3px 5px rgba(0,0,0,0.1); |
| 25 | + transition: 0.2s; |
| 26 | + } |
| 27 | + button { |
| 28 | + background: #3498db; |
| 29 | + color: #fff; |
| 30 | + cursor: pointer; |
| 31 | + font-size: 16px; |
| 32 | + } |
| 33 | + h1 { text-shadow: -7px 10px 7px rgb(67 57 57 / 76%); } |
| 34 | + button:hover { background: #c9913d; } |
| 35 | + input:focus { outline: none; border-color: #3498db; } |
| 36 | + </style> |
| 37 | + </head> |
| 38 | + <body> |
| 39 | + <h1>WebUI - Call Python from JavaScript</h1> |
| 40 | + <p>Call Python functions with arguments (<em>See the logs in your terminal</em>)</p> |
| 41 | + <button onclick="my_function_string('Hello', 'World');">Call my_function_string()</button> |
| 42 | + <br> |
| 43 | + <button onclick="my_function_integer(123, 456, 789, 12345.6789);">Call my_function_integer()</button> |
| 44 | + <br> |
| 45 | + <button onclick="my_function_boolean(true, false);">Call my_function_boolean()</button> |
| 46 | + <br> |
| 47 | + <button onclick="my_function_raw_binary(new Uint8Array([0x41,0x42,0x43]), big_arr);"> |
| 48 | + Call my_function_raw_binary()</button> |
| 49 | + <br> |
| 50 | + <p>Call a Python function that returns a response</p> |
| 51 | + <button onclick="MyJS();">Call my_function_with_response()</button> |
| 52 | + <div>Double: <input type="text" id="MyInputID" value="2"></div> |
| 53 | + <script> |
| 54 | + const arr_size = 512 * 1000; |
| 55 | + const big_arr = new Uint8Array(arr_size); |
| 56 | + big_arr[0] = 0xA1; |
| 57 | + big_arr[arr_size - 1] = 0xA2; |
| 58 | + function MyJS() { |
| 59 | + const MyInput = document.getElementById('MyInputID'); |
| 60 | + const number = MyInput.value; |
| 61 | + my_function_with_response(number, 2).then((response) => { |
| 62 | + MyInput.value = response; |
| 63 | + }); |
| 64 | + } |
| 65 | + </script> |
| 66 | + </body> |
| 67 | +</html>""" |
| 68 | + |
| 69 | + |
| 70 | +def my_function_string(e: webui.Event): |
| 71 | + # JavaScript: my_function_string('Hello', 'World') |
| 72 | + str_1 = e.get_string() # index 0 |
| 73 | + str_2 = e.get_string_at(1) |
| 74 | + print(f"my_function_string 1: {str_1}") # Hello |
| 75 | + print(f"my_function_string 2: {str_2}") # World |
| 76 | + |
| 77 | + |
| 78 | +def my_function_integer(e: webui.Event): |
| 79 | + # JavaScript: my_function_integer(123, 456, 789, 12345.6789) |
| 80 | + count = e.get_count() |
| 81 | + print(f"my_function_integer: There are {count} arguments in this event") # 4 |
| 82 | + |
| 83 | + number_1 = e.get_int() # index 0 |
| 84 | + number_2 = e.get_int_at(1) |
| 85 | + number_3 = e.get_int_at(2) |
| 86 | + float_1 = e.get_float_at(3) |
| 87 | + |
| 88 | + print(f"my_function_integer 1: {number_1}") # 123 |
| 89 | + print(f"my_function_integer 2: {number_2}") # 456 |
| 90 | + print(f"my_function_integer 3: {number_3}") # 789 |
| 91 | + print(f"my_function_integer 4: {float_1}") # 12345.6789 |
| 92 | + |
| 93 | + |
| 94 | +def my_function_boolean(e: webui.Event): |
| 95 | + # JavaScript: my_function_boolean(true, false) |
| 96 | + status_1 = e.get_bool() # index 0 |
| 97 | + status_2 = e.get_bool_at(1) |
| 98 | + print(f"my_function_boolean 1: {status_1}") # True |
| 99 | + print(f"my_function_boolean 2: {status_2}") # False |
| 100 | + |
| 101 | + |
| 102 | +def my_function_raw_binary(e: webui.Event): |
| 103 | + # JavaScript: my_function_raw_binary(new Uint8Array([0x41,0x42,0x43]), big_arr) |
| 104 | + raw_1 = e.get_string() # index 0 — raw bytes as str |
| 105 | + raw_2 = e.get_string_at(1) |
| 106 | + len_1 = e.get_size() # index 0 |
| 107 | + len_2 = e.get_size_at(1) |
| 108 | + |
| 109 | + hex_1 = " ".join(f"0x{b:02x}" for b in raw_1.encode("latin-1")[:len_1]) |
| 110 | + print(f"my_function_raw_binary 1 ({len_1} bytes): {hex_1}") |
| 111 | + |
| 112 | + raw_2_bytes = raw_2.encode("latin-1") |
| 113 | + valid = len_2 >= 2 and raw_2_bytes[0] == 0xA1 and raw_2_bytes[len_2 - 1] == 0xA2 |
| 114 | + print(f"my_function_raw_binary 2 big ({len_2} bytes): valid data? {'Yes' if valid else 'No'}") |
| 115 | + |
| 116 | + |
| 117 | +def my_function_with_response(e: webui.Event): |
| 118 | + # JavaScript: my_function_with_response(number, 2).then(...) |
| 119 | + number = e.get_int() # index 0 |
| 120 | + times = e.get_int_at(1) |
| 121 | + result = number * times |
| 122 | + print(f"my_function_with_response: {number} * {times} = {result}") |
| 123 | + e.return_int(result) |
| 124 | + |
| 125 | + |
| 126 | +def main(): |
| 127 | + window = webui.Window() |
| 128 | + |
| 129 | + window.bind("my_function_string", my_function_string) |
| 130 | + window.bind("my_function_integer", my_function_integer) |
| 131 | + window.bind("my_function_boolean", my_function_boolean) |
| 132 | + window.bind("my_function_raw_binary", my_function_raw_binary) |
| 133 | + window.bind("my_function_with_response", my_function_with_response) |
| 134 | + |
| 135 | + window.show(html) |
| 136 | + webui.wait() |
| 137 | + |
| 138 | + |
| 139 | +if __name__ == "__main__": |
| 140 | + main() |
0 commit comments