skip to Main Content

I need to insert Python code so that it reads two variables from the data entry windows in HTML, as well as two excel files, runs the code when the button is clicked, and outputs the result of the program to a special .
How can this be done?

I tried using two frameworks Flask and Py Script. It is not possible to make the Python code take data and excel tables from the input windows and output the result to an html page.

df and df1 should read from the HTML page from the windows id="file-input-1" and id="file-input-2", respectively. your_choice from id="pipeline-input", and your_choice_year from id="data-input". when you click on the id="runCodeButton" button, the python code should be triggered and output the result result to the page

from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/')
def index():
return render_template('index.html')

@app.route('/calculate', methods=['POST'])
def calculate():
df = pd.read_excel(request.files['file-input-1'], index_col=0)
df1 = pd.read_excel(request.files['file-input-2'], index_col=0)
your_choice = request.form['pipeline-input']
your_choice_year = int(request.form['data-input'])

name_list = df.index.tolist()

def f(your_choice, df, df1, name_list, your_choice_year):
...........
return render_template('index.html', result=result)

if __name__ == '__main__':
app.run(debug=True)

2

Answers


  1. You definitely don’t need PyScript for this task. Here is an example how to upload two excel files from html page to the python code using Flask and process it using Pandas.

    app.py:

    from flask import Flask, app, render_template, request
    import pandas as pd
    
    app = Flask(__name__)
    
    
    def do_some_stuff(*args):
        return 42
    
    
    @app.route("/", methods=["GET", "POST"])
    def calculate():
        if request.method == "POST":
            excel_file_1 = request.files["file-input-1"]
            if excel_file_1.filename == "":
                return render_template(
                    "index.html", error_message="No file-input-1 input provided"
                )
            df1 = pd.read_excel(excel_file_1, index_col=0)
    
            excel_file_2 = request.files["file-input-2"]
            if excel_file_2.filename == "":
                return render_template(
                    "index.html", error_message="No file-input-2 input provided"
                )
            df2 = pd.read_excel(excel_file_2, index_col=0)
    
            result = do_some_stuff(df1, df2)
    
            return render_template("index.html", result=result)
        return render_template("index.html")
    
    
    app.run(host="0.0.0.0", port=8081)
    

    As @detlef correctly mentioned you should use name attribute of the <input> instead of id.
    index.html:

    <!doctype html>
    <title>Calculator</title>
    <html lang="en">
    
    <body>
        {% if error_message %}
        Error: {{error_message}}
        {% endif %}
        <form action="/" method=post enctype="multipart/form-data">
            <input type=file name=file-input-1>
            <input type=file name=file-input-2>
            <input type=submit value=Upload>
        </form>
        Result: {{ result if result else "No result yet"}}
    </body>
    
    </html>
    

    Note, this is not good solution but only the example how to deal with files in flask. Use flashing rather to pass error to the template. Read how to correctly save files in flask especially part about secure_filename. I have repeated myself twice for file reading logic but this code should be generalized to some function. This code simply calls pd.read_excel but it would be better to handle any possible errors here and notify user about it.

    Login or Signup to reply.
  2. It is indeed possible to use PyScript to handle Excel files in the browser, if you choose to go that route. Here’s an example with two upload <input>s and a button that prints the size of both:

    <!-- index.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <link rel="stylesheet" href="https://pyscript.net/releases/2023.05.1/pyscript.css">
        <script defer src="https://pyscript.net/releases/2023.05.1/pyscript.js"></script>
    </head>
    <body>
        <br><label for="file-1">Upload a first Excel file</label>
        <input type="file" id="file-1">
    
        <br><label for="file-2">Upload a second Excel file</label>
        <input type="file" id="file-2">
    
        <br><button py-click="calculate()">Click to Calculate</button>
    
        <py-config>
            packages = ['pandas', 'openpyxl']
        </py-config>
    
        <script type="py" src="test.py">
        </script>
    </body>
    </html>
    
    from js import document, Uint8Array
    from pyodide.ffi.wrappers import add_event_listener
    
    import pandas as pd
    
    async def storeFile(evt):
        file_list = evt.target.files
        first_item = file_list.item(0)
    
        #Get the data from the files arrayBuffer as an array of unsigned bytes
        array_buf = Uint8Array.new(await first_item.arrayBuffer())
    
        #IO wants a bytes-like object, so convert to bytearray first
        bytes_list = bytearray(array_buf)
    
        #Write the contents of the uploaded file to a file in the virtual FS that looks like "{id}.xls"
        file_name = evt.target.id + ".xls"
        with open(file_name, "wb") as f:
            f.write(bytes_list)
    
    def calculate(*args):
        df = pd.read_excel("file-1.xls", index_col=0)
        df1 = pd.read_excel("file-2.xls", index_col=0)
        print(f"{df.size=}")
        print(f"{df1.size= }")
    
    #Hook up event listeners to the inputs
    add_event_listener(document.getElementById("file-1"), "change", storeFile)
    add_event_listener(document.getElementById("file-2"), "change", storeFile)
    

    Note that this is a very minimal example – there’s no error handling around what happens if one/both of the files don’t exist, are unparsable, etc.

    Note too that this is for the current release of PyScript (2023.05.1 at time of writing). An upcoming release changes a bit about how the py-[event] syntax works, but not much else.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search