![見出し画像](https://assets.st-note.com/production/uploads/images/38096423/rectangle_large_type_2_a9db6ec7133fe109f0a268597f563891.png?width=1200)
REST API
サプライチェイン最適化のためのいろいろな関数ををWeb APIで呼び出せると便利かと思い,作ってみた.いわゆるREST(Representational State Transfer) APIをというやつだ.
以前はFlaskとか使って面倒だったのだが,FastAPI というのを使うとドキュメントも同時にできる.ドキュメント化はちょうどしたかったので,ついでということだ.上に示した画面がブラウザに出てくる.
- FastAPI https://fastapi.tiangolo.com/ は, APIを構築するためのWebフレームワークである.
- pydantic https://github.com/samuelcolvin/pydantic/ は,FastAPI内で使われるJSON互換のデータ定義のためのモジュールである.
インストールは,fastapiとサーバーとして uvicorn http://www.uvicorn.org/ を必要とする.(pipでできる.)
例として,連続型施設配置の最適化関数(反復Weiszfeld法)を使う.
モデルクラスMelosGfは,顧客クラスCustomer,製品クラスProduct,総需要クラスTotalDemandから構成され,以下のように定義される.
class Customer(BaseModel):
name: str = Field(description="名称")
lat: float = Field(description="緯度")
lon: float = Field(description="経度")
class Config:
schema_extra = {
"example": {
"name": "響本店",
"lat": 43.06417,
"lon": 141.34694
}
}
class Product(BaseModel):
name: str = Field(description="名称")
average_demand: float = Field(description="平均需要量")
weight: float = Field(description="重量")
class Config:
schema_extra = {
"example": {
"name": "いちご大福",
"average_demand": 200.,
"weight": 0.2
}
}
class TotalDemand(BaseModel):
cust: str = Field(description="顧客名")
prod: str = Field(description="製品名")
demand: float = Field(description="需要量")
class Config:
schema_extra = {
"example": {
"cust": "響本店",
"prod": "いちご大福",
"demand": 20.
}
}
class MelosGf(BaseModel):
num_facilities: int = Field(1, description="施設数", gt=1)
epsilon: float = Field(0.00001, description="誤差", gt=0.)
max_iter: int = Field(10, description="最大反復数", gt=1)
seed: int = Field(1, description="乱数の種")
customers: List[Customer]= Field(description="顧客リスト", default=[])
products: List[Product] = Field(description="製品リスト", default=[])
total_demand: List[TotalDemand] = Field(description="総需要リスト", default=[])
サーバーサイドにモデルインスタンスを渡して,結果をJSONで戻す.
main.pyでFastAPIを動かすためのコードを記述してから,サーバーを起動する.
uvicorn main:app --reload
appはコード内で定義されたFastAPIのインスタンスである.
データを入れた辞書をJSONファイルに変換してサーバーに渡すと,サーバー側でモデルインスタンスに変換される.
それをもとに,最適化計算を行い,結果を返す.NumPyの配列が入っているとエラーするので,返り値はリストに変換しておく.するとFastAPIが勝手にJSONにしてくれる.
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from typing import List, Optional
from pydantic import BaseModel
app = FastAPI(
title="SCM OPT REST API",
description="Supply Chain Optimization Functions using REST API",
version="1.0.0",)
@app.put("/melosgf/")
def solve_melos_gf(model: MelosGf):
return solve_weiszfeld(model)
呼び出しは以下のように行う.元になるデータはデータフレームから変換して入れる.
import requests
test ={"num_facilities":5, "seed":1, "customers":cust_df.to_dict("records"), "products":prod_df.to_dict("records"),"total_demand":total_demand.to_dict("records")}
URL = "http://127.0.0.1:8000/melosgf"
r = requests.put(URL, data=json.dumps(test))
r.text
結果は以下のようになる.
'{"X":[35.01350991745481,36.654503169280886,33.09944338928921,35.47166691503066,39.64036433809142],"Y":[135.7644851375748,137.30155884486237,130.5265424716167,133.0504404534288,140.87199396073555],"partition":{"20":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"35":0,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"21":1,"34":2,"39":2,"40":2,"41":2,"42":2,"43":2,"44":2,"45":2,"46":2,"30":3,"31":3,"32":3,"33":3,"36":3,"37":3,"38":3,"0":4,"1":4,"2":4,"3":4,"4":4,"5":4,"6":4},"cost":126671550.60208969}'
この記事が気に入ったらサポートをしてみませんか?