Skip to content

[PY] Added the ability to run Brython code#8640

Closed
Ahsoka wants to merge 25 commits intoSeleniumHQ:trunkfrom
Ahsoka:brython
Closed

[PY] Added the ability to run Brython code#8640
Ahsoka wants to merge 25 commits intoSeleniumHQ:trunkfrom
Ahsoka:brython

Conversation

@Ahsoka
Copy link

@Ahsoka Ahsoka commented Aug 22, 2020

Description

For the uninitiated Brython is a way to use Python code on the front-end instead of Javascript. This pull-request adds a execute_brython() method which allows you to execute Brython code much in the same way you would use the execute_script() method to execute JavaScript code. There is also now a load_brython() method which is used to load the necessary JavaScript files to run Brython code and must be called before using the execute_brython() method.

Examples

Here are a couple of examples of using the load_brython() and execute_brython() methods.

Example 1

>>> from selenium import webdriver
>>> driver = webdriver.Chrome()
>>> # You must use `load_brython()` before using `execute_brython()`
>>> driver.load_brython()
>>> driver.execute_script("console.log('Hello World');")
>>> # Equivalent using `execute_brython()`
>>> driver.execute_brython("print('Hello World')")

Example 2

>>> from selenium import webdriver
>>> driver = webdriver.Chrome()
>>> driver.load_brython()
>>> # turtle_script is defined below
>>> driver.execute_brython(turtle_script)

This is turtle_script

# Adapted from https://brython.info/gallery/turtle.html
from browser import document, html
import turtle
if 'turtle-div' not in document:
    document <= html.DIV(Id='turtle-div', style={'float':'left', 'border': '1px solid green'})
turtle.set_defaults(
    turtle_canvas_wrapper = document['turtle-div']
)
t = turtle.Turtle()

t.width(5)

for c in ['red', '#00ff00', '#fa0', 'rgb(0,0,200)']:
    t.color(c)
    t.forward(100)
    t.left(90)

# dot() and write() do not require the pen to be down
t.penup()
t.goto(-30, -100)
t.dot(40, 'rgba(255, 0, 0, 0.5')
t.goto(30, -100)
t.dot(40, 'rgba(0, 255, 0, 0.5')
t.goto(0, -70)
t.dot(40, 'rgba(0, 0, 255, 0.5')

t.goto(0, 125)
t.color('purple')
t.write("I love Brython!", font=("Arial", 20, "normal"))


turtle.done()

Result of Example 2

data_, - Google Chrome 2020-08-22 16-44-07_Trim

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • I have read the contributing document.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Ahsoka added 3 commits August 22, 2020 00:07
Used to load the necessary Javascript files to run Brython code.
This method allows you to execute Brython code just like the 
execute_script() method allows you to execute Javascript code.
@CLAassistant
Copy link

CLAassistant commented Aug 22, 2020

CLA assistant check
All committers have signed the CLA.

Ahsoka added 3 commits August 22, 2020 14:19
Before the stdlib was accessed via files in the Brython Github 
repository, but it now accessed through the brython_stdlib.js file.  
Initially, I thought this method of acessing the Brython stdlib would 
not work because for some unknown reason, when brython_stdlib,js 
accessed the Indexed Database API, it caused the following error: 
"access to the Indexed Database API is denied in this context".  
However, recently I discovered in the brython() function there is an 
option to disable access to the database (which is used to load the 
Brython stdlib) and access through some other method (which I don't 
fully understand).
@Ahsoka
Copy link
Author

Ahsoka commented Aug 23, 2020

I am not sure how I would go about adding documentation. I have added a docstring to both of the new methods I created. Does this satisfy the I have updated the documentation accordingly. requirement? Please let me know.

@Ahsoka Ahsoka marked this pull request as ready for review August 23, 2020 00:04
Copy link
Member

@AutomatedTester AutomatedTester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind adding support for Brython but ongoing it might break and there are no tests in this patch to make sure that never happens.

Would it not be better to have a package that you own that has a dependency on Selenium that you ship?

'args': converted_args})['value']

def load_brython(self,
src="https://cdn.jsdelivr.net/npm/brython@3.8.9/brython.min.js",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure Brython users would always be in the internet? Who not bundle as data like some of the other JS packages that are shipped

Copy link
Author

@Ahsoka Ahsoka Aug 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also thought of something similar to what you suggested but unfortunately it can be unreliable. For example, in Chrome whenever I try to access local files I get the follow error Not allowed to load local resource: {file name here}. However, I believe in Firefox it would work with no problem (I have not tested this but I have reason to believe this to be the case from the exhaustive amount of research I have conducted on this topic). Additionally, unless configured in a certain way, Brython has a reliance on certain external files anyway. Loading Brython from a file would still require access to the external files via the internet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to use bazel here. I will help with this part.

@@ -0,0 +1,4 @@
var script = document.createElement('script')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These files should in /javascript/brython

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you refer to /javascript/brython do you mean py/selenium/webdriver/remote/javascript/brython or the top level directory /javascript/brython.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

top level /javascript/brython and add a bazel file or if you want to use npm then we can add it to the package.json and I will help with the bazel stuff .

Copy link
Author

@Ahsoka Ahsoka Aug 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright I added the files to the top level directory /javascript/brython. See this commit for reference. I am not too familiar with Bazel so please let me know what I need to do to reference the files in my code.

As of now they are currently referenced like this:

See the below here.

_pkg = '.'.join(__name__.split('.')[:-1])
template = pkgutil.get_data(_pkg, 'loadBrython.js').decode('UTF-8')

and like this

_pkg = '.'.join(__name__.split('.')[:-1])
running = pkgutil.get_data(_pkg, 'runBrython.js').decode('UTF-8').format(repr(script))

See the above here.

Ahsoka added 3 commits August 27, 2020 10:33
Before this patch there was a **MAJOR BUG** that would cause an error 
when using the `execute_brython()` too soon after using the 
`load_brython()` method. Now, the `load_brython()` method will now 
terminate **ONLY** after Brython has been succesfully loaded.
This test tests for several things:
- Can Brython be successfully loaded in a reasonable amount of time (5 
seconds to be exact)?
- Are the stdlib modules accesible? (this is tested by accessing the 
turtle module)
- Is execute_brython functioning properly? (This is tested by running a 
simple script with turtle)
@Ahsoka
Copy link
Author

Ahsoka commented Aug 27, 2020

I added a single test that will pretty reliable test whether or not Brython works. See these changes for reference,

@Ahsoka
Copy link
Author

Ahsoka commented Sep 1, 2020

@AutomatedTester Whenever you get a chance please let me know what the next steps are in getting this PR ready to merge. Thank you!

The reasoning behind this is instead of constantly changing the URL 
everytime a newer version of Brython comes out, use a URL that will 
always point to the latest development version.  If users do not like 
this they always have the option to override the default and pass in 
whatever 
version they would like instead.
For compatibility with older versions of Python
@Ahsoka
Copy link
Author

Ahsoka commented Sep 20, 2020

@AutomatedTester Any updates on this PR?

@Ahsoka
Copy link
Author

Ahsoka commented Nov 15, 2020

Hey @AutomatedTester, I just wanted to follow up again to see if there are any plans to merge this PR? If not, please let me know so I can stop bothering you and close this PR. 🙃

@AutomatedTester
Copy link
Member

Hey @AutomatedTester, I just wanted to follow up again to see if there are any plans to merge this PR? If not, please let me know so I can stop bothering you and close this PR. 🙃

I need to find time to fix the build system for this PR. I am hoping soon

@Ahsoka
Copy link
Author

Ahsoka commented Nov 16, 2020

Awesome, thank you so much for getting back to me. If there is anything I can do, please let me know! 😁

@diemol diemol added the C-py Python Bindings label Mar 29, 2021
@github-actions github-actions bot added the Stale label Jan 30, 2022
@github-actions github-actions bot closed this Feb 13, 2022
@Ahsoka
Copy link
Author

Ahsoka commented Feb 13, 2022

Any updates on this?

@titusfortner titusfortner added J-stale Applied to issues that become stale, and eventually closed. and removed Stale labels Mar 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-py Python Bindings J-stale Applied to issues that become stale, and eventually closed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants