Data Science

Run Python programs in a browser

In recent years, WebAssembly (usually abbreviated like WASM) has become an interesting technology that extends the capabilities of web browsers far beyond the traditional realm of HTML, CSS, and JavaScript.

As a Python developer, a particularly exciting application is the ability to run Python code directly in the browser. In this article, I’ll explore what WebAssembly is (and its relationship with the Pyodide library), discuss its benefits and daily use cases, and dig into some practical examples of how to use WebAssembly to run Python programs online.

These tools can also benefit data scientists and ML professionals. Pyodide brings a large portion of the scientific python stack (Numpy, Pandas, Scikit-Learn, Matplotlib, Scipy, etc.) to the browser, which means that familiar tools and libraries can be used during code development. It can also be used for demonstration purposes. As you can see in my last example, combining Python’s data processing power with HTML, CSS, and JavaScript for the UI, you can quickly build interactive dashboards or tools without the need for a separate backend in many use cases.

What is WebAssembly?

WebAssembly is a low-level binary instruction format designed as a portable target for compiling high-level languages ​​such as C, C++, Rust, and even Python. It was created to enable high-performance applications on the network without some of the pitfalls of traditional JavaScript execution, such as runtime speed. Some key aspects of WebAssembly include:

  • portability. The WebAssembly module always runs in all modern browsers.
  • Performance. The binary format is compact and can be parsed quickly, which allows for near-local execution speed.
  • Safety. WebAssembly runs in a sandbox environment, providing strong security assurance.
  • Language agnostic. Although browsers primarily support JavaScript, WebAssembly enables developers to write code in other languages ​​and compile it into WebAssembly (WASM).

What can be used with WebAssembly?

WebAssembly has a wide variety of applications. Some of the most common use cases include: –

  1. High-performance web applications. WebAssembly helps applications like gaming, image and video editors and achieves near-native performance.
  2. Porting traditional code. Code written in C, C++, or Rust can be compiled into WebAssembly, allowing developers to reuse existing libraries and code bases on the web.
  3. Multimedia processing. Audio and video processing libraries benefit from WebAssembly’s speed, enabling more complex processing tasks in real time.
  4. Scientific calculations. A large number of calculations such as machine learning, data visualization, or numerical simulation can be offloaded into the WebAssembly module.
  5. Runs multiple languages. Projects like Pyodide allow Python (and its broad ecosystem) to be Execute in the browser without the server backend.

If you code in Python frequently, the last point should sting your ears, so let’s dig deeper.

Run python online

Traditionally, Python runs in a server or desktop application. But, thanks to like BijidPython can be run in the browser via WebAssembly. Pyodide compiles CPYTHON interpreter code into WebAssembly, allowing you to execute Python code and use many popular third-party libraries directly in your web application.

It’s more than just a head. There are several advantages to doing this, including: –

  • A wide library ecosystem using Python, including data science packages (Numpy, Pandas, Matplotlib) and machine learning (Scikit-Learn, TensorFlow).
  • Responsiveness is improved as fewer round trips are required.
  • This is a simpler deployment because the entire application logic can reside on the front end.

We’ve mentioned Bidid a few times, so let’s take a closer look at what the real high peptide is.

What is a pus production agent

The idea behind Pyodide is derived from the increasing number of Python code running in the browser without relying on traditional server-side settings. Traditionally, web applications depend on JavaScript for client interactions, while Python is limited to backend or desktop applications. However, with the advent of WebAssembly, there is a chance to bridge the gap.

Mozilla Research recognizes the potential of this approach and set out to use the Emscripten toolchain Cpython Port Cpython (a reference implementation of Python). This work is about running Python in a browser and unlocking a new world of interactive client applications made up of Python’s rich data science libraries, numerical calculations, and more.

All in all, Pyodide is a port of Cpython that has been compiled into WebAssembly. This means that when you run Python code in your browser using Pyodide, you will execute a fully functional Python interpreter optimized for your web environment.

Yes, it’s time to check out some code.

Establish a development environment

Before we start coding, let’s set up the development environment. The best thing to do is to create a separate Python environment where you can install any necessary software and try coding, knowing that nothing you do in this environment will affect the rest of the system.

I use Conda for this, but you can use whatever method is best for you. Note that I’m using Linux (WSL2 on Windows).

#create our test environment
(base) $ conda create -n wasm_test python=3.12 -y

# Now activate it
(base) $ conda activate wasm_test

Now that the environment is set up, we can install the required libraries and software.

# 
#
(wasm_test) $ pip install jupyter nest-asyncio

Enter now jupyter notebook Go to your command prompt. You should see your Jupyter laptop in your browser. If this does not happen automatically, you may jupyter notebook Order. Near the bottom, there will be a URL that you should copy and paste into your browser to start your Jupyter notebook.

Your URL is different from mine, but it should look like this: –

Code Example 1 – Hello World equivalent to use Pyodide

Let’s start with the simplest example. The easiest way to include a graduation in your HTML page is through a Content Delivery Network (CDN). Then we print out the text “Hello World!”




  
  Hello, World! with Pyodide


  
  
  


I ran the above code in W3SCHOOLS HTML TRITIT editor and got this code

Image of the author

When the button is clicked, Pyodide runs the Python code that prints “Hello, World!”. We can’t see anything printed on the screen because it is printed to the console by default. We will solve it in the following example.

Code Example 2 – Print Output to the Browser

In our second example, we will use Pyodide to run Python code in the browser, which will perform simple mathematical calculations. In this case, we will calculate the square root of 16 and output the result to the browser.




  
  Pyodide Example


  
  
  



Running the above code in W3Schools Tryit browser, I get this output.

Image of the author

Code Example 3 – Calling Python Functions from JavaScript

Another valuable and powerful feature of using Pyodide is the ability to call Python features from JavaScript and vice versa.

In this example, we create a Python function that performs simple mathematical operations (calculate the factorial of a number) and calls it from JavaScript code.




  
  Call Python from JavaScript


  
  
  
  


This is the sample output when running on W3Schools. This time I don’t include the code part, just the output.

Image of the author

Code Example 4 – Using Python libraries such as Numpy

Python’s power comes from its rich library ecosystem. With Pyodide, you can import and use popular libraries like Numpy for numerical calculations.

The following example demonstrates how to perform array operations using numpy in a browser. Using Numpy library pyodide.loadpackage Function.




  
  NumPy in the Browser


  
  
  


Image of the author

Code Example 5 – Using Python libraries such as Matplotlib

Another powerful aspect of running Python in a browser is the ability to generate visualizations. With Pyodide, you can create graphs dynamically using GUI libraries such as Matplotlib. This is how to generate and display a simple drawing on a canvas element.

In this example, we use matplotlib to create a quadratic plot (y = x²), save the image to a memory buffer as a png, and then encode it as a base64 string before displaying.




  
  Matplotlib in the Browser


  
  
  "conspiracy

  
  

Image of the author

Code Example 6: Run Python in Web Worker

For more complex applications, or if you need to make sure that heavy computing does not block the main UI thread, you can run Pyodide in Web Worker. Web workers allow you to run scripts in background threads, thus keeping your application responsive.

Here is an example of how to set up Pyodide in Web Worker. We perform calculations and simulate calculations running for a period of time, using that delay sleep() Function. We also display a constantly updated counter that shows the main UI functioning and normal response.

We need three files: – index.html file and two JavaScript files.

index.html




  
  Pyodide Web Worker Example


  
  
  

Status: Idle


Worker

// Load Pyodide from the CDN inside the worker
self.importScripts("

async function initPyodide() {
  self.pyodide = await loadPyodide();
  // Inform the main thread that Pyodide has been loaded
  self.postMessage("Pyodide loaded in Worker");
}

initPyodide();

// Listen for messages from the main thread
self.onmessage = async (event) => {
  if (event.data === 'start') {
    // Execute a heavy computation in Python within the worker.
    // The compute function now pauses for 0.5 seconds every 1,000,000 iterations.
    let result = await self.pyodide.runPythonAsync(`
import time
def compute():
    total = 0
    for i in range(1, 10000001):  # Loop from 1 to 10,000,000
        total += i
        if i % 1000000 == 0:
            time.sleep(0.5)  # Pause for 0.5 seconds every 1,000,000 iterations
    return total
compute()
    `);
    // Send the computed result back to the main thread
    self.postMessage("Computed result: " + result);
  }
};

main.js

// Create a new worker from worker.js
const worker = new Worker('worker.js');

// DOM elements to update status and output
const statusElement = document.getElementById('status');
const outputElement = document.getElementById('workerOutput');
const startButton = document.getElementById('startWorker');

let timerInterval;
let secondsElapsed = 0;

// Listen for messages from the worker
worker.onmessage = (event) => {
  // Append any message from the worker to the output
  outputElement.textContent += event.data + "n";

  if (event.data.startsWith("Computed result:")) {
    // When computation is complete, stop the timer and update status
    clearInterval(timerInterval);
    statusElement.textContent = `Status: Completed in ${secondsElapsed} seconds`;
  } else if (event.data === "Pyodide loaded in Worker") {
    // Update status when the worker is ready
    statusElement.textContent = "Status: Worker Ready";
  }
};

// When the start button is clicked, begin the computation
startButton.addEventListener('click', () => {
  // Reset the display and timer
  outputElement.textContent = "";
  secondsElapsed = 0;
  statusElement.textContent = "Status: Running...";
  
  // Start a timer that updates the main page every second
  timerInterval = setInterval(() => {
    secondsElapsed++;
    statusElement.textContent = `Status: Running... ${secondsElapsed} seconds elapsed`;
  }, 1000);
  
  // Tell the worker to start the heavy computation
  worker.postMessage('start');
});

To run this code, create all three files above and put them in the same directory on the local system. In this directory, enter the following command.

$ python -m http.server 8000

Now, in your browser, type this URL into it.

You should see a screen like this.

Image of the author

Now, if you press Start Computation Button, you should see a counter on the screen, starting at 1, ticking 1 per second until the calculation is finished and its final result is displayed – a total of about 5 seconds.

This shows that front-end logic and calculations are not bound by the work done by the Python code behind the buttons.

Image of the author

Code Example 7: Running a simple data dashboard

For our final example, I’ll show you how to run a simple data dashboard directly in your browser. Our source data will be synthetic sales data in the CSV file.

We need three files, all of which should be in the same folder.

sales_data.csv

The file I’m using has 100,000 records, but you can make this file as big or small as possible. These are the top twenty records that will give you an idea of ​​how the data looks.

Date,Category,Region,Sales
2021-01-01,Books,West,610.57
2021-01-01,Beauty,West,2319.0
2021-01-01,Electronics,North,4196.76
2021-01-01,Electronics,West,1132.53
2021-01-01,Home,North,544.12
2021-01-01,Beauty,East,3243.56
2021-01-01,Sports,East,2023.08
2021-01-01,Fashion,East,2540.87
2021-01-01,Automotive,South,953.05
2021-01-01,Electronics,North,3142.8
2021-01-01,Books,East,2319.27
2021-01-01,Sports,East,4385.25
2021-01-01,Beauty,North,2179.01
2021-01-01,Fashion,North,2234.61
2021-01-01,Beauty,South,4338.5
2021-01-01,Beauty,East,783.36
2021-01-01,Sports,West,696.25
2021-01-01,Electronics,South,97.03
2021-01-01,Books,West,4889.65

index.html

This is the main GUI interface of our dashboard.




    
    
    Pyodide Sales Dashboard
    
    



    

    
    
    
    

    

📈 Sales Data Visualization

"generate

📊 Sales Data Table

main.js

This contains our main Python Pyodide code.

async function loadPyodideAndRun() {
  const pyodide = await loadPyodide();
  await pyodide.loadPackage(["numpy", "pandas", "matplotlib"]);
  
  document.getElementById("analyzeData").addEventListener("click", async () => {
    const fileInput = document.getElementById("csvUpload");
    const selectedMetric = document.getElementById("metricSelect").value;
    const chartImage = document.getElementById("chartImage");
    const tableOutput = document.getElementById("tableOutput");
    
    if (fileInput.files.length === 0) {
      alert("Please upload a CSV file first.");
      return;
    }

    // Read the CSV file
    const file = fileInput.files[0];
    const reader = new FileReader();
    reader.readAsText(file);
    
    reader.onload = async function (event) {
      const csvData = event.target.result;
      
      await pyodide.globals.set('csv_data', csvData);
      await pyodide.globals.set('selected_metric', selectedMetric);
      
      const pythonCode = 
        'import sysn' +
        'import ion' +
        'import numpy as npn' +
        'import pandas as pdn' +
        'import matplotlibn' +
        'matplotlib.use("Agg")n' +
        'import matplotlib.pyplot as pltn' +
        'import base64n' +
        'n' +
        '# Capture outputn' +
        'output_buffer = io.StringIO()n' +
        'sys.stdout = output_buffern' +
        'n' +
        '# Read CSV directly using csv_data from JavaScriptn' +
        'df = pd.read_csv(io.StringIO(csv_data))n' +
        'n' +
        '# Ensure required columns existn' +
        'expected_cols = {"Date", "Category", "Region", "Sales"}n' +
        'if not expected_cols.issubset(set(df.columns)):n' +
        '    print("❌ CSV must contain 'Date', 'Category', 'Region', and 'Sales' columns.")n' +
        '    sys.stdout = sys.__stdout__n' +
        '    exit()n' +
        'n' +
        '# Convert Date column to datetimen' +
        'df["Date"] = pd.to_datetime(df["Date"])n' +
        'n' +
        'plt.figure(figsize=(12, 6))n' +
        'n' +
        'if selected_metric == "total_sales":n' +
        '    total_sales = df["Sales"].sum()n' +
        '    print(f"💰 Total Sales: ${total_sales:,.2f}")n' +
        '    # Add daily sales trend for total sales viewn' +
        '    daily_sales = df.groupby("Date")["Sales"].sum().reset_index()n' +
        '    plt.plot(daily_sales["Date"], daily_sales["Sales"], marker="o")n' +
        '    plt.title("Daily Sales Trend")n' +
        '    plt.ylabel("Sales ($)")n' +
        '    plt.xlabel("Date")n' +
        '    plt.xticks(rotation=45)n' +
        '    plt.grid(True, linestyle="--", alpha=0.7)n' +
        '    # Show top sales days in tablen' +
        '    table_data = daily_sales.sort_values("Sales", ascending=False).head(10)n' +
        '    table_data["Sales"] = table_data["Sales"].apply(lambda x: f"${x:,.2f}")n' +
        '    print("

Top 10 Sales Days

")n' + ' print(table_data.to_html(index=False))n' + 'elif selected_metric == "category_sales":n' + ' category_sales = df.groupby("Category")["Sales"].agg([n' + ' ("Total Sales", "sum"),n' + ' ("Average Sale", "mean"),n' + ' ("Number of Sales", "count")n' + ' ]).sort_values("Total Sales", ascending=True)n' + ' category_sales["Total Sales"].plot(kind="bar", title="Sales by Category")n' + ' plt.ylabel("Sales ($)")n' + ' plt.xlabel("Category")n' + ' plt.grid(True, linestyle="--", alpha=0.7)n' + ' # Format table datan' + ' table_data = category_sales.copy()n' + ' table_data["Total Sales"] = table_data["Total Sales"].apply(lambda x: f"${x:,.2f}")n' + ' table_data["Average Sale"] = table_data["Average Sale"].apply(lambda x: f"${x:,.2f}")n' + ' print("

Sales by Category

")n' + ' print(table_data.to_html())n' + 'elif selected_metric == "region_sales":n' + ' region_sales = df.groupby("Region")["Sales"].agg([n' + ' ("Total Sales", "sum"),n' + ' ("Average Sale", "mean"),n' + ' ("Number of Sales", "count")n' + ' ]).sort_values("Total Sales", ascending=True)n' + ' region_sales["Total Sales"].plot(kind="barh", title="Sales by Region")n' + ' plt.xlabel("Sales ($)")n' + ' plt.ylabel("Region")n' + ' plt.grid(True, linestyle="--", alpha=0.7)n' + ' # Format table datan' + ' table_data = region_sales.copy()n' + ' table_data["Total Sales"] = table_data["Total Sales"].apply(lambda x: f"${x:,.2f}")n' + ' table_data["Average Sale"] = table_data["Average Sale"].apply(lambda x: f"${x:,.2f}")n' + ' print("

Sales by Region

")n' + ' print(table_data.to_html())n' + 'elif selected_metric == "monthly_trends":n' + ' df["Month"] = df["Date"].dt.to_period("M")n' + ' monthly_sales = df.groupby("Month")["Sales"].agg([n' + ' ("Total Sales", "sum"),n' + ' ("Average Sale", "mean"),n' + ' ("Number of Sales", "count")n' + ' ])n' + ' monthly_sales["Total Sales"].plot(kind="line", marker="o", title="Monthly Sales Trends")n' + ' plt.ylabel("Sales ($)")n' + ' plt.xlabel("Month")n' + ' plt.xticks(rotation=45)n' + ' plt.grid(True, linestyle="--", alpha=0.7)n' + ' # Format table datan' + ' table_data = monthly_sales.copy()n' + ' table_data["Total Sales"] = table_data["Total Sales"].apply(lambda x: f"${x:,.2f}")n' + ' table_data["Average Sale"] = table_data["Average Sale"].apply(lambda x: f"${x:,.2f}")n' + ' print("

Monthly Sales Analysis

")n' + ' print(table_data.to_html())n' + 'n' + 'plt.tight_layout()n' + 'n' + 'buf = io.BytesIO()n' + 'plt.savefig(buf, format="png", dpi=100, bbox_inches="tight")n' + 'plt.close()n' + 'img_data = base64.b64encode(buf.getvalue()).decode("utf-8")n' + 'print(f"IMAGE_START{img_data}IMAGE_END")n' + 'n' + 'sys.stdout = sys.__stdout__n' + 'output_buffer.getvalue()'; const result = await pyodide.runPythonAsync(pythonCode); // Extract and display output with markers const imageMatch = result.match(/IMAGE_START(.+?)IMAGE_END/); if (imageMatch) { const imageData = imageMatch[1]; chartImage.src = 'data:image/png;base64,' + imageData; chartImage.style.display = 'block'; // Remove the image data from the result before showing the table tableOutput.innerHTML = result.replace(/IMAGE_START(.+?)IMAGE_END/, '').trim(); } else { chartImage.style.display = 'none'; tableOutput.innerHTML = result.trim(); } }; }); } loadPyodideAndRun();

Like the previous example, you can run this as follows. Create all three files and place them in the same directory on the local system. In this directory, on the command terminal, enter the following content,

$ python -m http.server 8000

Now, in your browser, type this URL into it.

Initially, your screen should look like this,

Image of the author

Click Choose File button and select the data file you created to enter the dashboard. After that, select the appropriate indicators Select Sales Metric Drop down the list and click Analyze data button. Depending on the options you choose to display, you should see something similar on the screen.

Image of the author

Summary

In this article, I described how to use Pyodide and WebAssembly, we can run Python programs in the browser and show some examples that prove this. I talked about the role of WebAssembly as a portable, high-performance assembly target that extends browser functionality and how it can be implemented in the Python ecosystem using third-party library Pyodide.

To illustrate the functionality and versatility of climbing disease, I provide several examples of uses, including: –

  • Basic “Hello, world!” example.
  • Call Python functions from JavaScript.
  • Use Numpy to perform numerical operations.
  • Use matplotlib to generate visualization.
  • Run Python code that computes heavy in web workers.
  • Data Dashboard

I hope that after reading this article, you will be like me, realizing the power of Python, Pyodide and web browsers.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button