Pynecone – Performant, customizable web apps in pure Python
pynecone.io
pynecone.io
The app state is just a class. State updates are methods in the class. And the UI is a reflection of the state.
It's rare to see this sort of clarity on a landing page. Even more impressed to see that it carried over into the documentation, which is excellent.
I've been a fan of the plotly/Dash framework, but this looks like an exciting alternative, feeling more immediately accessible without some of the quirks (like the pragmatic but weird-feeling 12 virtual columns, for example). I look forward to re-implementing some existing projects for comparison.
We've been using Pynecone for a bit and are coming up against some problems.
For example trying to write a wrapper for AG Grid there is no way to pass a custom class attribute so you can't style the output with a theme.
Serializing state together with some code that operates on it may be doable but sounds either complicated or brittle.
Dash had some amazing ideas and architecture, but suffered from too little hardcore developers working on the repo. Pynecone looks a whole lot like it was heavily inspired by Dash, but re-architected with the lessons of Dash power users.
I find the project incredibly impressive and well thought out. I cringe at transpilation into Next.js, but the target code is actually extremely clean and easy to follow/read/debug. Kudos to the team.
You can see it in their demo:
https://pynecone.io/docs/getting-started/introduction
The counter increment should be instantaneous, but instead, it goes through websocket, calls a python function on the server, and comes back.
In which case the difference between this and django+htmx is not huge: mostly you get widgets in pure Python, and websocket is not experimental.
Not sure it's worth giving up the whole django and htmx community to get locked in their widget set.
I'm not saying this to hit on the project, I do think pycone is a cool idea and it's nice to see people trying to make web dev more accessible.
But I want people to know what they are signing for.
The reason I gave up on Pynecone is that these things transpile to other already high abstraction frameworks like React. This is all good and well until something goes wrong and you now have more layers to troubleshoot. Another huge downside to this approach is that now I have to deal with two sets of build and deployment tools: python and node. And given that I have few fond memories of the node tool set from previous project, I refuse to incur this complexity unless it's absolutely unavoidable.
If someone actually built something like Pynecone that targeted html/dom/js directly instead of wrapping node/react/next I would be the first to hop on the bandwagon. Because the API is very good but the way that sausage is made ain't pretty.
This might not be what you were imagining, but I think this js more or less what we built at https://anvil.works (I'm a founder).
Anvil's UI toolkit is built "straight on the DOM", and it's shaped like Python objects rather than going via some other React-y abstraction. This is possible because we expose the difference between client and server code - even though they're both in Python (transpiled as necessary), and you can make mostly-transparent function calls from one to the other. Contrast Pynecone, where the UI is "puppeteered" from the back end over a websocket, so every update is a round-trip. And of course, because you're writing in-browser code, the HTML/JS interop is pretty straightforward (in fact, you can import JS objects right into Python code).
There are downsides to our approach, of course - the developer needs to understand the difference between code in the browser and on the server, which can be a hurdle, and it's really neat that Pynecone apps can be a single Python file - but you don't have to round-trip every UI update to the server, and we've seen people have scaled up to some pretty big apps with Anvil!
We have also had some users build some fairly large Pynecone apps including our whole website built in our own framework.
Aside: I get grouchy about the term "low-code", mostly because it's almost always a lie (you're going to need the code, and most "low-code" systems just hide how much that's going to hurt - which is why we put the code front and centre), and it causes people to lump Anvil in with, eg, Retool rather than, eg, Pynecone/Viola/Beeware...but this is definitely getting off topic ;)
Interested to hear how your scale-up/B2C users deal with the round-trip delays - I guess that's less of a deal with websites than interactive apps? (Should probably have grabbed you at PyCon to ask, but we were both pinned down pretty hard! I did manage to wave at you though, I think...)
Will be improved in the future as we start to offload client side actions with wasm, starting to do this but the python wasm ecosystem is still maturing
I didn't know about either Pynecone or Anvil, and have a side project for a friend that might be well suited to one/both. So I'm both more enlightened on options, and more predisposed to both given the positive dialogue here. Thanks for both.
Had good experience with them, works out of the box and UI is very responsive.
But, be advised that it's not production ready and quite unstable yet.
this week my deploy script was broken because version 0.1.26 was un-released. Which broke my docker file build with pinned dependencies.
The file upload component was changed a few times so my UI with file uploads silently stopped working.
I had some issues when state binding input components. Which lead to the backspace key no longer working inside a text box.
The websocket state updates can make the ui feel sluggish.
Despite all that, I love this framework and will continue tinkering with it. It hope it can grow to maturity before people lose interest!
But it's interesting to see that Python is able to advance so much in this direction; I hope it will continue.
Not seeing any network requests so I can't imagine why it would be so laggy.
All user state is stored on the server. Behind the scenes, events are sent as API calls to update the state on the server. The state delta is then sent to the frontend, which updates the UI to reflect the new state.
(very interesting project nonetheless!)
We’re working to offload more logic to the client in the for purely UI operations like you mention, and in the future want to leverage wasm once it’s more mature.
1. Looks like you posted this comment pretty close to when this was posted on HN. It's possible the server was more loaded, as I tried it myself and it wasn't very laggy (though there was a delay, it wasn't nearly the one second you experienced).
2. I copied the example code and ran it locally, and the latency is no worse than, say, an electron app. Better than most of them, to be honest.
Likely this was related to server load or network latency or both, because the core functionality seems pretty lag-free.
I assume what is meant is that having a single language is allowing people who know Python to work "full stack". I don't believe in that argument
1. JS has brought you that since Node.
2. You can transpile Python to JS, the fact that it's the same language is only a marginal gain. Certainly you'll skip the few quirks of JS, but front end dev is arguably another paradigm from back-end, using the same language is not the biggest hurdle to learning front end dev.
3. This is proposing to learn a specific and niche framework that will probably not used in your next project or job, rather than spending similar time learning the proper, mainstream tools of front-end.
I have this personal side project which in the wee days of me career I wrote in CherryPy; I love Python and have been exploring frameworks. I didn't really get a lot written in it because eventually I realized the project is frontend-heavy and I was never in the mood to write the JS for it.
Recently I had the need for this side project again so I thought, why not rewrite it using a framework that would avoid me having to deal with the madness that is the Node.js ecosystem? For one reason or another I ended up with Vaadin.
I've nothing against Java. If it works, it works. I got over the initial bump that is Spring and I got a "core" backend running, with tests too. My grievance with it is the usual Java fault of needing to write a lot of boilerplate just to shoehorn my app into the framework's philosophy. (Man, part of my initial consideration was even the tooling, editor, autocomplete, and all that, because damn me if I try Spring without these modern conveniences!)
And this...this is all the things that attracted me to Vaadin---but in Python! I am so tempted to rewrite again. My experience and your documentation should make this a two hour job, right? Right?
("Haha, I'm in danger," my side project chuckles like Ralph Wiggum, staring blankly at https://www.commitstrip.com/en/2014/11/25/west-side-project-...)
Python has a place in scripting
Because you can, does not mean you should, build full applications with it
It is a colossal waste of resources. It leads to genuine problems as it gets bigger that you will only find when you have considerable sunk costs.
This is a terrible idea, it was a terrible idea in 1995 when people did this with Perl, it is a terrible idea now
Use Python for what it is good at, not for what it is dreadful at
No, get the idea working first. Talk to customers... pivot... repeat. After finding a fit and portions are too slow look into Cython or offload to services in golang, etc.
This looks like a great productivity booster.
It amplifies all the bad desicions ever made in software
Because you can does not mean you should,
• A large memory foot print
▪ Inefficient execution
That's two out of the top of my head
I have been badly burnt by Mailman3, pure Python, pretty front end, 2G needed to install it. That cost me real money. The difference between a cheap, and a very cheap, VPS
Wuh?
There are a lot of success stories, big and small, with apps built with Python, Ruby, PHP.
So, if you are already familiar with the language and build something now, go with it.
On the other hand, also be aware of the other side of the coin.
It'll probably be much more productive to build long lived applications in a better language more suited to it.
I've built 30+ apps and wrote hundreds of thousands of lines of code with Python for ~10 years.
I've switched to C#/.NET now, and couldn't be happier. It allows me to almost all the dynamic things I had done in Python, in a type safe way, thus making everything easier.
I wish the modern, cross-platform .NET existing when I've started my journey in Python.
However whenever I see such good abstraction I always worry that when my project gets big and complicated there will be things which are not possible to do, and at that point switching will be super expensive.
I suppose this is not expected
Edit: nevermind, its expected in slow connection due to a client-erver round-trip
Sadly it's apparently incompatible with SQLAlchemy 2.0, so I can't use it.