0

I am using FastApi for the API and HTML/CSS for the interface.

I want the click function for the button that returns me the wanted value (mt

means when I put node1 and node 2 it gets me its prediction from the JSON array.

This is my code:

This is the data list

prediction_data = [
  { "node1": 0, "node2": 1, "pred": 0},
  { "node1": 0, "node2": 476, "pred":0.352956 },
  { "node1": 0, "node2": 494, "pred":0.769988 },
  { "node1": 1, "node2": 505, "pred":0.463901 },
  { "node1": 9, "node2": 68 , "pred":1.238807},
  { "node1": 15, "node2": 408, "pred":0.204171 },
  { "node1": 18, "node2":549 , "pred":0.204171 },
  { "node1": 60, "node2": 227, "pred":0.204171 },
  { "node1": 199, "node2": 220, "pred":0.245246 },
  { "node1": 170, "node2": 570, "pred":0.509272 },
  { "node1": 148, "node2": 570, "pred":0.204171 },
  { "node1": 151, "node2": 384, "pred":0.204114 },
  { "node1": 232, "node2": 337, "pred":0.285999 },
  { "node1": 446, "node2": 509, "pred":0.291206 },
  { "node1": 510, "node2":576 , "pred":0.495378 },
  { "node1": 571, "node2":589 , "pred":0 },
  { "node1": 585, "node2":596 , "pred":0.245243 },
  { "node1": 446, "node2":509 , "pred":0.291206 },
  { "node1": 375, "node2":383 , "pred":0.46390 },
  { "node1": 461, "node2":462 , "pred":0 }
    ]

This the getter function of the wanted value

# Prediction
@app.get("/prediction/{node1,node2}", response_class=HTMLResponse)
async def gets(request: Request, node1: int, node2: int):
    matching = list(filter(lambda x: x['node1'] == node1 and x['node2'] == node2, prediction_data))
    mt = matching[0]['pred'] if matching else None
    return templates.TemplateResponse("Interface.html", {"request": request, "mt": mt})

This is the interface


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Link Prediction</title>
    <link href="{{ url_for('static', path='/style.css') }}" rel="stylesheet">
</head>

<body>
    <div class="container" >
        <h1>Link Prediction </h1>
        <h2>In Social Network</h2>
        <form class="form" action="#">
          <fieldset class="form-fieldset ui-input __first">
            <input type="number" id="Node1" tabindex="0" /> {{node1}}
            <label for="Node1">
              <span data-text="Node 1">Node 1</span>
            </label>
          </fieldset>
          
          <fieldset class="form-fieldset ui-input __second">
            <input  type="number" id="Node2" tabindex="0" /> {{node2}}
            <label for="Node2">
              <span data-text="Node 2">Node 2 </span>
            </label>
          </fieldset>

          <div class="form-footer">
            <button  onclick="myfunctionName(Node1, Node2)" class="btn">Predict Now</button>
          </div>

          <script type="text/javascript">
              
              function myfunctionName( n1,n2 ){
          
                  document.getElementById("Node1").innerHTML += n1;
                  document.getElementById("Node2").innerHTML += n2;
                  document.getElementById("Prediction") = mt;
              }
          
          </script>

<fieldset class="form-fieldset ui-input __third">
    <input type="text" id="Prediction" readonly/> {{mt}}
    <label for="Prediction">
      <span data-text="Prediction Result" >Prediction Result</span>
    </label>
  </fieldset>
          
        </form>
      </div>
</body>
</html>


tous
  • 29
  • 6

1 Answers1

0

To start with, you should have a look at how Path parameters work in FastAPI. The following in your code @app.get("/prediction/{node1,node2}" is not a valid route for passing path parameters. It will instead be recognised as a single path name. You can verify this by opening Swagger UI at http://127.0.0.1:8000/docs, which shows that the endpoint expects node1 and node2 to be query params, not path params. When submitting form data, one should use Form for that purpose, and POST HTTP method (your endpoint should be using @app.post()). Please take the time to read the documentation, as well as have a look at this answer. If you still, however, need this to be a GET request, you can use a GET operation @app.get() in your API, as well as define the method for your HTML form being method="GET". Below is an example demonstrating this.

In your API (access the main page at http://127.0.0.1:8000):

@app.get("/", response_class=HTMLResponse)
async def main(request: Request):
    return templates.TemplateResponse("predict.html", {"request": request})
    
@app.get("/predict", response_class=HTMLResponse)
async def predict(request: Request, node1: int, node2: int):
    matching = list(filter(lambda x: x['node1'] == node1 and x['node2'] == node2, prediction_data))
    mt = matching[0]['pred'] if matching else None
    return templates.TemplateResponse("predict.html", {"request": request, "node1": node1, "node2": node2, "mt": mt})

In your template (i.e., predict.html in this case)

<!DOCTYPE html>
<html lang="en">
   <body>
      <h1>Link Prediction </h1>
      <h2>In Social Network</h2>
      <form method="GET" action="/predict" id="myForm">
         node1 : <input type="text" name="node1" value={{node1}}> <br>
         node2 : <input type="text" name="node2" value={{node2}}><br>
         <input type="submit" value="Predict" >
      </form>
      Prediction Result: <b>{{mt}}</b>
   </body>
</html>
Chris
  • 4,940
  • 2
  • 7
  • 28