
Using websockets to easily build GUIs for Python programs - jsomers
https://gist.github.com/jsomers/d32dd3507e5406c56e47b4cd6f28c60e
======
userbinator
Keep that in mind "easily" can be good for you, but not for your users---

[https://blogs.msdn.microsoft.com/tonyschr/2004/03/30/drivers...](https://blogs.msdn.microsoft.com/tonyschr/2004/03/30/drivers-
a-new-kind-of-bloat/)

Even if it's just restricted to the local machine, any application that
seemingly should have nothing to do with the network is going to arouse plenty
of unneeded suspicion if it starts listening on a port or creating
connections. Several years ago I remember coming across an application written
in Python that did something similar, and its forums had users complaining
that their firewall had detected something or that it was otherwise not
working. I downloaded the executable, analysed it to discover the above, and
decided to find an alternative instead.

~~~
nine_k
Why would a firewall care about anything listening on localhost?

Why an app exposing itself to a local GUI process would listen on anything but
localhost?

I wonder if websockets can work on Unix domain sockets; it's the normal way
for non-websockets programs of a similar architecture.

~~~
nineteen999
Well Websockets sit atop HTTP last time I looked, what would be the point of
using HTTP over domain sockets? I must be missing something - I thought the
main reason so many protocols are implemented atop HTTP these days is because
traditionally many corporate firewalls block nearly everything else.

~~~
GauntletWizard
You still need the HTML served somewhere - running a HTTP server on domain
socket is a reasonable way of serving the that if it's at all dynamic, and
since you've already got the socket open why not reuse it and do websocket
over it too? Once the socket has transitioned, there's no overhead.

------
amasad
There's a Python library for this called "remi"[1]: REMote Interface library.
It's amazing how well it works. We've been playing around with it on repl.it
because we have a lot of users asking for GUI.

I recently built a TicTacToe game[2] in it in the fraction of the time it
would take me just to setup a webapp. It's pretty impressive and goes to show
how badly setup the web is for apps.

[1]:
[https://github.com/dddomodossola/remi](https://github.com/dddomodossola/remi)

[2]: [https://repl.it/talk/share/Tic-Tac-Toe-in-remi-a-cross-
platf...](https://repl.it/talk/share/Tic-Tac-Toe-in-remi-a-cross-platform-
Python-Remote-GUI-Library/6145)

~~~
nawgszy
>I recently built [a simple app built on a platform for building simple apps]
in the fraction of the time it would take me just to setup a webapp

Ok, sure

>It's pretty impressive and goes to show how badly setup the web is for apps

That conclusion really doesn't seem to follow for me. Someone else wrote a
library that does all of the setup work, and then you didn't have to do that
work, so you concluded that something else wasn't well set up?

~~~
amasad
Even if you pulled in angular or react it's still really hard to get something
like this going. Especially for novices, these frameworks suffer from
inversion of control and are pretty weird way to program. Once you get it it's
pretty powerful tho.

------
abhinai
This is an idea in the right direction! HTML5/Javascript/CSS stack is great
for making UI. So much effort has been poured into making this stack great
that it makes all the sense in the world to make it a standard GUI stack.

Now we need a good connector library so that we can program in any language of
our choice and use the web stack for seamless display. Web sockets are a good
start but we could do better.

------
renegadus
I've been working on something similar in Kotlin called
[http://kweb.io/](http://kweb.io/). It works but is still pre-1.0. You can
manipulate a remote DOM as if it was local to the server and attach event
listeners. Feedback welcome.

------
mangecoeur
This is pretty much what bokeh (
[https://bokeh.pydata.org/en/latest/](https://bokeh.pydata.org/en/latest/) )
does, there's Holoviews higher level plotting interfaces built on it too (
[http://holoviews.org/](http://holoviews.org/) )

~~~
devxpy
I feel like Bokeh is way too complicated for what it does.

I guess flutter has really spoiled me; my expectations from a UI framework are
just too damn high now xD

------
fromthestart
I've been something of a full stack developer for about 10 years now, my bread
and butter being Python and c#, with a background in c++. The handful of times
I've tried writing a web based UI for python and c# applications have been
exercises in frustration.

Web is a cancer on tech. A giant, bloated, broken mess, built emergently,
without any cohesiveness or vision. Simple applications come with hundreds of
external dependencies, many of which regularly release breaking updates. It is
simply impossible to consistently find up to date documentation on best usage
for many of these libraries because of the speed with which the space moves,
not necessarily toward anything good. Not to mention the incredibly dangerous
nature of such a loosly typed language like JavaScript.

In my opinion, the whole system needs to be burnt to the ground to make way
for something cleaner, safer, and more secure.

Then again, maybe I'm just biased by my preference for backend coding.

------
Per_Bothner
The DomTerm terminal emulator ([https://domterm.org](https://domterm.org))
also uses WebSockets. The "server" is written in C, and handles pttys, command
processing, help, and more. It uses libwebsockets
([https://libwebsockets.org/](https://libwebsockets.org/)) in the server.
JavaScript in the browser (or something browser-like such as Electron) handles
the GUI, including xterm/ansi escape sequences, menus, panes, buttons, etc.

------
rad_gruchalski
Is there anything preventing other applications from connecting to the web
socket server and messing up with the application state? Or is that possible
"by design"?

~~~
mic159
With websockets, it's actually up to the server to implement the cross origin
detection. The library used in this application does not implement any
protection.

So it's possible for any page on the net (eg evil.com) to connect to your
socket and exfiltrate any data.

Make sure all tabs are closed and never visit any sites with advertising on it
while this is running.

~~~
rad_gruchalski
But this example works and, I assume, is intended to work over localhost. How
would cross origin detection work in this case?

~~~
mic159
The websocket server needs to check the "Origin" header from the client. The
code then needs to know what is expected (eg localhost or 127.0.0.q). If the
origin header is something like "evil.xyz.com", then it needs to reject the
connection.

~~~
rad_gruchalski
Yes, I understand how origin verification is done. Nothing stops any other
local app to make make a WS connection to this app's server and pretend it is
making valid requests while, potentially, executing destructive actions or
stealing data.

I understand that the generic answer will be along the lines: "well, if you
have local access, you're never safe", but there is zero protection here.
Anything local can connect to it and impersonate the "front end".

------
pq0ak2nnd
Local UI?

electron + ES6 + html5 + no package installs + linux/macos/windows portable =
why bother with anything else?

~~~
craftyguy
Because some people don't want to distribute a full, buggy web browser with
every application they create.

~~~
pq0ak2nnd
Nice strawman argument, but you undermined your own argument:

Electron apps are not generic browsers that run random content from the web:
they are fully debug-able projects, and the developers have full control over
what is deployed.

You know, like ANY compiled project that is shipped as an .exe/.dmg.

Nice try though.

~~~
dang
On HN, please don't reply in the flamewar style, even if another comment is
annoying. It just leads to a downward spiral. Plus your refutation will be
much more convincing if it's simple, factual, and civil.

[https://news.ycombinator.com/newsguidelines.html](https://news.ycombinator.com/newsguidelines.html)

~~~
pq0ak2nnd
Dammit, I did it again. Sorry, thanks for calling me out. That's actually why
i -like- HN, so few flamewars.

------
dxxvi
My use case is the same, but my local ui is composed of angular + websocket.
It seems to me that when the browser (Firefox) tab containing the websocket is
inactive, the websocket doesn't run. Not sure if it's because of any bug in my
app or because of Firefox.

------
itronitron
I've recently started on this approach as well for hooking up a computational
backend in Java to D3 based visualizations in the browser. Netbeans has
several good introductory websocket examples that are a good starting point
for setting up the socket connection.

------
nurettin
Websockets are known to happily drop packages in bad connectivity situations.
I'd prefer something more robust like mqtt or stomp over ws.

~~~
rcfox
You have to try pretty hard to get bad connectivity to localhost though...

~~~
Silixon
There's a code golf problem in there.

My money's on sed and /etc/network/interfaces.

------
colek42
Be careful, web sockets require state which causes issues when scaling.

~~~
rcfox
The article is about making a local client in HTML/Javascript for a program
doing the heavy lifting in Python. I feel like your response is just a knee-
jerk reaction to seeing the work "websockets".

~~~
pdonis
For a local client, yes, scaling would not be a concern; there is one
websocket per client.

But this same method could be used for remote clients as well; I have a
websocket-based "dashboard" for a project I'm working on that will potentially
have to scale to thousands or more of remote clients. For a case like that,
scaling is indeed a concern.

For example, the very simple websocket server used in the article won't scale
well beyond a certain point because it spawns a new thread per client;
something like gevent (which is what my dashboard uses) will scale much
better. (Also the server in the example just exits on any exception; you need
more robust error handling for something that needs to handle remote clients.)

