{"id":27931455,"url":"https://github.com/59de44955ebd/python-webview2","last_synced_at":"2026-04-02T18:53:39.414Z","repository":{"id":291406417,"uuid":"977204604","full_name":"59de44955ebd/python-webview2","owner":"59de44955ebd","description":"Lightweight WebView implementation for Python 3.x in Windows 10/11 based on the MS Edge WebView2 runtime (Chrome/Chromium).","archived":false,"fork":false,"pushed_at":"2025-05-04T15:20:34.000Z","size":2003,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-07T03:52:47.761Z","etag":null,"topics":["cef","cefypthon","chrome","chromium","edge","python","python3","webview","webview2","windows","windows10","windows11"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/59de44955ebd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-03T16:58:02.000Z","updated_at":"2025-05-04T15:20:37.000Z","dependencies_parsed_at":"2025-05-04T13:25:10.543Z","dependency_job_id":"ade84130-30fe-4af4-8257-dcf170fbf7c1","html_url":"https://github.com/59de44955ebd/python-webview2","commit_stats":null,"previous_names":["59de44955ebd/python-webview2"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/59de44955ebd%2Fpython-webview2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/59de44955ebd%2Fpython-webview2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/59de44955ebd%2Fpython-webview2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/59de44955ebd%2Fpython-webview2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/59de44955ebd","download_url":"https://codeload.github.com/59de44955ebd/python-webview2/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252810276,"owners_count":21807759,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cef","cefypthon","chrome","chromium","edge","python","python3","webview","webview2","windows","windows10","windows11"],"created_at":"2025-05-07T03:52:54.530Z","updated_at":"2025-12-30T23:05:03.118Z","avatar_url":"https://github.com/59de44955ebd.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# python-webview2\r\n\r\npython-webview2 is a WebView implementation for Python 3.x in Windows 10/11 based on the [MS Edge WebView2 runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2) (i.e. Chrome/Chromium). It's a lightweight (about 200 KB) alternative for (outdated) [cefpython3](https://pypi.org/project/cefpython3/). As far as I know the Edge runtime is preinstalled in any Windows 11 and fully updated Windows 10 system, and can be installed manually in older Windows 10 systems.\r\n\r\npython-webview2 is implemented as binary Python extension module (.pyd) and uses code from this [webview library](https://github.com/webview/webview).\r\n\r\n## Installation\r\n\r\nCopy the appropriate webview2.cp...-win_....pyd file into the DLLs folder of your local Python installation, done.\r\n\r\n## Configuration\r\n\r\nYou can pass arbitrary [Chromium Command Line Switches](https://peter.sh/experiments/chromium-command-line-switches/) by setting environment variable `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS` before creating a WebView instance. The following example would make WebView use the specified SOCKS5 proxy:\r\n\r\n```python\r\nimport os\r\nimport webview2\r\n\r\nos.environ['WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS'] = '--proxy-server=\"socks5://127.0.0.1:5150\"'\r\n\r\nwebview = webview2.WebView(url = \"https://ipaddress.my/\")\r\n\r\nwebview.run()\r\n```\r\n\r\n## Examples\r\n\r\n*The [examples](examples/) folder also contains demos for using python-webview2 with [wxWidgets](https://pypi.org/project/wxPython/) or with the plain [WinAPI](https://en.wikipedia.org/wiki/Windows_API) and [ctypes](https://en.wikipedia.org/wiki/Windows_API).*\r\n\r\n### 1.) Binding: Call from JS into Python, return result to JS\r\n```python\r\nimport webview2\r\n\r\nwebview = webview2.WebView()\r\nwebview.set_html('''\r\n\u003cbr\u003e\r\n\u003cp\u003e\r\n  \u003clabel for=\"inp\"\u003eExpression:\u003c/label\u003e\r\n  \u003cinput id=\"inp\" value=\"23 * 7 - 42\" style=\"width: 100%\"\u003e\r\n\u003c/p\u003e\r\n\u003cp\u003e\u003cbutton id=\"btn\"\u003eEvaluate in Python\u003c/button\u003e\u003c/p\u003e\r\n\u003cp\u003e\r\n  \u003clabel for=\"res\"\u003eResult:\u003c/label\u003e\r\n  \u003cinput id=\"res\" style=\"width: 100%\"\u003e\r\n\u003c/p\u003e\r\n\u003cscript\u003e\r\ndocument.getElementById('btn').addEventListener(\"click\", async () =\u003e {\r\n    document.getElementById('res').value = await __py_eval__(document.getElementById('inp').value);\r\n});\r\n\u003c/script\u003e\r\n''')\r\n\r\ndef python_eval(id, args):\r\n    try:\r\n        expression = eval(args)[0]  # quick \u0026 dirty, better use json.loads\r\n        webview.js_return(id, 0, str(eval(expression)))\r\n    except Exception as e:\r\n        webview.js_return(id, 0, f'\"Error: {e}\"')  # quick \u0026 dirty, better use json.dumps\r\n\r\nwebview.js_bind(\"__py_eval__\", python_eval)\r\nwebview.run()\r\n```\r\n![Binding Demo](screenshots/demo_binding.png)\r\n\r\n### 2.) Minimal Map Viewer Demo (Standalone)\r\n```python\r\nimport os\r\nimport webview2\r\n\r\nAPP_DIR = os.path.dirname(os.path.realpath(__file__))\r\n\r\nwebview = webview2.WebView(\r\n    width = 1024, height = 768,\r\n    icon = os.path.join(APP_DIR, \"resources\", \"main.ico\"),\r\n    title = \"WebView2 Map Demo (Standalone)\",\r\n    url = \"https://59de44955ebd.github.io/map/\",\r\n    debug = True,\r\n)\r\nwebview.js_bind(\"__on_fs__\", lambda id, args: webview.set_fullscreen(eval(args)[0]))\r\nwebview.js_eval(\"\"\"\r\ndocument.addEventListener(\r\n    'fullscreenchange', \r\n    () =\u003e __on_fs__(+!map._isFullscreen)\r\n)\r\n\"\"\")\r\nwebview.run()\r\n```\r\n![Map Demo](screenshots/demo_map_standalone.png)\r\n\r\n### 3.) Minimal Map Viewer Demo ([PyQt5](https://pypi.org/project/PyQt5/), [PyQt6](https://pypi.org/project/PyQt6/) or [PySide6](https://pypi.org/project/PySide6/))\r\n```python\r\nimport os\r\nimport webview2\r\n\r\nfrom PyQt5.QtWidgets import QApplication, QMainWindow\r\n# from PyQt6.QtWidgets import QApplication, QMainWindow\r\n# from PySide6.QtWidgets import QApplication, QMainWindow\r\n\r\nAPP_DIR = os.path.dirname(os.path.realpath(__file__))\r\n\r\n\r\nclass Main(QMainWindow):\r\n\r\n    def __init__(self):\r\n        super().__init__()\r\n        self.webview = webview2.WebView(\r\n            window = int(self.winId()),\r\n            autosize = True,\r\n            icon = os.path.join(APP_DIR, \"resources\", \"main.ico\"),\r\n            title = \"WebView2 Map Demo (PyQt/PySide)\",\r\n            url = \"https://59de44955ebd.github.io/map/\",\r\n            debug = True,\r\n        )\r\n        self.webview.js_bind(\"__on_fs__\", \r\n                lambda id, args: self.webview.set_fullscreen(eval(args)[0]))\r\n        self.webview.js_eval(\"\"\"\r\n        document.addEventListener(\r\n            'fullscreenchange', \r\n            () =\u003e __on_fs__(+!map._isFullscreen)\r\n        )\r\n        \"\"\")\r\n        self.resize(1024, 768)\r\n        self.show()\r\n\r\n    def closeEvent(self, e):\r\n        self.webview.terminate()\r\n\r\n    def run(self):\r\n        self.webview.run()\r\n\r\nif __name__ == \"__main__\":\r\n    app = QApplication([])\r\n    main = Main()\r\n    main.run()\r\n```\r\n\r\n## API\r\n\r\n```\r\nwebview2.WebView(autosize=False, bgcolor=0xFFFFFF, debug=False, height=240, icon=None, title=None, url=None, width=320, window=None)\r\n```\r\nConstructor, create a WebView instance, either as standalone window or embedded into an existing window.  \r\nParameters:\r\n* autosize (bool) - Embedded mode only: If True, WebView resizes automatically to the parent window's client rect\r\n* bgcolor (int) - Webview's default background color as COLORREF, i.e. in BGR byte order\r\n* debug (bool) - If True, the DevTools (Console etc.) are available (F12)  \r\n* height (int) - Initial height of the WebView\r\n* icon (str) - Standalone mode only: path to .ico file used as window icon\r\n* title (str) - Standalone mode only: window title\r\n* url (str) - URL to load (same as calling navigate(url))\r\n* width (int) - Initial width of the WebView\r\n* window (int): - Handle (HWND) of existing window in which WebView is embedded\r\n  \r\n```\r\n\u003cinstance\u003e.get_native_handle(kind)\r\n```\r\nGet a native handle (HWND) of choice.  \r\nParameters:\r\n* kind (int) - See constants\r\n\r\n```\r\n\u003cinstance\u003e.js_bind(name, fn)\r\n```\r\nBind a function pointer to a new global JavaScript function.  \r\nParameters:\r\n* name (str) - Name of the JS function.  \r\n* fn (function) - Callback function  \r\n\r\n```\r\n\u003cinstance\u003e.js_eval(js)\r\n```\r\nEvaluate arbitrary JavaScript code. Use bindings if you need to communicate the result of the evaluation.  \r\nParameters:\r\n* js (str) - The JavaScript code to evaluate\r\n\r\n```\r\n\u003cinstance\u003e.js_init(js)\r\n```\r\nInject JavaScript code to be executed immediately upon loading a page. The code will be executed before window.onload.  \r\nParameters:\r\n* js (str) - The JavaScript code to inject\r\n\r\n```\r\n\u003cinstance\u003e.js_return(id, status, result)\r\n```\r\nRespond to a binding call from the JS side.  \r\nParameters:  \r\n* id (str) - The identifier of the binding call.Pass along the value received in the binding handler(see webview_bind()).   \r\n* status (int)  -- A status of zero tells the JS side that the binding call was successful; any other value indicates an error.  \r\n* result (str)  - The result of the binding call to be returned to the JS side. This must either be a valid JSON value or an empty string for the primitive JS value undefined.\r\n\r\n```\r\n\u003cinstance\u003e.js_unbind(name)\r\n```\r\nRemove a binding created with bind().  \r\nParameters:\r\n* name (str) - Name of the JS function. \r\n\r\n```\r\n\u003cinstance\u003e.navigate(url)\r\n```\r\nNavigate webview to the given URL. URL may be a properly encoded data URI.  \r\nParameters:\r\n* url (str)\r\n\r\n```\r\n\u003cinstance\u003e.run(hwnd=None, haccel=None)\r\n```\r\nRun the main loop until it's terminated.  \r\nOptional parameters hwnd and haccel only make sense if you use the native Windows API via ctypes, they have type HWND and HACCEL (from ctypes.wintypes) and allow to translate accelerators (key shortcuts) in the specified accelerator table for the specified window. However, those accelerators only work while the webview doesn't have keyboard focus, otherwise it doesn't forward key events to the host window. To handle both cases, webview without and with focus, you have to install a binding in JS that forwards keydown events to your application and then process those manually.\r\n\r\n```\r\n\u003cinstance\u003e.set_focus()\r\n```\r\nSet/restore mouse scroll and keyboard focus to webview.  \r\n\r\n```\r\n\u003cinstance\u003e.set_fullscreen(fullscreen)\r\n```\r\nEnter/leave fullscreen mode.\r\nParameters:\r\n* fullscreen (bool)\r\n\r\n```\r\n\u003cinstance\u003e.set_html(html)\r\n```\r\nLoad HTML content into the webview.\r\nParameters:  \r\n* html (str)\r\n\r\n```\r\n\u003cinstance\u003e.set_size(width, height, hint=0)\r\n```\r\nUpdate the size of the WebView.  \r\nParameters:\r\n* width (int) - New width.  \r\n* height (int) - New height.  \r\n* hint (int) - Size hint (see constants)\r\n\r\n```\r\n\u003cinstance\u003e.set_title(title)\r\n```\r\nUpdate the title of the native window.   \r\nParameters:\r\n* title (str)\r\n\r\n```\r\n\u003cinstance\u003e.terminate()\r\n```\r\nStop the main loop.\r\n\r\n### Constants\r\nWindow size hints  \r\n* webview2.HINT_NONE = 0  \r\n* webview2.HINT_MIN = 1  \r\n* webview2.HINT_MAX = 2  \r\n* webview2.HINT_FIXED = 3  \r\n\r\nNative handle kind.   \r\n* webview2.NATIVE_HANDLE_KIND_UI_WINDOW = 0  \r\n* webview2.NATIVE_HANDLE_KIND_UI_WIDGET = 1  \r\n\r\n## Compiling\r\n\r\nCompiling the Python extension module (.pyd) requires MS Visual Studio 2017 or later, and the environment variable %PYTHONHOME% must be set and contain the full path to a Python 3.x for Windows installation with \"include\" and \"libs\" subfolders.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F59de44955ebd%2Fpython-webview2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F59de44955ebd%2Fpython-webview2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F59de44955ebd%2Fpython-webview2/lists"}