Add fastapi fastapi_run_project_return_dict to return the text version of simulation results
This commit is contained in:
@@ -1 +1 @@
|
|||||||
from .epanet import run_project, run_inp, dump_output
|
from .epanet import run_project, run_project_return_dict, run_inp, dump_output
|
||||||
@@ -238,7 +238,40 @@ def dump_output_binary(path: str) -> str:
|
|||||||
bast64_data = base64.b64encode(data)
|
bast64_data = base64.b64encode(data)
|
||||||
return str(bast64_data, 'utf-8')
|
return str(bast64_data, 'utf-8')
|
||||||
|
|
||||||
|
#DingZQ, 2025-02-04, 返回dict[str, Any]
|
||||||
|
def run_project_return_dict(name: str, readable_output: bool = False) -> dict[str, Any]:
|
||||||
|
if not project.have_project(name):
|
||||||
|
raise Exception(f'Not found project [{name}]')
|
||||||
|
|
||||||
|
dir = os.path.abspath(os.getcwd())
|
||||||
|
|
||||||
|
db_inp = os.path.join(os.path.join(dir, 'db_inp'), name + '.db.inp')
|
||||||
|
inp_out.dump_inp(name, db_inp, '2')
|
||||||
|
|
||||||
|
input = name + '.db'
|
||||||
|
exe = os.path.join(os.path.join(dir, 'epanet'), 'runepanet.exe')
|
||||||
|
inp = os.path.join(os.path.join(dir, 'db_inp'), input + '.inp')
|
||||||
|
rpt = os.path.join(os.path.join(dir, 'temp'), input + '.rpt')
|
||||||
|
opt = os.path.join(os.path.join(dir, 'temp'), input + '.opt')
|
||||||
|
command = f'{exe} {inp} {rpt} {opt}'
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
result = os.system(command)
|
||||||
|
if result != 0:
|
||||||
|
data['simulation_result'] = 'failed'
|
||||||
|
else:
|
||||||
|
data['simulation_result'] = 'successful'
|
||||||
|
if readable_output:
|
||||||
|
data |= _dump_output(opt)
|
||||||
|
else:
|
||||||
|
data['output'] = dump_output_binary(opt)
|
||||||
|
|
||||||
|
data['report'] = dump_report(rpt)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
# original code
|
||||||
def run_project(name: str, readable_output: bool = False) -> str:
|
def run_project(name: str, readable_output: bool = False) -> str:
|
||||||
if not project.have_project(name):
|
if not project.have_project(name):
|
||||||
raise Exception(f'Not found project [{name}]')
|
raise Exception(f'Not found project [{name}]')
|
||||||
|
|||||||
29
main.py
29
main.py
@@ -207,11 +207,34 @@ async def fastapi_run_project(network: str) -> str:
|
|||||||
raise HTTPException(status_code=409, detail="is in simulation")
|
raise HTTPException(status_code=409, detail="is in simulation")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
result = run_project(network)
|
return run_project(network)
|
||||||
return result
|
|
||||||
finally:
|
finally:
|
||||||
# 手动释放锁(可选,依赖过期时间自动释放更安全)
|
# 手动释放锁(可选,依赖过期时间自动释放更安全)
|
||||||
redis_client.delete(lock_key)
|
redis_client.delete(lock_key)
|
||||||
|
|
||||||
|
# DingZQ, 2025-02-04, 返回dict[str, Any]
|
||||||
|
# output 和 report
|
||||||
|
# output 是 json
|
||||||
|
# report 是 text
|
||||||
|
@app.get("/runprojectreturndict/")
|
||||||
|
async def fastapi_run_project_return_dict(network: str) -> dict[str, Any]:
|
||||||
|
lock_key = "exclusive_api_lock"
|
||||||
|
timeout = 120 # 锁自动过期时间(秒)
|
||||||
|
|
||||||
|
# 尝试获取锁(NX=True: 不存在时设置,EX=timeout: 过期时间)
|
||||||
|
acquired = redis_client.set(lock_key, "locked", nx=True, ex=timeout)
|
||||||
|
|
||||||
|
logger.info(f"acquired : {acquired}")
|
||||||
|
|
||||||
|
if not acquired:
|
||||||
|
raise HTTPException(status_code=409, detail="is in simulation")
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return run_project_return_dict(network)
|
||||||
|
finally:
|
||||||
|
# 手动释放锁(可选,依赖过期时间自动释放更安全)
|
||||||
|
redis_client.delete(lock_key)
|
||||||
|
|
||||||
|
|
||||||
# put in inp folder, name without extension
|
# put in inp folder, name without extension
|
||||||
@app.get("/runinp/")
|
@app.get("/runinp/")
|
||||||
@@ -1897,7 +1920,7 @@ async def upload_inp(afile: bytes, name: str ):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
@app.get("/downloadinp/", status_code=status.HTTP_200_OK)
|
@app.get("/downloadinp/", status_code=status.HTTP_200_OK)
|
||||||
async def download_inp(name: str, response: Response):
|
async def download_name: str, response: Response):
|
||||||
filePath = inpDir + name
|
filePath = inpDir + name
|
||||||
if os.path.exists(filePath):
|
if os.path.exists(filePath):
|
||||||
return FileResponse(filePath, media_type='application/octet-stream', filename="inp.inp")
|
return FileResponse(filePath, media_type='application/octet-stream', filename="inp.inp")
|
||||||
|
|||||||
@@ -211,6 +211,11 @@ def import_inp(name: str, cs: ChangeSet, version: str = '3') -> bool:
|
|||||||
def export_inp(name: str, version: str = '3') -> ChangeSet:
|
def export_inp(name: str, version: str = '3') -> ChangeSet:
|
||||||
return api.export_inp(name, version)
|
return api.export_inp(name, version)
|
||||||
|
|
||||||
|
#DingZQ, 2025-02-04, 返回dict[str, Any]
|
||||||
|
def run_project_return_dict(name: str) -> dict[str, Any]:
|
||||||
|
return epanet.run_project_return_dict(name)
|
||||||
|
|
||||||
|
# original code
|
||||||
def run_project(name: str) -> str:
|
def run_project(name: str) -> str:
|
||||||
return epanet.run_project(name)
|
return epanet.run_project(name)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user