{"id":15442794,"url":"https://github.com/dtmilano/viaduc","last_synced_at":"2025-07-23T21:39:02.583Z","repository":{"id":57477451,"uuid":"318708174","full_name":"dtmilano/viaduc","owner":"dtmilano","description":"Viaduc is probably the simplest way to create a nice-looking gui using python and tiny bit of html/css/js.","archived":false,"fork":false,"pushed_at":"2024-11-03T03:13:10.000Z","size":1878,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-05T23:41:51.870Z","etag":null,"topics":["eel-python","gui","html-css-javascript","python","tkinter"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dtmilano.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2020-12-05T05:17:33.000Z","updated_at":"2025-04-16T15:39:57.000Z","dependencies_parsed_at":"2024-10-28T01:35:16.065Z","dependency_job_id":"fb696d80-b5a7-4614-aeda-f6f93b9fb7fc","html_url":"https://github.com/dtmilano/viaduc","commit_stats":{"total_commits":96,"total_committers":1,"mean_commits":96.0,"dds":0.0,"last_synced_commit":"57905652968cbda1852e430d41eafddb5c38ab4f"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/dtmilano/viaduc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtmilano%2Fviaduc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtmilano%2Fviaduc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtmilano%2Fviaduc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtmilano%2Fviaduc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dtmilano","download_url":"https://codeload.github.com/dtmilano/viaduc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtmilano%2Fviaduc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266753979,"owners_count":23979145,"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","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["eel-python","gui","html-css-javascript","python","tkinter"],"created_at":"2024-10-01T19:30:14.255Z","updated_at":"2025-07-23T21:39:02.561Z","avatar_url":"https://github.com/dtmilano.png","language":"Python","readme":"# viaduc\n![Upload Python Package](https://github.com/dtmilano/viaduc/workflows/Upload%20Python%20Package/badge.svg)\n[![PyPI version](https://badge.fury.io/py/viaduc.svg)](https://badge.fury.io/py/viaduc)\n\nViaduc is probably the simplest way to create a nice-looking gui using python and a tiny bit of html/css/js. No server and everything in one file.\n\n![form](./screenshots/form.png)\n\nSee the code for this example [here](./examples/form.py).\n\n**viaduc** uses pywebview and [Bootstrap](https://getbootstrap.com/) to provide a gui for other tools and scripts.\n\n# install\n```\n$ pip install viaduc\n```\n\n## development\n\nTo install a development version run\n\n```\npip install git+https://github.com/dtmilano/viaduc\n```\n\n# simplest\nThe simplest Viaduc program instantiates a `Viaduc` object, like this ([simplest.py](./examples/simplest.py))\n\n```\n#! /usr/bin/env python3\n\nfrom viaduc import Viaduc\n\nif __name__ == '__main__':\n    Viaduc()\n```\n\nand you will see this window\n\n![simplest](./screenshots/simplest.png)\n\n# helloworld\nThen, let's do something more interesting implementing the `Presentation` class.\nLet's add a `title` and some `html` which includes some metatags (`{{name}}`) that are replaced by viaduc ([helloworld.py](./examples/helloworld.py)).\n\n```\n#! /usr/bin/env python3\n\nfrom viaduc import Viaduc\n\n\nclass Presentation(Viaduc.Presentation):\n    title = 'hello world'\n    html = '''\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    {{bootstrap_meta}}\n\n    {{bootstrap_css}}\n\n    \u003ctitle\u003e{{title}}\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cdiv class=\"jumbotron\"\u003e\n        \u003ch1\u003e{{title}}\u003c/h1\u003e\n        \u003cp class=\"lead\"\u003eWelcome to \u003cem\u003eViaduc\u003c/em\u003e, the simplest way of creating a GUI in python.\u003c/p\u003e\n    \u003c/div\u003e\n    \n    {{bootstrap_js}}\n\n  \u003c/body\u003e  \n \u003c/html\u003e\n'''\n\n\nif __name__ == '__main__':\n    Viaduc(presentation=Presentation())\n```\n\nand we will obtain this\n\n\n![helloworld](./screenshots/helloworld.png)\n\n# temperature converter\nWe have seen how `Presentation` can implement the GUI, but what about the interaction?\n([temperature-converter.py](./examples/temperature-converter.py))\n\n```\n#! /usr/bin/env python3\nimport sys\n\nfrom viaduc import Viaduc\n\n\ndef fahrenheit_to_celsius(fahrenheit):\n    return round((5 / 9) * (float(fahrenheit) - 32), 2)\n\n\nclass Api(Viaduc.Api):\n    def convert(self, vals):\n        v = self.map_vals(vals)\n        if not v['_fahrenheit']:\n            raise ValueError('Enter a temperature')\n        return Viaduc.callback('showCelsius', {'celsius': fahrenheit_to_celsius(v['_fahrenheit'])})\n\n\nclass Presentation(Viaduc.Presentation):\n    width = 320\n    height = 468\n    title = 'temperature converter'\n    html = '''\n    \u003c!-- copy file here --\u003e\n    '''\n    file = \"temperature-converter.html\"\n\n\nif __name__ == '__main__':\n    Viaduc(api=Api(), presentation=Presentation(), args=sys.argv + ['--frameless'])\n```\n\n\nHere we are also implementing API, which provides the means of interoperation between domains.\n\nAnother thing to note here is that instead of having the HTML as a string, we read it from a file to keep this example file smaller and focus on the essential parts.\n\nWhen we execute it, we obtain this window. It's `frameless` as we are passing this extra argument to `Viaduc`.\n\n\n![temperature-converter](./screenshots/temperature-converter.png)\n\nClicking the **Convert** button or pressing **RETURN** converts Fahrenheit's temperature to Celsius, invoking the `convert()` method. Viaduc automatically adds all the form values as `vals` that contain `id`s and `values`.\n\nOnce we convert the temperature using `fahrenheit_to_celsius()` we use the `CALLBACK` action to invoke a javascript method defined in [temperature-converter.html](./examples/temperature-converter.html#L65) to show the result.\n\n# editor\nWe can also interact with the local filesystem reading and writing files. This [editor](./examples/editor.py) shows these interactions.\n\nAlso shows how to use [Bootstrap Material Design](https://mdbootstrap.github.io/bootstrap-material-design/).\n\n![editor](./screenshots/editor-example.gif)\n\n# android-device-viewer\nA more involved and practical example. [android-device-viewer](./examples/android-device-viewer.py) shows how easy is to provide a GUI and some interaction to other apps.\n\n![android-device-viewer](./screenshots/android-device-viewer.png)\n\nUsing [Culebratester2-public](https://github.com/dtmilano/CulebraTester2-public) and the python client library [Culebratester2-client](https://github.com/dtmilano/CulebraTester2-client) communicates with an Android device to get the screenshot and send events (i.e. clicks). Therefore, you can interact with the physical device through its representation.\n\nAlso provides a context menu to be able to send BACK or quit the app.\n\n# no bootstrap\nIm case you don't need or want **bootstrap** to be included you can pass the option `--no-bootstrap` and **viaduc** won't\ncomplain if the components are missing.\n\n\n```\nViaduc(presentation=Presentation(), args=sys.argv + ['--no-bootstrap'])\n```\n\nSee [no-bootstrap.py](./examples/no-bootstrap.py).\n\n![no bootstrap](./screenshots/no-bootstrap.png)\n\n# with streamlit\nIn case you are into [streamlit](https://streamlit.io/) and want to use your app without a web browser, you can pass the option `--with-streamlit=YOUR-APP.py` or to see streamlit's demo you can use `--with-streamlit=hello`.\n\n💁  \u0026nbsp; viaduc \u003e= 2.0.3 is required for this feature\n\nHere is an example of the latter\n\n![streamlit hello](./screenshots/with-streamlit.png)\n\nSee [with-streamlit.py](./examples/with-streamlit.py).\n\nAlso included in these examples, a *columns* demo\n\n![streamlit columns](./screenshots/with-streamlit-columns.png)\n\n\nSee [with-streamlit-columns.py](./examples/with-streamlit-columns.py) and [columns.py](./examples/columns.py).\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdtmilano%2Fviaduc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdtmilano%2Fviaduc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdtmilano%2Fviaduc/lists"}