9 ms·
Brython: an implementation of Python 3 running in the browser
- redfox2 5y agoI discovered this about a month ago, and it deserves to go up to the sky. The GitHub page is linked at the end. Some articles/content that relates to this ([4] is pretty cool and definitely check it out, so is [6]): [1] https://brython.info/static_doc/en/intro.html https://brython.info/static_doc/en/intro.html [2] https://towardsdatascience.com/run-python-code-on-websites-exploring-brython-83c43fb7ac5f https://towardsdatascience.com/run-python-code-on-websites-e... [3] https://stackabuse.com/an-introductory-guide-to-brython https://stackabuse.com/an-introductory-guide-to-brython [4] https://rayluo.github.io/brython-project-template/ https://rayluo.github.io/brython-project-template/ [5] https://github.com/rayluo/brip https://github.com/rayluo/brip [6] https://github.com/brython-dev/brython/wiki/Brython%20in%20the%20wild https://github.com/brython-dev/brython/wiki/Brython%20in%20t... [7] https://academy.cs.cmu.edu/ https://academy.cs.cmu.edu/ (CMU's academy website runs on Brython) Here's the GitHub page: https://github.com/brython-dev/brython/ https://github.com/brython-dev/brython/ And the Wiki, for examples -https://github.com/brython-dev/brython/wiki/Brython%20in%20the%20wild https://github.com/brython-dev/brython/wiki/Brython%20in%20t... If you're familiar with all that's going on with the source code or at least some parts of it, and have time to spare, do take the time out to contribute to this project. It's pretty insane what they're building. You can join their Google Groups forum here: https://groups.google.com/forum/?fromgroups=#!forum/brython https://groups.google.com/forum/?fromgroups=#!forum/brython
- rahimnathwani 5y agoFrom the site guidelines: "Show HN is for something you've made that other people can play with."
- dang 5y agoGreat post and great comment but please don't put "Show HN" on submissions like this. As rahimnathwani pointed out, that signifies that the project is your personal work. https://news.ycombinator.com/showhn.html https://news.ycombinator.com/showhn.html
- eatonphil 5y agoIt's a great project! I use it to power the Python interpreter for an in-browser backend of an app I'm working on. I wrote a bit more about my experience using it (and a guide for others) here: https://datastation.multiprocess.io/blog/2021-06-16-languages-you-can-run-in-the-browser.html https://datastation.multiprocess.io/blog/2021-06-16-language.... My biggest gripe is that so far I haven't been able to get good stacktraces out of it on errors. It also wraps all objects in custom Brython types that you have to rewrap in Python types to do stuff like get `.keys()` on JavaScript objects.
- redfox2 5y agoYeah. Like I said, it could really do with more contributors who can work on these issues and add keep adding features. rayluo who is a major contributor (developed brip to support using regular PyPi packages with brython), for example, works at Microsoft, and most probably does this in his spare time. More people like this can help bring Brython up even more, so there's a majority coverage for what JS can do, with Brython. Joining their Groups forum really shows you how much they're working and how much they're dedicated to this. This is only going to keep growing, if more devs and contributors hop onto the project even in their spare time.
- stuaxo 5y agoFantastic there is brip, I like to check in on Brython from time to time, and the lack of something like Brip was one reason I haven't been able to use it more. I guess being able to take the C parts of extensions and have them compiled with emscripten would be a logical step further.
- bmannix 5y agoBrython has been around a long time, at least 7 or 8 years. While I love Python and I'm not a particularly big JS fan, I feel like if Brython didn't really make a dent before ES6 and TypeScript, then it will be really hard to do it now. Does anyone know what the biggest Brython project/app is? Can we see it in production other than a simple hello world?
- redfox2 5y agoYeah, it has been there for quite some time, but has really started getting off the ground in about mid-late 2019 which is strange, since like you mentioned, the advent of TS. But slowly a lot of interest has been brewing over it, it's growing faster than ever, and has been attracting users/contributors a LOT only since the start of last year. https://academy.cs.cmu.edu/ https://academy.cs.cmu.edu/ This is Carnegie Mellon's academy website, running on Brython. See the Brython Wiki page on their GitHub, they got a list there.
- rossdavidh 5y agoPython was itself around for years, predating PHP by several years even, before it took off; PHP got big much quicker. Ruby was around for several years before Rails helped it take off outside of Japan. So, that doesn't mean Brython will take off now, but it does at least suggest it's possible.
- peterthehacker 5y agoThis project will transpile python code to JavaScript code instead of something WASM-based, like pyodide [0]. What are there the performance and usability consequences of each approach (py to js vs. py to wasm)? [0] https://github.com/pyodide/pyodide https://github.com/pyodide/pyodide
- redfox2 5y agoPyodide still involves writing JS (literally). Brython just needs you to know the simple basics of JS (since the syntax is similar), and you're good to go with pure Python from there on.
- meredydd 5y ago(Disclosure: I'm a maintainer of https://skulpt.org https://skulpt.org, another Python-in-the-browser runtime, as well as a Python web framework/dev environment that uses it, https://anvil.works https://anvil.works) The short answer is that basically all the current Python-in-the-browser implementations (and there are a few!) predate widespread support of WASM. But even once WASM is a thing, you get a choice between: 1. Compile a full Python environment to WASM (via Emscripten), and load it in the browser. This is what Pyodide does - it lets you use a boatload of existing libraries, but you have to download and bytecode-compile the world to do it. On my machine Pyodide takes 10+ seconds to load. (PyPy.js, which predated WASM, was even worse!) The upside is that you can run more or less anything from the existing ecosystem. This tradeoff is great for Pyodide's use case (notebooks in the browser) - long load times are OK, but you really want those numerical libraries. 2. Ship a lightweight, JS-based runtime. This is what Brython and Skulpt do. You'll pay in performance (compilation overhead, interpretation, and the overhead of preserving Python rather than JS semantics for things like attribute lookup), but your payload will be much smaller (Skulpt is ~250kb on the wire), and you'll be interactive much faster. We chose Skulpt for the client side of our full-stack Python-in-the browser platform, Anvil (https://anvil.works https://anvil.works). Unfortunately, you'll be amazed how many Python libraries don't work in this environment. Most "normal" Python code is pretty straightforward, but dig into any big library and you'll find a native dependency really fast. (Skulpt's original 'datetime' implementation was ported from PyPy, and even that depended on native code. In PyPy, the interpreter written in nearly pure Python!) In something like Anvil, this is no biggie, because you can call server-side code with one function call, but it could be a nasty surprise in a traditional app. 3. Compile "not quite Python" to JS (this is what Transcrypt does). This more or less transliterates Python code to the nearest Javascript equivalent. This produces really compact, JIT-friendly JS code, but it will bite you the moment you rely on Python semantics that aren't there in JS. Worse, you're now neither fish nor fowl: If you have a question, you can't consult StackOverflow for Javascript answers, but half the Python answers won't work for you. (To my knowledge, nobody has yet attempted the "WASM + lightweight runtime" approach. We've occasionally discussed it, but it would be hard to retrofit to an existing project, because you'd want to move a-lot-but-not-all of the runtime into WASM to avoid being hammered by the JS-WASM bridge, and building a Python runtime from scratch is a heavy lift...all for a performance boost you might just get from generating faster JS.) Before the pandemic, a colleague of mine wrote an in-depth comparison of six popular Python-in-the-browser implementations, with sample code and a discussion of their trade-offs, with a lot more detail than I can fit into this comment: https://anvil.works/blog/python-in-the-browser-talk https://anvil.works/blog/python-in-the-browser-talk
- miohtama 5y agoSee also https://starboard.gg/ https://starboard.gg/ https://github.com/pyodide/pyodide https://github.com/pyodide/pyodide They offer pure client-side Jupyter notebooks. Wasm compiled, no cloud servers needed.
- redfox2 5y agoStarboard is completely different from Brython, although it is cool. As for pyodide, it still involves proper working knowledge and literal implemetation of JS - Brython just needs you to know the bare basics, the rest is just pure Python
- deven88 5y agoJupyterLite[1] can also be added to this list. [1] https://github.com/jupyterlite/jupyterlite https://github.com/jupyterlite/jupyterlite
- smetsjp 5y agoConsider also https://basthon.fr/ https://basthon.fr/ which is used for education
- redfox2 5y agoPlease have a look at the last comment for all related content links - implementation, projects, doc etc.
- redfox2 5y agohttps://github.com/rayluo/brip https://github.com/rayluo/brip This brings standard PyPi packages to Brython
- bluedays 5y agoI'm hoping web assembly eventually completely replaces javascript. It would be amazing if we could theoretically compile any language down to be browser compatible.
- gchamonlive 5y agoThis is something that I wanted to hear more from people invested in frontend. I work exclusively as a DevOps/DataOps/Backend engineer and have little contact with stuff running in the browser. I did, however, work with AngularJS back in the day, and although the framework itself didn't lend itself to nicely to productivity and simplicity, I believe that what I found most confusing was how unergonomic the browser environment itself was, from not dealing with a filesystem (and thus having to resort to tricks like transpiling and bundling) to the rather terse API, not having for instance a SQLite natively and not being able to enable something like this without bringing copious amounts of megabytes of extra javascript deps... Is the browser environment becoming more dev-friendly with the adoption of WebAssembly? I ask that because, in my opinion, if the browser itself doesn't evolve, it doesn't matter which language we use, interacting with it will still be a hassle. All in all, it feels like the browser advanced a lot in technology for optimization and resource management, but not so much in becoming more user-friendly to the developer.
- Tade0 5y ago> not having for instance a SQLite natively We had this for a brief moment in the form of Web SQL, but as a rule web standards require independent implementations to be developed, and all the implementors were using SQLite under the hood. The current alternative is IndexedDB - for better or worse. > Is the browser environment becoming more dev-friendly with the adoption of WebAssembly? Yes, but that doesn't have much to do with WebAssembly. JavaScript as a language evolved, we have TypeScript with its flexible and expressive type system and bundling is becoming less of a pain with each consecutive framework re-written using ES2015 modules(and loaded via e.g. Snowpack https://www.snowpack.dev/ https://www.snowpack.dev/). WebAssembly is helpful when there's a need for some heavy lifting - e.g. in software codecs, but that's still a niche application.
- frou_dh 5y agoI found the following article and associated presentation to be a great overview of the options for this kind of thing: https://anvil.works/blog/python-in-the-browser-talk https://anvil.works/blog/python-in-the-browser-talk Transcrypt's (https://github.com/QQuick/Transcrypt https://github.com/QQuick/Transcrypt) approach made the most sense for me. The project seems to be a heroic effort by one guy.
- wilsonfiifi 5y agoYeah Transcrypt is interesting! There’s even a book that shows you how to use it with React [0]. Personally I think mithril.js would be a better fit than React because JSX isn’t supported. [0] http://www.transcrypt.org/pdfs/rtptutorial.pdf http://www.transcrypt.org/pdfs/rtptutorial.pdf
- dang 5y agoPast related threads: Brython: Python in the Browser - https://news.ycombinator.com/item?id=26781461 https://news.ycombinator.com/item?id=26781461 - April 2021 (1 comment) Brython – A Python 3 implementation for client-side web programming - https://news.ycombinator.com/item?id=23746067 https://news.ycombinator.com/item?id=23746067 - July 2020 (214 comments) Brython – Client-side web programming in Python - https://news.ycombinator.com/item?id=15914805 https://news.ycombinator.com/item?id=15914805 - Dec 2017 (1 comment) Brython – A Python 3 implementation for client-side web programming - https://news.ycombinator.com/item?id=9792536 https://news.ycombinator.com/item?id=9792536 - June 2015 (60 comments) A Python 3 implementation for client-side web programming - https://news.ycombinator.com/item?id=5807059 https://news.ycombinator.com/item?id=5807059 - June 2013 (117 comments) Brython, Python in the browser - https://news.ycombinator.com/item?id=5133047 https://news.ycombinator.com/item?id=5133047 - Jan 2013 (65 comments) Brython - Python to Javascript translator - https://news.ycombinator.com/item?id=4923530 https://news.ycombinator.com/item?id=4923530 - Dec 2012 (68 comments) (That last thread and the June 2013 thread are good for anyone worried that HN has become more negative lately...)
- redfox2 5y agoWow I wasn't aware of those. But apart from the 2020 post, the others are pre-TS. Brython seems to have come a long way since TS came in
- cyanydeez 5y agoid say they wont make it till they get into webassembly. especially if their own website runs brython cause its a poor standard bearer
- dolmen 5y agotext/javascript or application/javascript? And so, text/python or application/python?
- eatonphil 5y agoAfter reading this thread and being frustrated by the pretty useless exceptions Brython gives, I switched over to using Pyodide (which took 5 minutes, both libraries are pretty simple). There is a huge improvement on usability with Pyodide. It doesn't wrap JavaScript objects in lots of additional structures like Brython does and it actually gives stack traces that end in user code! I've only been exploring Pyodide for the 10 minutes since I switched over and discovered these two pieces. I'm curious if there's a good reason to use Brython over Pyodide. Edit: Ok one weird thing with Pyodide is that I cannot use subscripts with JavaScript objects in Python. I have to use dot accessors. So not `row["age"]` but `row.age`. Kinda weird, not too Pythonic.
- yboris 5y agoThank you for sharing Pyodide. Please consider adding a link to things like this. Cheers! https://github.com/pyodide/pyodide https://github.com/pyodide/pyodide
- Doxin 5y agoPyodide is rather larger than brython. It's essentially a full python interpreter and stdlib compiled to wasm, whereas brython is a reimplementation of python directly in javascript.
- d33d33 5y ago4MB for pure brython_stdlib.js ? :(
- goffi 5y agothis is the default stdlib with everything, you have tools to transpile only what you need and make it much smaller: https://www.brython.info/static_doc/en/import.html https://www.brython.info/static_doc/en/import.html. Also after first launch it is stored in indexedDB, which speed up import the following times.
- anticristi 5y agoCan I hijack this post for a nit-pick? While I love Python and feel most comfortable with it, it always bothered me that it make a distinction between accessing a dictionary item and accessing an object member. E.g.: a["getStuff"]() # call the "getStuff" function of dictionary "a" b.getStuff() # call the "getStuff" method of object "b" In contrast, in JavaScript, these two are equivalant. a["getStuff"]() a.getStuff() I find JavaScript more dev-friendly. Any idea why Python didn't opt for the same approach? Would make sense to me, since "everything is a dictionary/object".
- rhacker 5y agoI ran into this recently while learning it... confused me for a long time because I'm typically writing TS for my day job.
- supervisual 5y agoI would argue opposite, For a long time JS had this issue where when you iterated on keys in a dictionary you had to ensure you were skipping methods etc via .hasOwnProperty check. Python by making clear distinction between contents and functionality avoids this.
- neoncontrails 5y agoHighly recommend looking into Munch, "a dictionary that supports attribute-style access, a la JavaScript." https://github.com/Infinidat/munch https://github.com/Infinidat/munch In theory, implementing attribute-style access on user-defined Python object is just a matter of overriding its __(get|set)attr__ methods, for example: In [1]: import collections In [2]: class DotDict(collections.UserDict): 2 def __getattr__(self, k): 3 try: 4 return self.__getitem__(k) 5 except: 6 return super().__getattribute__(k) 7 def __setattr__(self, k, v): 8 try: 9 self.__setitem__(k, v) 10 except Exception as e: 11 super().__setattr__(k,v) In [3]: d = DotDict({'a': 'b', 'c': [1,2,3], 'square': lambda x: x*x}) In [4]: d.square(4) Out[4]: 16 In [5]: d Out[5]: {'a': 'b', 'c': [1, 2, 3], 'square': <function <lambda> at 0x7f9ef5d5b0d0>} In [6]: import datetime In [7]: d.created_at = datetime.datetime.now() In [8]: d Out[8]: {'a': 'b', 'c': [1, 2, 3], 'square': <function <lambda> at 0x7f9ef5d5b0d0>, 'created_at': datetime.datetime(2021, 7, 19, 19, 42, 32, 341393)} In practice, this can lead to headaches. Take, for example, what happens if we try to serialize `d` (which has a non-serializable lambda function in its keys) using the built-in pickle module: In [9]: import pickle In [10]: pickle.dumps(d) Traceback (most recent call last): File "<stdin>", line 1, in <module> _pickle.PicklingError: Can't pickle <class 'DotDict'>: attribute lookup DotDict on builtins failed Thankfully there's a third-party library called cloudpickle which can serialize just about any python object to bytes -- even including the user-defined DotDict class (!): In [12]: deserialized_d = cloudpickle.loads(cloudpickle.dumps(d)) In [13]: deserialized_d Out[13]: {'a': 'b', 'c': [1, 2, 3], 'square': <function <lambda> at 0x7f9ef650fee0>, 'created_at': datetime.datetime(2021, 7, 19, 19, 42, 32, 341393)} Since the entire class definition is serialized along with the instance, the deserialized copy preserves the object's attribute-style interface as before: In [14]: deserialized_d.created_at.strftime("%c") Out[14]: 'Mon Jul 19 19:42:32 2021' But I recommend Munch over rolling your own because subclassing `dict` is fraught with a surprising number of edge cases.
- tpfour 5y agoThere's also Codeboot: https://codeboot.org/py/ https://codeboot.org/py/ which offers a single stepper.