import gradio as gr import wntr import traceback import tempfile import os import shutil def run_simulation (inp_file): try: # Create temporary working directory work_dir = tempfile.mkdtemp() inp_path = os.path.join(work_dir, "network.inp") # Save uploaded file to temp path shutil.copy(inp_file.name, inp_path) # Gradio returns a file path string (not a file object) wn = wntr.network.WaterNetworkModel(inp_file) sim = wntr.sim.EpanetSimulator(wn) results = sim.run_sim() # Extract node head values at time index 0 heads = results.node["head"].iloc[0] report = "\n".join( f"{node_id}: Head = {head:.2f} m" for node_id, head in heads.items() ) return report except Exception as e: tb = traceback.format_exc() return f"❌ Simulation failed:\n{e}\n\n{tb}" # Define Gradio interface iface = gr.Interface( fn=run_simulation, inputs=gr.File(label="Upload EPANET .inp file"), outputs="text", title="💧 EPANET Simulation Tool (Gradio + WNTR)", description="Upload a valid EPANET `.inp` file. This tool simulates hydraulic head at all nodes using the WNTR library.", allow_flagging="never" ) # Hugging Face Docker requires 0.0.0.0 and port 7860 if __name__ == "__main__": print("🚀 Gradio app is launching...") iface.launch(server_name="0.0.0.0", server_port=7860)