profundusman
profundusman

Reputation: 69

How can I run my python file on the web via pyodide

I have written a python code with which I can get the bluetooth data of the surrounding Devices. I need to run this code on the browser and it should be able to see the data of the surrounding ibeacon devices when everyone is requested by the client. Way too many for that I tried but failed. I thought that I should use pyodide as a last resort, and at the moment I want to run python code with which I get the blutooth data of the surrounding devices with pyodide.

1-) First, the index.i have included the pyodide cdn in the html file 2-) Then pyodide.i created the js file and wrote the following codes in it

async function main(){
    let pyodide = await loadPyodide();
    await pyodide.runPythonAsync(`
    from pyodide.http import pyfetch
    response = await pyfetch("beacon.py")
    with open("beacon.py", "wb") as f:
        f.write(await response.bytes())
`)
pkg = pyodide.pyimport("main()");
pkg.do_something();
}
main();

3-) From the outside in this code beacon.py i want to include the file and beacon.py i want to run the main() function in it. This is beacon.py codes

import asyncio
from uuid import UUID
import json 
from construct import Array, Byte, Const, Int8sl, Int16ub, Struct
from construct.core import ConstError

from bleak import BleakScanner
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData


ibeacon_format = Struct(
    "type_length" / Const(b"\x02\x15"),
    "uuid" / Array(16, Byte),
    "major" / Int16ub,
    "minor" / Int16ub,
    "power" / Int8sl,
)
class UUIDEncoder(json.JSONEncoder):
        def default(self, uuid):
            if isinstance(uuid, UUID):
                # if the obj is uuid, we simply return the value of uuid
                return uuid.hex
            return json.JSONEncoder.default(self, uuid)
def device_found(
    device: BLEDevice, advertisement_data: AdvertisementData
):
    """Decode iBeacon."""
    try:
        macadress = device.address
        name = advertisement_data.local_name
        apple_data = advertisement_data.manufacturer_data[0x004C]
        ibeacon = ibeacon_format.parse(apple_data)
        uuid = UUID(bytes=bytes(ibeacon.uuid))
        minor = ibeacon.minor 
        major = ibeacon.major 
        power = ibeacon.power
        rssi = device.rssi
        rssi = int(rssi)

        # beacons = { 
        #     "Mac Adress" : macadress,
        #     "Local Name" : name ,
        #     "UUID":uuid,
        #     "Major":major,
        #     "Minor":minor,
        #     "TX Power":power,
        #     "RSSI":rssi
        # } 

        print(f"Mac Adress : {macadress}")
        print(f"Local Name : {name}")
        print(f"UUID     : {uuid}")
        print(f"Major    : {major}")
        print(f"Minor    : {minor}")
        print(f"TX power : {power} dBm")
        print(f"RSSI     : {rssi} dBm")
        print(47 * "-") 
                
    except KeyError:
        pass
    except ConstError:
        pass

async def main():
    """Scan for devices."""
    scanner = BleakScanner()
    scanner.register_detection_callback(device_found)

    
    while (True):
        await scanner.start()
        await asyncio.sleep(0.5)
        await scanner.stop()
        
asyncio.run(main())

4-) Normally Beacon.py all the libraries in the file are installed, but I get the following error

File "/home/pyodide/beacon.py", line 4, in <module>
    from construct import Array, Byte, Const, Int8sl, Int16ub, Struct
ModuleNotFoundError: No module named 'construct'

5-) I don't know why I'm getting this error. I hope I was able to explain my problem well. Beacon.py how can I include the main() function in the file in pyodide via pyodide and how can I run this code on the web?

Upvotes: 0

Views: 651

Answers (1)

rth
rth

Reputation: 11201

Pyodide runs in the browser sandbox, which does not allow to interact with drivers in general (and Bluetooth devices in particular) directly. So you will not be able to use the bleak package from Pyodide.

You can however access Bluetooth devices via the Web Bluetooth API which you can use from Python using the Pyodide FFI.

As to the ImportError about construct, that package needs to be compiled for the emscripten/wasm32 architecture and currently is not included in the Pyodide distribution. You can build the corresponding wheel yourself with these instructions

Upvotes: 2

Related Questions