I would like to run a python code to solve some equations in the browser. I currently do this with javascript in a web worker. This does not interact with the DOM at all, it just receives some input, does some calculations, and then returns the output. I would love to able to use python in the same way. Is this possible?
I don't think you'd be able to get the client's browser execute any Python code. You'll have to figure out some sort of protocol to communicate back and forth with Python. A common way to do this is to have a Python process running somewhere that acts as an HTTP(s) server. You can have the client's browser make an API call (some form of HTTP request) to the Python server and that separate piece of Python code running will catch that call and send back data. This could be as simple as a <frame> tag or some Javascript code that makes the request and interprets the response in the browser.
Try this, go into a new directory and create two files.
server.py (built on python3):
#!/usr/bin/env python
import http.server
import logging
IP = '127.0.0.1'
PORT = 8001
class MyHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
url = self.path
headers = self.headers
print('received request:', url)
numbers = url.split('/')
print('parsed numbers:', numbers)
try:
sumTotal = 0
for num in numbers:
if num == '':
continue
sumTotal += int(num)
self.respond(sumTotal)
except ValueError as ex:
logging.error('unable to parse value: %s' % num)
self.respond(-1)
def respond(self, sumTotal):
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','text/html')
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
# Send message back to client
message = str(sumTotal)
# Write content as utf-8 data
self.wfile.write(bytes(message, 'utf8'))
return
def main():
address = (IP, PORT)
httpd = http.server.HTTPServer(address, MyHandler)
httpd.serve_forever()
if __name__ == '__main__':
main()
test.html:
<!DOCTYPE HTML>
<html lang="en-us">
<head>
<title>Python Linking Demo</title>
<script type="text/javascript">
function addNumbers(a, b) {
var url = 'http://localhost:8001/' + a + '/' + b;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
var data = xhr.responseText;
var el = document.getElementById('data-div');
if (!el) {
return;
}
el.innerHTML = data;
}
}
xhr.open('GET', url, true);
xhr.send(null);
};
setTimeout(function(){addNumbers(7, 13);}, 1000);
</script>
</head>
<body>
<h1>With some luck, this will populate below:</h1>
<div id="data-div">{{number}}</div>
</body>
</html>
Now, first start the server for the Python process:
$ python server.py
While that is running, also start the web server to serve the html (also python3):
$ python -m http.server 8000
Then try navigating a browser to http://localhost:8000/test.html and you should see test.html make a request to http://localhost:8001/7/13 which will invoke the Python method MyHandler.do_GET() which sends back an HTTP response containing the sum of the numbers, 20. Credit goes to this website which I basically copy-pasted from: https://daanlenaerts.com/blog/2015/06/03/create-a-simple-http-server-with-python-3/ .
This is as simple and raw as it gets, it will work great for a function or two but if you find yourself exporting lots of functionality to Python, it'd be worthwhile to upgrade to more advanced libraries and frameworks (both on the client/Javascript side and the server/Python side) that intend to be more robust and feature-complete for doing this type of thing.