

元々コマンドライン上で実行していたPythonスクリプトをWebアプリケーションとして実装しようと考えています。  
このファイルには複数の引数を入力する必要があるため、formに入力した値を引数として渡して実行できるようにしたいです。

Webアプリケーションを作成するのは初めてのため、学習コストが少ないと言われているFlaskを利用しようと考えています。  
おそらくflask_restfulとWTFormsを使用すればできると思うのですが、実装例などを教えていただけないでしょうか。


CC BY-SA 4.0
2023-07-13T08:27:57.423
95589
2023-07-19T02:36:29.447
37404
question
python flask
flaskで複数の引数を要求するpythonスクリプトを実行する方法


「元々コマンドライン上で実行していたPythonスクリプト」を動かしたい, ものとして  
Colabでの方法と, JupyterLab (Jupyter Notebook, colab 含む) 方法を示します

> この質問の意図としては複数の引数を要求するpythonスクリプトに、ブラウザ経由で引数を渡す方法が知りたかった

のコメントに応えたもので, Flask の回答ではありません  
マイナス評価している人は, その **理由を示して** ください

* * *

#### Colabでの方法

Colabメニューの[挿入][フォームの項目の追加] からフォームの項目を指定できます  
(あるいは セルの 「︙」メニューから同様に指定可能)

[code]

    uname = 'value' #@param {type:"string"}
    opt = '1st option' #@param ["1st option", "2nd option", "3rd option"]
    age = 30 #@param {type:"number"}
    weight = 38.9 #@param {type:"slider", min:30, max:120, step:0.1}
    
    fn(uname, opt, age, weight)
    
[/code]

[![Colab
forms](https://i.stack.imgur.com/zZ8hS.png)](https://i.stack.imgur.com/zZ8hS.png)

#### JupyterLab (Colabなども含む) での方法

[Jupyter Widgets](https://ipywidgets.readthedocs.io/en/stable/) が利用できます  
以下の関数 `f`は値が変わるたびに呼び出されるので, 問題があるなら `Button()`配置し 押されたときに実行するとよいでしょう  
また, `interactive` と `f` のキーワードは同じ名前の必要があり, 注意するところかも

[code]

    from ipywidgets import interact, interactive, fixed, interact_manual
    import ipywidgets as widgets
    
    def f(uname, opt, age, weight):
        print(uname)
    
    interactive(f, uname='---',
                   opt=['1st', '2nd', '3rd'],
                   age=widgets.IntText(30),
                   weight=50)
    
[/code]

[![IPyWidgets](https://i.stack.imgur.com/NwBjW.png)](https://i.stack.imgur.com/NwBjW.png)

* * *

「コマンドライン上で実行していたPythonスクリプト」が Colabや Jupyterで動かせるかどうかは分からないけど,
もしも動かすことができない場合は質問にそれらの情報記すとよいでしょう


CC BY-SA 4.0
2023-07-17T08:45:18.023
95659
2023-07-17T10:41:52.630
2023-07-17T10:41:52.630
43025
43025
95589
answer


質問の趣旨としては、簡易的であってもWebサーバを立て、その中でFlaskなどのWebアプリを動作させることが主な趣旨でしょうか。  
そして外部端末のWebブラウザからWebアプリを呼び出して、いつでも特定のPythonスクリプトを実行できることが目的と考えて回答いたします。

pythonでWebアプリを作成するフレームワークは複数あります。  
その中から学習コストが低いものをいくつか紹介します。  
下記の他にも様々なフレームワークがありますので、他を検討しても良いでしょう。  
cf:
[PythonでWebアプリ作れるやつのまとめ(8選)](https://zenn.dev/neka_nat/articles/f2f5b6ebeb049a)

# Flask

Flaskのチュートリアルで触れたであろう`Post`処理の中で「複数の引数を要求するpythonスクリプトに引数を渡」せばブラウザ経由でスクリプトを実行できます。  
下記は`my_script.py`の`calculate_bmi`関数に引数を渡して戻り値を表示するFlaskのコード例です。  
`app.py`と`my_script.py`を同一フォルダに配置して実行してください。

**my_script.py**

[code]

    def calculate_bmi(height, weight):
        bmi = weight / ((height/100) ** 2)
        return bmi
    
[/code]

**app.py**

[code]

    from flask import Flask, request
    from my_script import calculate_bmi
    
    app = Flask(__name__)
    
    @app.route('/', methods=['GET'])
    def get():
        return """ 
    <!DOCTYPE html>
    <html>
    <head>
        <title>BMI Calculator</title>
    </head>
    <body>
        <h1>BMI計算機</h1>
        <form action="/" method="POST">
            <label for="height">身長(cm):</label>
            <input type="text" name="height" id="height" required><br><br>
            <label for="weight">体重(kg):</label>
            <input type="text" name="weight" id="weight" required><br><br>
            <input type="submit" value="計算">
        </form>
    </body>
    </html>
    """ 
    
    @app.route('/', methods=['POST'])
    def post():
        height = float(request.form['height'])
        weight = float(request.form['weight'])
        bmi = calculate_bmi(height, weight)
        return f""" 
    <!DOCTYPE html>
    <html>
    <head>
        <title>BMI Result</title>
    </head>
    <body>
        <h1>BMI計算結果</h1>
        <p>あなたのBMIは {bmi} です。</p>
    </body>
    </html>
    """ 
    
    if __name__ == '__main__':
        app.run()
    
[/code]

# Bottle

[Bottle](https://bottlepy.org/docs/dev/)というフレームワークも同様に使えます。  
極めてシンプルな仕組みで、個人的に使用しているので紹介します。  
`pip install bottle`でインストール可能です。  
`app.py`と`my_script.py`を同一フォルダに配置して`python app.py`のように実行してください。

**my_script.py**  
上記と同様

**app.py**

[code]

    from bottle import route, run, request
    from my_script import calculate_bmi
    
    @route('/')
    def get():
        return '''
            <h1>BMI計算機</h1>
            <form action="/" method="POST">
                <label for="height">身長(cm):</label>
                <input type="text" name="height" id="height" required><br><br>
                <label for="weight">体重(kg):</label>
                <input type="text" name="weight" id="weight" required><br><br>
                <input type="submit" value="計算">
            </form>
        '''
    
    @route('/', method='POST')
    def post():
        height = float(request.forms.get('height'))
        weight = float(request.forms.get('weight'))
        bmi = calculate_bmi(height, weight)
        return f'''
            <h1>BMI計算結果</h1>
            <p>あなたのBMIは {bmi} です。</p>
        '''
    
    if __name__ == '__main__':
        run(host='localhost', port=8080, debug=True)
    
[/code]

# Streamlit

htmlを一度も入力せずにWebアプリを作成するフレームワークとして[Streamlit](https://streamlit.io/)がお勧めです。  
簡単な静的サイトであれば、html/css/javascriptを一切使わずにpythonだけで構築可能です。  
`pip install streamlit`でインストール可能です。  
`app.py`と`my_script.py`を同一フォルダに配置して`streamlit run app.py`のように実行してください。

**my_script.py**  
上記と同様

**app.py**

[code]

    import streamlit as st
    from my_script import calculate_bmi
    
    def main():
        st.title("BMI計算機")
        height = st.number_input("身長(cm)", min_value=1.0, max_value=300.0, step=0.1, value=160.0)
        weight = st.number_input("体重(kg)", min_value=1.0, max_value=500.0, step=0.1, value=60.0)
    
        if st.button("計算"):
            bmi = calculate_bmi(height, weight)
            st.write(f"あなたのBMIは {bmi:.2f} です。")
    
    if __name__ == '__main__':
        main()
    
[/code]


CC BY-SA 4.0
2023-07-19T02:36:29.447
95684
2023-07-19T02:36:29.447
9820
95589
answer