WebAssembly: Running python solution for the Classical 8 Queens puzzle using Pyodide
Innovative technologies are always emerging in the ever-changing field of web development, bringing new possibilities and opportunities to the table. WebAssembly, a binary instruction format designed to enable high performance execution on web browsers, is one such game-changing breakthrough. With the rapid adoption of WebAssembly, developers can now run complex programs and even languages not traditionally associated with web development on the client side.
In this article, we will take a look at WebAssembly and explore how it enables us to run Python programs directly in the browser using the Pyodide project. By enabling the installation and use of Python packages in the browser with micropip, Pyodide brings the power of Python to web applications.
What is WebAssembly?
WebAssembly is a binary instruction format that allows high-performance code to run directly in web browsers. It provides a low-level, efficient way to execute code written in languages like C++, Rust and Python, among others. Unlike interpreted languages such as JavaScript, WebAssembly runs at near-native speed, making it an excellent choice for computationally intensive activities and performance-critical applications. Please read my article on WebAssembly, if you haven’t seen it.
What is Pyodide?
Pyodide is the Python offspring of Iodide, the attempt to bring JavaScript and science to the browser. Since JavaScript had no well-defined scientific stack whereas Python does, the idea of replacing JavaScript with Python was suggested. And thus, Pyodide.
Pyodide makes it possible to install and run Python packages in the browser with?micropip
It comes with a robust Javascript ? Python foreign function interface so that you can freely mix these two languages in your code with minimal friction. This includes full support for error handling, async/await, and much more.
The 8 Queens puzzle and the solution
The classical 8 Queens problem is a classic puzzle that challenges us to place 8 queens on a standard chessboard in a way that no queen attack another. We will explore how to use WebAssembly and Pyodide to run a Python solution for 8 Queens problem directly in a web browser. The results will be displayed in a graphical form to visualize the solutions. In my earlier article about recursion, I have discussed the above Python program. It returns an array of positions. If you haven't read this, please go through the same.
WebAssembly-Pyodide workflow
The following statement fetches Pyodide from the CDN. There are alternative ways to use Pyodide. I'm not going to go over those possibilities here.
领英推荐
<script src="https://cdn.jsdelivr.net/pyodide/v0.23.4/full/pyodide.js"></script>
We can use?loadPyodide() function to load Pyodide. The runPython() method allows us to run simple Python statements. We will be using a slightly different approach here, as we have the Python script available in a separate file.
let pyodide = await loadPyodide()
pyodide.runPython();
The following function ('fetchAndLoadPythonScript') helps us in loading the script from a file ('chess.py').
async function fetchAndLoadPythonScript(pyodide) {
? ? console.log("Fetching Python script...");
? ? const response = await pyodide.runPythonAsync(`
? ? ? ? from pyodide.http import pyfetch
? ? ? ? response = await pyfetch('/chess.py')
? ? ? ? with open('chessscript.py', "wb") as f:
? ? ? ? ? ? f.write(await response.bytes())
? ? `);
? ? console.log("Python script fetched and loaded successfully.");
}
The following function invokes the above method to load the python script and then runs it. It also invokes additional methods in order to display the results on the screen.
async function runPython() {
? ? console.log("runPython");
? ? const loader = document.getElementById('loader');
? ? loader.style = "display: block";
? ? const pyodide = await loadPyodide();
? ? await fetchAndLoadPythonScript(pyodide);
? ? pkg = pyodide.pyimport("chessscript")
? ? const results = pkg.get_positions();
? ?
? ? const resArray = JSON.parse(results.toString()); //pyodide.toJs(results);
? ? for (const [index, solution] of resArray.entries()) {
? ? ? ? const boardId = 'sol' + index;
? ? ? ? createBoard(boardId);
? ? ? ? for (const [x, y] of solution.entries()) {
? ? ? ? ? ? addQueen(boardId, x, y);
? ? ? ? }
? ? }
? ? loader.style = "display:none";
}
Source code is available in Github. Please follow the link to access the same. If you are familiar with GitHub Codespaces, you can try running this program and view the results from your Github account with 2-3 clicks.
I've deployed this on Vercel, especially for those who want to see the results without running the application. To view the output, please click on this link.
Conclusion
With the seamless integration of Python through WebAssembly and Pyodide, developers can create highly interactive and performant web applications, bringing complex problem-solving and data processing tasks directly to the client-side. The Classical 8 Queens Problem serves as a compelling example of how WebAssembly and Pyodide can enhance the capabilities of web development.