Executing a small piece of brython code on demand

631 views
Skip to first unread message

Kiko

unread,
Feb 17, 2014, 5:53:27 PM2/17/14
to bry...@googlegroups.com
Hi,

The brython() function looks for script tags with type "text/python" and execute all of them.

The workflow is something as follows:

eval(__BRYTHON__.py2js(src_code).tojs())


What should I do if I want to run just a piece of code defined, for example, in a Python string? For example, if I define the following:

code = """
from browser import doc, html

for i in range(5):
    doc['mydiv'] <= html.P(i, style = {'backgroundColor': 'cyan'})
"""

How can I pass that code to the js machinery to run just that code.

I can do:

eval(__BRYTHON__.py2js('print(1)').tojs())

and it works but I would like to define a multiline string and use imports and all the power of brython on demand.

I know it is possible but I don't know how should I do it.

Best regards.

Billy Earney

unread,
Feb 18, 2014, 8:11:45 AM2/18/14
to bry...@googlegroups.com
Kiko,

I have not tried this, but it seems to me you could just put it all in a variable such as

_str="from browser import doc, html\n"

_str+="for i in range(5):\n"
_str+="    doc['mydiv'] <= html.P(i, style={'backgroundColor': 'cyan'})\n"

eval(__BRYTHON__.py2js(_str).tojs())


Billy


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/brython/CAB-sx63xMK8gPQDT22RYrH8fQR%2BS325oeQjbSQd6qDfw3--pyA%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.

Kiko

unread,
Feb 18, 2014, 8:51:30 AM2/18/14
to bry...@googlegroups.com



2014-02-18 14:11 GMT+01:00 Billy Earney <billy....@gmail.com>:
Kiko,

I have not tried this, but it seems to me you could just put it all in a variable such as

_str="from browser import doc, html\n"

_str+="for i in range(5):\n"
_str+="    doc['mydiv'] <= html.P(i, style={'backgroundColor': 'cyan'})\n"

eval(__BRYTHON__.py2js(_str).tojs())


It works if you use vanilla 'Python'. But if I import modules or if you want to do other stuff there are variables that are not populated like __BRYTHON__.scope, __BRYTHON__.modules, __BRYTHON__.path,... and sometimes it fails...

I think that a new brython function would be helpful. It could be something like an ibrython function (i for interactive ;-D) that could be used on this special cases and no need to load the brython function.

Billy Earney

unread,
Feb 18, 2014, 9:10:32 AM2/18/14
to bry...@googlegroups.com
Good point..   Try this.

Still do a  onload="brython()"   in the body tag.  If there are no script tags with type="text/python", it still should be okay.

Then put the eval(__BRYTHON__.py2js...... code in a function such as the following

function myfunc() {
     eval(__BRYTHON__.py2js.......)
}

and add myfunc() to the body onload such as

<body onload="brython();myfunc()">


the brython() call should do all the setup for you

Hope this helps.

Billy



--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Billy Earney

unread,
Feb 18, 2014, 9:57:13 AM2/18/14
to bry...@googlegroups.com
This brings up a good point.

if brython is added to a page via a script tag, should brython automatically set the window.onload to brython()?  Or should we force the user to type  <body onload="brython()"> ?   Does typing <body onload="brython()"> override/reset window.onload?

Billy 

Kiko

unread,
Feb 18, 2014, 10:18:33 AM2/18/14
to bry...@googlegroups.com


2014-02-18 15:57 GMT+01:00 Billy Earney <billy....@gmail.com>:
This brings up a good point.

if brython is added to a page via a script tag, should brython automatically set the window.onload to brython()?  Or should we force the user to type  <body onload="brython()"> ?   Does typing <body onload="brython()"> override/reset window.onload?

Billy 



Also, if you have several script tags of type "text/python" or "text/python3", the __main__ module would be addressed to the code enclosed by the last script tag of type "text/python".

I am trying to understand py2js.js but I'm going very slowly and I'm not understanding the use of some stuff... I have to go deeper.

Pierre Quentel

unread,
Feb 18, 2014, 10:50:42 AM2/18/14
to bry...@googlegroups.com

Hi,

What is wrong with

code = """
from browser import doc, html

for i in range(5):
    doc['mydiv'] <= html.P(i, style = {'backgroundColor': 'cyan'})
"""
exec(code)

?
 

Kiko

unread,
Feb 18, 2014, 10:57:49 AM2/18/14
to bry...@googlegroups.com
I tried, but exec(code) doesn't work in my case (IPython nb).
I have to do more research...

--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Pierre Quentel

unread,
Feb 18, 2014, 10:58:55 AM2/18/14
to bry...@googlegroups.com

Oops, it seems you mean running Python code inside Javascript...

Pierre Quentel

unread,
Feb 18, 2014, 11:49:52 AM2/18/14
to bry...@googlegroups.com

Ideally, one could create a script element on the fly with type="text/python", set its source code to the Python code, and run brython() which would detect and run the newly created script

Unfortunately, as far as I know it's not possible to set the code of a dynamically created script

Another solution would be to create another element (a DIV with visibility set to "hidden" for instance), and add a parameter to brython() to say that Python code stands in DIV elements with type="text/python3"

I slightly modified brython() so that this code works (the additional argument to brython() is called py_tag) :

<script>
function run_python(src){
    // dynamically create an invisible DIV with type="text/python3"
    var py_script = document.createElement('div')
    py_script.style.visibility = 'hidden'
    py_script.type = 'text/python3'
    // set DIV content to Python source code
    py_script.textContent = src
    document.body.appendChild(py_script)
    // run brython(), searching Python code in DIV tags
    brython({debug:1,py_tag:'div'})
    // clean up
    document.body.removeChild(py_script)
}

py_code = "from browser import doc, html\n"
py_code += "print(doc.getElementById('mydiv'))\n"
py_code += "for i in range(5):\n"
py_code += "    doc['mydiv'] <= html.P(i, style = {'backgroundColor': 'cyan'})"

run_python(py_code)
</script>

Would this make sense for your use case ? If so I will push the change to the repository
- Pierre

Kiko

unread,
Feb 18, 2014, 1:45:43 PM2/18/14
to bry...@googlegroups.com
First of all, if someone don't  know what the IPython notebook is you could take a look here: ipython.org

Right now I could run this in an IPython notebook cell:

%%HTML
<script type="text/javascript">window.onload = brython()</script>
<script type="text/python">

from browser import doc, html

doc["mydiv"].text = ""

for i in range(3):   
    doc['mydiv'] <= html.P(i)
</script>
<div id="mydiv"></div>

If I want to run a new brython script in a new cell I have to add again

<script type="text/javascript">window.onload = brython()</script>

in the new cell so all the brython scripts in other cells are run, not just the brython script of the cell. This is why there is this line:

doc["mydiv"].text = ""

I have to clean the div if I don't want to repeat the code again in the div

I tested the 2.0.0.dev version of IPython and exec(code) works but again I have to write:

<script type="text/javascript">window.onload = brython()</script>

but if I write the brython code as a string I can't use all the IPython capabilities (colored syntax, autocompletion,...).

So, the idea would be to run code on demand. I will try the Pierre solution. Later I will upload a notebook somewhere to share with you the results of my research (nbviewer.ipython.org). Some stuff is not working so I need to spend more time on it (bind is not working, the three.js example of the gallery is not working, some tests I made with D3.js are not 100% working,...).

I think IPython would be a good advertisement platform for Brython and after some tests I think an interchange between python code and brython code using json serialization could be feasible so IPython users maybe could use Brython to replace their js code.

Thanks for your help.

Kiko

unread,
Feb 19, 2014, 3:51:06 AM2/19/14
to bry...@googlegroups.com


<script>
function run_python(src){
    // dynamically create an invisible DIV with type="text/python3"
    var py_script = document.createElement('div')
    py_script.style.visibility = 'hidden'
    py_script.type = 'text/python3'
    // set DIV content to Python source code
    py_script.textContent = src
    document.body.appendChild(py_script)
    // run brython(), searching Python code in DIV tags
    brython({debug:1,py_tag:'div'})
    // clean up
    document.body.removeChild(py_script)
}

py_code = "from browser import doc, html\n"
py_code += "print(doc.getElementById('mydiv'))\n"
py_code += "for i in range(5):\n"
py_code += "    doc['mydiv'] <= html.P(i, style = {'backgroundColor': 'cyan'})"

run_python(py_code)
</script>



I was thinking in this solution and maybe could be simpler:

<script>
function run_python(src){
    brython({debug:1, src: JSON.stringify(src)})

}

py_code = """
from browser import doc, html
print(doc.getElementById('mydiv'))

for i in range(5):
    doc['mydiv'] <= html.P(i, style = {'backgroundColor': 'cyan'})
"""
run_python(py_code)
</script>


py_code would be the code of the ipython code cell. Do you think it could be possible to run it in this way?

In this way you could run your source on demand and you don't have to do 'window.onload = brython()' on each cell avoiding the execution of all the code cells in the IPython notebook each time you want to run a single brython code cell.

Thanks

Billy Earney

unread,
Feb 19, 2014, 8:13:21 AM2/19/14
to bry...@googlegroups.com
this works for me..

eval(__BRYTHON__.py2js("import unittest;print(dir(unittest))").to_js())

or you could do it as:

_src="import unittest\n"
_src+="print(dir(unittest))"

eval(__BRYTHON__.py2js(_src).to_js())

this seems to work for me, and it is simpler than creating and putting stuff in div tag.

Billy



--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Francois Dion

unread,
Feb 19, 2014, 8:21:02 AM2/19/14
to bry...@googlegroups.com

Kiko

unread,
Feb 19, 2014, 8:32:27 AM2/19/14
to bry...@googlegroups.com
2014-02-19 14:21 GMT+01:00 Francois Dion <franco...@gmail.com>:

Nice!

On Feb 19, 2014 8:13 AM, "Billy Earney" <billy....@gmail.com> wrote:
this works for me..

eval(__BRYTHON__.py2js("import unittest;print(dir(unittest))").to_js())

or you could do it as:

_src="import unittest\n"
_src+="print(dir(unittest))"

eval(__BRYTHON__.py2js(_src).to_js())


See my reply to Pierre above.

I think both solutions could be feasible.

I am advancing fine in my brython/IPython integration idea... D3 is working (with some tweaks,...).
 

Billy Earney

unread,
Feb 19, 2014, 8:36:51 AM2/19/14
to bry...@googlegroups.com
I think it is best to keep brython internals away from the user as much as possible.  So maybe we should implement a src argument to the brython function (or create another javascript function to hold the internal calls) maybe something like

function brython.eval(src) {
   eval(__BRYTYHON__.py2js(src).to_js()))
}

if this is okay with everyone, I'll look into adding it to py2js.js

Billy


Kiko

unread,
Feb 19, 2014, 8:46:52 AM2/19/14
to bry...@googlegroups.com
2014-02-19 14:36 GMT+01:00 Billy Earney <billy....@gmail.com>:
I think it is best to keep brython internals away from the user as much as possible.  So maybe we should implement a src argument to the brython function (or create another javascript function to hold the internal calls) maybe something like

function brython.eval(src) {
   eval(__BRYTYHON__.py2js(src).to_js()))
}

if this is okay with everyone, I'll look into adding it to py2js.js

Billy

Maybe the Pierre idea is better:
-Let the brython function accept a new parameter (src or whatever) and in this case, do not look for script tags with type="text/python(3)" and apply all the BRYTHON machinery only to the source code passed as argument.

I don't know if it makes sense.

Billy Earney

unread,
Feb 19, 2014, 9:05:01 AM2/19/14
to bry...@googlegroups.com
sure that makes sense.  I think either idea (or even implementing both) maybe okay.

Billy


--
You received this message because you are subscribed to the Google Groups "brython" group.
To unsubscribe from this group and stop receiving emails from it, send an email to brython+u...@googlegroups.com.
To post to this group, send email to bry...@googlegroups.com.

Pierre Quentel

unread,
Feb 19, 2014, 10:59:02 AM2/19/14
to bry...@googlegroups.com
I have pushed the changeset with the additional "py_tag" argument, just for testing, but it's probably not the best solution

I just installed iPython on my PC and started playing with the Notebook. I see it's getting very popular ; Kiko, when the integration with Brython is ok it would be great to publish a "howto" about it somewhere

- Pierre


Kiko

unread,
Feb 19, 2014, 4:45:24 PM2/19/14
to bry...@googlegroups.com
2014-02-19 16:59 GMT+01:00 Pierre Quentel <pierre....@gmail.com>:
I have pushed the changeset with the additional "py_tag" argument, just for testing, but it's probably not the best solution

I just installed iPython on my PC and started playing with the Notebook. I see it's getting very popular ; Kiko, when the integration with Brython is ok it would be great to publish a "howto" about it somewhere


The examples are working online but for the last example you should download the ipynb and run it locally (I don't know why it is not shown online¿?). If you download the ipynb you could play with it. In the ipynb you have instructions to make it work locally.

Maybe wth this ipynb you can get a better idea of what I'm thinking. In this ipynb there are some tweaks to make things work. I would like to avoid that (reinterpretation of all script tags when a new code cell is executed. Avoid to import many times the same libraries if they are already imported on other cells,...

There are some functionality called IPython magic functions and cell magic are among them (for example, when I use %%HTML I'm using a cell magic to define the cell as HTML code). To create a %%BRYTHON magic would be very easy and this is what I want to do but first some things should be adapted.

Good night and thanks Billy, Francois and Pierre.
Reply all
Reply to author
Forward
0 new messages