PyScript: is it possible to execute an uploaded Python script?

Question:

Is it possible to have a user upload an arbitrary Python script (that uses built-ins only, no external packages) and then execute it using PyScript?

Asked By: SultanOrazbayev

||

Answers:

You can use an HTML <input> element to upload the file, and use await file.txt() to get the source. Then there are a couple ways to execute the code.

Using Python’s exec() method:

<script defer src="https://pyscript.net/releases/2022.12.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2022.12.1/pyscript.css">

<input type="file" id="file-upload">

<py-script>
    import js
    from pyodide.ffi.wrappers import add_event_listener

    async def upload_and_run(event):
        file_list = event.target.files
        first_item = file_list.item(0)

        src = await first_item.text()
        exec(src)

    input_elem = js.document.getElementById("file-upload")
    add_event_listener(input_elem, "change", upload_and_run);
</py-script>

Or, if you want the script to behave like a <py-script> tag, with pretty error handling and such, you could add source to a new <py-script> tag:

<script defer src="https://pyscript.net/releases/2022.12.1/pyscript.js"></script>
<link rel="stylesheet" href="https://pyscript.net/releases/2022.12.1/pyscript.css">

<input type="file" id="file-upload">

<py-script>
    import js
    from pyodide.ffi.wrappers import add_event_listener

    async def upload_as_script_tag(event):
        file_list = event.target.files
        first_item = file_list.item(0)

        src = await first_item.text()
        newTag = js.document.createElement("py-script")
        newTag.innerText = src
        js.document.body.appendChild(newTag)

    input_elem = js.document.getElementById("file-upload")
    add_event_listener(input_elem, "change", upload_as_script_tag);
</py-script>
</body>
Answered By: Jeff Glass
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.