6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FortranAdvent Calendar 2022

Day 6

Fortran+FastAPIで数値解析webAPIを生やす

Posted at

Fortran+FastAPIで数値解析webAPIを生やす

Fortranユーザの方々は主に科学技術計算を行うアプリケーションを実装されているかと思います.
アプリケーションをブラウザ/API経由で行えると,外部のアプリケーションとの連携ができて嬉しいです.
ここでは,FastAPIによりFortranにwebAPIを生やす方法を概説します.

1. Fortranの入出力をJSONに対応させ,コマンドライン引数でJSON形式ファイルを指定できるようにする.

WebAPI経由でFortranに入力データを受け渡す際には,JSON形式を使うと便利です.

use your_module
implicit none

type(Your_object) :: your_object
character(256) :: json_file_name

call get_command_argument(number=1,value=json_file_name)
your_object = your_object%initialize(json_file=json_file_name)

!!! call some operations !!!
call your_object%execute_something()

call your_object%export_json_file(json_flle=trim(json_file_name)//".result.json")

end

2. FastAPIでオンラインフォームを作成し,ユーザからの入力を受け付ける(必須ではない).

(content headerにbootstrapを使用していますが,省略しています.)


@app.get("/your_api/createjsonfile")
async def get_json_form():
    content = """
<h2>Online json editor </h2><br>
<form class="form-group" action="/your_api/download_new_json" method="get">

    <div class="col-auto">
        arg1 (integer) 
        <input name="arg1" type="text"  class="form-control" value="1">
    </div>

    <div class="col-auto">
        arg2 (real32)
        <input name="arg2" type="text"  class="form-control" value="1.00">
    </div>
...
    <div class="col-auto">
        Download from here!
        <input type="submit" value="Download">
    </div>

</form>

    """
    return HTMLResponse(content=content)


3. FastAPIでアクセスポイントを作成し,フォームから情報を受け取り保存する.

あらかじめ,working directoryでテンプレート(以下のyour_template.json)を作成しておく.

@app.get("/your_api/download_new_json/")
async def download_new_json(arg1: str, arg2: str):

    current = Path()
    filename = "your_template.json"
    file_path = current / filename
    
    with open(file_path, 'r') as fcc_file:
        fcc_data = json.load(fcc_file)
        fcc_data["arg1"] = int(arg1)
        fcc_data["arg2"] = float(arg2)
        
    new_filename = "download_"+str(uuid.uuid4())+"_bridge.json"
    f = open(new_filename,"w")
    f.write((json.dumps(fcc_data, indent=4)))
    f.close()

    file_path = current / new_filename
    response = FileResponse(
        path=file_path,
        filename=f"{new_filename}"
        )
    
    return response

4. FastAPIでjsonファイルのuploadを受け,ビルド済みの実行ファイルを呼び出し,処理を行い,jsonファイルをローカルに保存してから,結果ファイルのダウンロードページへを遷移する.

(Fortran側の結果ファイルの名前を,[入力ファイル名].result.jsonとしたことに留意)


@app.post("/your_api/execute_fortran/")
async def create_upload_files(files: List[UploadFile] = File(...),
    ):
    for file in files:
        filename = 'uploaded_'+str(uuid.uuid4()) +'.json'
        f = open(filename, 'wb+')
        print(type(file.file) )
        fileobj = file.file
        shutil.copyfileobj(fileobj, f)
        f.close()
        sts = subprocess.Popen("./a.out " + filename , shell=True)
    content = """
<html>

<body>


<form class="row g-3" action="/your_api/downloadfile/" method="get">
    <div class="col-auto">
        <input type="hidden" name="filename" value="""+filename+".result.json"+ """>
        <input type="submit" class="btn btn-primary mb-2" value="Download output file as .json">
    </div>
</form>

</body>
</html>
    """    
    return HTMLResponse(content=content)



@app.get("/your_api/downloadfile")
async def get_file(filename: str):
    current = Path()
    if not filename.endswith(".json"):
        return {"status": "error"}
    file_path = current / filename
    
    response = FileResponse(
        path=file_path,
        filename=f"download_{filename}"
        )
    
    return response


APIのデプロイ

こちらを参照してください.

実装例

ボックスカルバート自動生成API

補足

上記の通り実装したAPIはあくまで簡易的なものです.
公開するためには,アクセス制御を行ったり,認証を実装したりするなどの工夫が要ります.
LANやVPN内での運用を推奨します.

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?