Brython (Browser Python) is an implementation of Python 3 running in the browser

Overview

brython

Brython (Browser Python) is an implementation of Python 3 running in the browser, with an interface to the DOM elements and events.

Here is a simple example of an HTML page running Python:

    <html>

        <head>
            <script type="text/javascript" src="/path/to/brython.js"></script>
        </head>

        <body onload="brython()">

            <script type="text/python">
            from browser import document, alert

            def echo(event):
                alert(document["zone"].value)

            document["mybutton"].bind("click", echo)
            </script>

            <input id="zone"><button id="mybutton">click !</button>

        </body>

    </html>

To use Brython, all there is to do is:

  1. Load the script brython.js.
  2. Run the function brython() on page load, like <body onload="brython()">.
  3. Write Python code inside tags <script type="text/python">.

Main features

Brython supports the syntax of Python 3, including comprehensions, generators, metaclasses, imports, etc. and many modules of the CPython distribution.

Since version 3.8.0, Brython implements the Python version of the same major / minor version number.

It includes libraries to interact with DOM elements and events, and with existing Javascript libraries such as jQuery, D3, Highcharts, Raphael etc. It supports the latest specs of HTML5/CSS3, and can use CSS Frameworks like Bootstrap3, LESS, SASS etc.

Getting started

Zero install !

The most simple way to get started, without anything to install, is to use the distribution available online through jsDelivr. You can choose the latest stable release :

<script type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/[email protected]/brython.min.js">
</script>

The previous code will allow you to use raw python code, but if you import modules from the standard library you have to load a single javascript file with the available stdlib:

<script type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/[email protected]/brython_stdlib.js">
</script>

jsDelivr supports version ranges, so if you want the latest of the 3.9.x versions:

<script type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/[email protected]/brython.min.js">
</script>
<script type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/[email protected]/brython_stdlib.js">
</script>

or the latest of the 3.x.y versions:

<script type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js">
</script>
<script type="text/javascript"
    src="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js">
</script>

If you want to use the latest development version, you can load these scripts instead:

<script src="https://raw.githack.com/brython-dev/brython/master/www/src/brython.js"></script>
<script src="https://raw.githack.com/brython-dev/brython/master/www/src/brython_stdlib.js"></script>

Local install

To install Brython locally, if you have a CPython distribution with pip :

pip install brython

then create a new directory and run

brython-cli --install

or by loading the latest version of the Brython zip file from the releases page.

In both cases, the distribution includes brython.js (the core Brython engine) and brython_stdlib.js (a bundle of all the files in the standard distribution).

It also includes the page demo.html that shows a few examples of how you can interact with a web page using Python as the scripting language : create new elements, access and modify existing elements, create graphics, animations, send Ajax requests, etc.

Test Brython online

If you want to test Brython online you can visit the following:

Gallery of examples

There is a gallery of examples where you can see simple and advanced examples using vanilla Brython or interacting with Javascript libraries.

Documentation

You can start by reading the official Brython tutorial.

Full documentation is available on the official site. You can read the docs in English, French and Spanish.

The most updated docs usually are the English and French versions so if you want to be up-to-date, please, use these versions.

Curious about how Brython works ?

A tutorial explains how to build Android applications with Brython.

Community (questions, feedback, issues, new features, ...)

You can subscribe and post to the mailing list.

If you find a bug/issue or do you want to see a new feature in Brython, please, open a new issue.

If you want to contribute to Brython, please read the contributing guide.

Thank you

  • BrowserStack for providing an access to their online testing environment.
Comments
  • documentation on how to package libraries for brython

    documentation on how to package libraries for brython

    If I want to use a package from PyPI in Brython, what do I do? Right now I am manually adding packages or symlinks to a fork of brython, but it would be nice to be able to use Pip for this.

    Until Brython has Pip (or something like it), at least some documentation around conventions for how to write and use libraries would be nice.

    opened by glyph 42
  • Brython dict() can't handle nested JS Object Literals (dict's)

    Brython dict() can't handle nested JS Object Literals (dict's)

    Hello,

    I've attempted correcting this in the source, but I'm too new to Brython to make sure I'm doing a good job - I see the creation of a dict requires issues with future updates to the JSObj, etc.

    The problem is simple to replicate. Assuming an Object Literal from a function like this:

    do_list = function(){
        return {1:'one', 2:'two', 3:'three', 4:{ 'big_bad_wolf':1 }}
    }
    

    in Brython:

    js_dict = window.do_list() print(js_dict)

    I see in line 304 of py_dict.js looping across the object, assigning the value to the new dict. Everything is fine until it hits item 4, where I see it assigns an Object to the value, so it's packing an un-wrapped JS Object into the brython dict.

    The error is expressed as:

    Uncaught Error: TypeError: Cannot read property 'mro' of undefined

    .. depending on how I'm accessing the dict, because it can't find what it for that object.

    If someone with more skill with Brython could fix this for me, I'd appreciate it.

    Thanks.

    opened by cforger 37
  • nested scopes are overwritten when the enclosing function is called again

    nested scopes are overwritten when the enclosing function is called again

    To start, let me say that I know that this is a terrible bug report; I tried to get a minimal reproducing case and I was unable to do so. I'm reporting it in the hopes that someone who knows brython's internals better than I do might be able to point me in the right direction to reproduce it.

    I'm working on a Brython-compatible port of Twisted's Deferred, here: https://github.com/glyph/deferred/tree/brython. This is in service of creating a client-side framework sort sharing idioms with Twisted, here: https://github.com/glyph/brytly.

    The problem is here:

    https://github.com/glyph/brytly/blob/master/brytly/phantestic.py#L29

    Basically, I have the same lambda callback either way; but if I define it in the arg list of addBoth, then it appears self takes on the wrong value in its closure. You can see that if you load up test.html in a browser (after symlinking both these projects into site-packages in a brython checkout, which is the only way I've figured out how to "install" stuff, hence my filing of #119) with the assigned-to-a-variable lambda, the test run completes, but with the defined-in-the-arg-list lambda, it gets stuck and runs SuiteRun.keepGoing for MyTest twice, instead of properly running it once for MyTest and then once for the Root suite generated by the framework.

    Again, sorry I couldn't make this example more minimal; it seems to be a very tricky failure mode.

    By the way, I should note that Brython has come a long way in the last year - when I first took a look at doing this it would have been basically impossible. So thanks a lot for all the hard work!

    opened by glyph 35
  • Perfomance Issue

    Perfomance Issue

    I have tested the simple code with Brython and Javascript:

    <!doctype html>
    <html>
        <head>
            <meta charset="utf-8">
            <script src="brython.js"></script>
            <script src="brython_modules.js"></script>
        </head>
    
        <body onload="brython(1)">
            <script type="text/python">
                from browser import console
    
                console.time('python')
                list = []
                i = 0
                while i < 100000:
                    list.append(i)
                    i += 1
                console.timeEnd('python')
            </script>
            <script>
                console.time('javascript')
                var list = [];
                for (var i = 0; i <= 100000; i++) {
                    list.push(i);
                }
                console.timeEnd('javascript')
            </script>
            <div id="root"></div>
        </body>
    </html>
    

    And the results in Chrome are the following:

    javascript: 2.59716796875ms
    brython.js:5316 using indexedDB for stdlib modules cache
    brython.js:9073 python: 289.85302734375ms
    

    Profiling from Chrome is attached:

    Profile-20200617T123405.zip

    Also according the report Brython seems to be only 3 times slower ... strange ...

    Seems like it should be investigated as time will be ...

    opened by redradist 33
  • including source maps, to allow for debugging python with in-browser debugger

    including source maps, to allow for debugging python with in-browser debugger

    I've been trying to debug #121 and it has been very challenging to do so because it's not possible to get a JavaScript debugger to set a breakpoint in a Python file.

    If you could easily do ahead-of-time compilation (emitting, let's say, .pyc.js files next to the .py files), it would at least be possible to set breakpoints in the generated JavaScript source. Even better, with pre-generated source files we could potentially have source maps which would facilitate actually debugging Python code with a JavaScript debugger.

    Is this already possible? I searched the documentation, but maybe I'm just not looking for the right string.

    opened by glyph 28
  • Research and Implement simplified way to add Brython to a page

    Research and Implement simplified way to add Brython to a page

    • Research and Implement a simplified way to add Brython to a page.
    • 1 line added to add Brython to a existing page. K.I.S.S.
    • Move the onLoad somewhere?, bind a callback?, on url parameter?, something else?
    • Update Docs to reflect that change. Add Async and Defer script tag attributes to Docs?

    Context: https://github.com/brython-dev/brython/commit/5c5c44e905da4560712118f630ad5566a65fbb72#commitcomment-8631942

    https://github.com/brython-dev/brython/commit/e770f9e55b1a8647e532295a300b59dd712852a5

    :pensive:

    opened by ghost 25
  • The dictionary implementation is painfully slow

    The dictionary implementation is painfully slow

    The performance is really suboptimal. Looking at the code, it quickly becomes clear why: To find an object, the whole dictionary is searched in a loop (i.e. https://github.com/brython-dev/brython/blob/e1dc7b4575280dd7a00e3012890c7c2533d48e32/src/py_dict.js#L68). I expected to find some sort of hash map. Don't python objects have hash functions or the like? I don't know, but I guess it would be possible to find something. :-) Anyhow - I converted the hash maps into arrays to solve the performance issues and am very happy with Brython, it is a great project. To who it may concern: Thank you for all the hard work and making it available open source!

    enhancement help wanted in progress 
    opened by Pfiver 21
  • possible silent overflow of larger ints

    possible silent overflow of larger ints

    Hi, I only recently tested Brython and am pretty amazed - thanks for providing this implementation!

    While experimentig in the interactive mode, I noticed an unexpected behaviour for larger ints, which may indicate silent overflows; floats are more sensible in this case. cf. the following results (using Opera 27 dev on win 7):

    Brython 3.0.0 on Netscape 5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2188.2 Safari/537.36 OPR/27.0.1683.0 (Edition developer)

    [(x,2**x) for x in range(68,80)] [(68, 295147905179352830000), (69, 590295810358705700000), (70, 1), (71, 2), (72, 4), (73, 9), (74, 1), (75, 3), (76, 7), (77, 1), (78, 3), (79, 6)] [(x,2.0**x) for x in range(68,80)] [(68, 295147905179352830000.0), (69, 590295810358705700000.0), (70, 1.1805916207174113e+21), (71, 2.3611832414348226e+21), (72, 4.722366482869645e+21), (73, 9.44473296573929e+21), (74, 1.888946593147858e+22), (75, 3.777893186295716e+22), (76, 7.555786372591432e+22), (77, 1.5111572745182865e+23), (78, 3.022314549036573e+23), (79, 6.044629098073146e+23)]

    Some oddities also appear at the bounds of the float type - the integers start to appear as NaNs:

    [(x,2**x) for x in range(1020,1030)] [(1020, 1), (1021, 2), (1022, 4), (1023, 8), (1024, NaN), (1025, NaN), (1026, NaN), (1027, NaN), (1028, NaN), (1029, NaN)] [(x,2.0**x) for x in range(1020,1030)] [(1020, 1.1235582092889474e+307), (1021, 2.247116418577895e+307), (1022, 4.49423283715579e+307), (1023, 8.98846567431158e+307), (1024, inf), (1025, inf), (1026, inf), (1027, inf), (1028, inf), (1029, inf)]

    I currently don't have usecases for such calculations in Brython, but I'd prefer a more transparent handling of these cases; probably raising an exception (as the generally unlimited precission of int in python probably isn't available in the underlying javascript).

    regards, vbr

    bug help wanted 
    opened by vbr 20
  • code.interact() does not work right

    code.interact() does not work right

    And neither does import pdb; pdb.set_trace(), which is what I really wanted, but I get further with interact().

    I put

    import code
    code.interact()
    

    in the <script> tag. On page load, I get the expected >>> prompt (in a pop up, but OK, it's a web page). If I give it a simple input, like 1, I get another >>> prompt, as expected, but the 1 doesn't seem to have printed anywhere, not even in the browser developer tools' JS console, which is where you see the output of a print call, even though the interact banner printed to the console.

     Python 3.3.0 (default, 2018-04-17 08:26:29.400878) 
    [Javascript 1.5] on Brython on brython
    Type "help", "copyright", "credits" or "license" for more information.
    (InteractiveConsole)
    

    However, entering print(1) at the pop-up prompt does produce output in the JS console.

    Also, multi-line inputs completely crash. If I enter def foo(): I expect the next prompt to be ... so I can do the next line, but this just crashes. I don't get another prompt.

    If Brython's aim is to be a drop-in replacement for client-side JavaScript, we need some kind of interactive console. Python's just not the same without it. It seems like this should be possible, considering that a bookmarklet like Firebug Lite could inject developer tools in the web page and we already have a demo console. It doesn't seem like much of a stretch to have something like IDLE embedded in a bookmarklet, but pdb.set_trace() didn't work right in the demo console either, so I don't know.

    opened by gilch 19
  • import is very slow

    import is very slow

    I tried to report this on #123 along with a whole bunch of other related issues, but I think it would be good to have a separate issue that calls out this one specific thing.

    Importing modules on brython is slow. Unacceptably slow, in my opinion, because one of the major advantages of Python over JS for in-browser development is the very nice module system, and brython punishes you for using it with very slow import times.

    The solution proposed on #123 is to implement a way to pre-generate .pyc.js files, since the transpiler is a clear bottleneck in import; but that is a proposed solution, so this issue is specifically for the problem of import being slow, if others wish to address it some other way.

    opened by glyph 19
  • Some general questions/suggestions

    Some general questions/suggestions

    Hi, great and interesting project, just few questions/suggestions: 1- Why you don't use the default python tokenizer module converted to Javascript because it is much simpler and battle tested, the current implementation is a bit bloated, plus there are many bugs which I can of course contribute/report (mainly related with error tokens and the start/end range). 2- Why not using ANTLR to generate the parse tree (ANTLR python grammar is already defined and battle tested and the Javascript or python runtimes are also available+ possibility to interface any python version like 2.x which is out the scope of this project + possibility to get inspired from other projects like Jython) and thus the whole project will consist of a visitor which will have all the transform methods migrated to. 3- Implementing 2 will give an easier out-of-the-box implementation of the ast module which is unimplemented currently. 4- Why not using a safer typed language like Typescript and divide the transpiler into smaller chunks using better OOP paradigms(an ultimate goal is the whole project written in python and which it can transpile itself to Javascript)

    opened by deadlocklogic 18
  • String encode utf-8 boundary case errors

    String encode utf-8 boundary case errors

    The following test cases are failing. The problem seems to be in py_bytes.js, where < should be changed to <=.

    assert '\u007f'.encode('utf-8') == b'\x7f'
    assert '\u07ff'.encode('utf-8') == b'\xdf\xbf'
    assert '\uffff'.encode('utf-8') == b'\xef\xbf\xbf'
    
    opened by mircea3 0
  • The calendar module is not working

    The calendar module is not working

    Hello,

    The calendar module is not working. I can import the module, but when I try to generate a calendar it fails.

    Script:

    import calendar
    
    cal = calendar.calendar(2023)
    

    Error message:

    brython.min.js:1 Traceback (most recent call last):
      File "http://127.0.0.1:5500/a-model.html#__main__", line 3, in <module>
        cal = calendar.calendar(2023)
      File "VFS.calendar.py", line 389, in formatyear
        a(formatstring(names,colwidth,c).rstrip())
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "VFS.calendar.py", line 646, in formatstring
        return spacing.join(c.center(colwidth)for c in cols)
               ^^^^^^^^^^^^
    AttributeError: 'int' object has no attribute 'join'
    
    opened by tdmsilvino 0
  • modules used on a worker thread are not cached in indexedDB

    modules used on a worker thread are not cached in indexedDB

    As far as I can tell, the modules used on a worker thread are not cached into the indexedDB. Is this a known limitation? In my case, most of my python code is running in a worker, so I expect my load times would improve with indexedDB caching of worker thread modules.

    opened by benjie-git 1
  • import datetime is very slow

    import datetime is very slow

    As the subject says. (I do not if that qualifies as a bug, more a hint for improvements) I have profiled all import times for all "customers" of a web site made in Brython and came to this conclusion.

    opened by lefranco 6
  • Brython recent version cannot run on Midori

    Brython recent version cannot run on Midori

    Lubuntu 2210

    brython-cli --version -> Brython version 3.11.0

    sudo snap install midori -> midori browser installed

    run midori go to site made with brython https://diplomania-gen.fr/ working fine with edge, safari, firefox, chrome

    no page CTRL + shift + I

    three errors :

    SyntaxError: No identifiers allowed directly after numeric literal brython.js:8021

    ReferenceError: Can't find variable: BRYTHON brython_modules.js:1

    ReferenceError: Can't find variable: brython onload diplomania-gen.fr:21

    (no such errors at least on chrome/firefox) Is midora missng a feature required by brython produces code ?

    opened by lefranco 1
  • Problem with ajax

    Problem with ajax

    In version 3.10.7 ajax.form_data() does not work. (I am aware that you know this) In version 3.11.0 this problem is solved, but it now creates now an error on ajax.file_upload() in the same program. No errors with 3.10.7

    JavaMessages.txt

    opened by rpietsch1953 2
Releases(3.11)
Owner
null
tox-gh is a tox plugin which helps running tox on GitHub Actions with multiple different Python versions on multiple workers in parallel

tox-gh is a tox plugin which helps running tox on GitHub Actions with multiple different Python versions on multiple workers in parallel. This project is inspired by tox-travis.

tox development team 19 Dec 26, 2022
Cirq is a Python library for writing, manipulating, and optimizing quantum circuits and running them against quantum computers and simulators

Cirq is a Python library for writing, manipulating, and optimizing quantum circuits and running them against quantum computers and simulators. Install

quantumlib 3.6k Jan 7, 2023
Airflow Operator for running Soda SQL scans

Airflow Operator for running Soda SQL scans

Todd de Quincey 7 Oct 18, 2022
Commodore 64 OS running on Atari 8-bit hardware

This is the Commodre 64 KERNAL, modified to run on the Atari 8-bit line of computers. They're practically the same machine; why didn't someone try this 30 years ago?

Nick Bensema 133 Nov 12, 2022
Easy installer for running Amazon AVS Device SDK on Raspberry Pi

avs-device-sdk-pi Scripts to enable Alexa voice activation using Picovoice Porcupine If you like the work, find it useful and if you would like to get

null 4 Nov 14, 2022
Tool for running a high throughput data ingestion/transformation workload with MongoDB

Mongo Mangler The mongo-mangler tool is a lightweight Python utility, which you can run from a low-powered machine to execute a high throughput data i

Paul Done 9 Jan 2, 2023
Running a complete single-node all-in-one cluster instance of TIBCO ActiveMatrix™ BusinessWorks 6.8.0.

TIBCO ActiveMatrix™ BusinessWorks 6.8 Docker Image Image for running a complete single-node all-in-one cluster instance of TIBCO ActiveMatrix™ Busines

Federico Alpi 1 Dec 10, 2021
SQL centered, docker process running game

REQUIREMENTS Linux Docker Python/bash set up image "docker build -t game ." create db container "run my_whatever/game_docker/pdb create" # creating po

null 1 Jan 11, 2022
Grail(TM) is a web browser written in Python

Grail is distributed in source form. It requires that you have a Python interpreter and a Tcl/Tk installation, with the Python interpreter configured for Tcl/Tk support.

null 22 Oct 18, 2022
Simple Python Gemini browser with nice formatting

gg I wasn't satisfied with any of the other available Gemini clients, so I wrote my own. Requires Python 3.9 (maybe older, I haven't checked) and opti

Sarah Taube 2 Nov 21, 2021
Open source tools to allow working with ESP devices in the browser

ESP Web Tools Allow flashing ESPHome or other ESP-based firmwares via the browser. Will automatically detect the board type and select a supported fir

ESPHome 195 Dec 31, 2022
Yandex Media Browser

Браузер медиа для плагина Yandex Station Включайте музыку, плейлисты и радио на Яндекс.Станции из Home Assistant! Скриншот Корневой раздел: Библиотека

Alexander Ryazanov 35 Dec 19, 2022
A script that will warn you, by opening a new browser tab, when there are new content in your favourite websites.

web check A script that will warn you, by opening a new browser tab, when there are new content in your favourite websites. What it does The script wi

Jaime Álvarez 52 Mar 15, 2022
A browser login credentials thief for windows and Linux

Thief ???? A browser login credentials thief for windows and Linux Python script to decrypt login credentials from browsers in windows or linux Decryp

Ash 1 Dec 13, 2021
Batch generate asset browser previews

When dealing with hundreds of library files it becomes tedious to mark their contents as assets. Using python to automate the process is a perfect fit

null 54 Dec 24, 2022
Integration between the awesome window manager and the firefox web browser.

Integration between the awesome window manager and the firefox web browser.

contribuewwt 3 Feb 2, 2022
KeyBrowser: A program launches a browser and a keylogger at the same time, is used to retrieve a person's personal information

KeyBrowser: A program launches a browser and a keylogger at the same time, is used to retrieve a person's personal information

null 3 Oct 16, 2022
Implementation of the Angular Spectrum method in Python to simulate Diffraction Patterns

Diffraction Simulations - Angular Spectrum Method Implementation of the Angular Spectrum method in Python to simulate Diffraction Patterns with arbitr

Rafael de la Fuente 276 Dec 30, 2022
Python implementation of the ASFLIP advection method

This is a python implementation of the ASFLIP advection method . We would like to hear from you if you appreciate this work.

Raymond Yun Fei 133 Nov 13, 2022