3

This code is for Flask

import requests
from flask import Flask,request,session,render_template, jsonify
import requests,time
from datetime import datetime,timedelta

app = Flask(__name__,template_folder='./')

@app.route('/')
def home():
    return render_template("For_putting_lat_lon.html")

@app.route('/distance') 
def check():
    Latitude1 = request.args.get("Latitude1")
    Latitude2 = request.args.get("Latitude2")  
    Longitude1 = request.args.get("Longitude1")
    Longitude2 = request.args.get("Longitude2")
    
    data = list()
    result = Travel_distance(Latitude1, Longitude1, Latitude2, Longitude2,data)
    
    if(result == 0):
        return render_template("noavailable.html")
    return render_template("For_posting_lat_lon.html",data = data)


def Travel_distance(Latitude1, Longitude1, Latitude2, Longitude2, data):
  geolocator = Nominatim(user_agent="geoapiExercises")
  location_name1 = geolocator.geocode(str(Latitude1)+", " +str(Longitude1))                                         
  location_name2 = geolocator.geocode(str(Latitude2)+", "+str(Longitude2))  
  req = requests.get(f"""http://router.project-osrm.org/route/v1/drive/{Longitude1},{Latitude1};{Longitude2},{Latitude2}?overview=false""") #car,bike,foot
  route_1 = json.loads(req.content)
  df_s = list()
  df_s.append(location_name1)  
  df_s.append(location_name2) 
  df_s.append(str((route_1['routes'][0]['distance'])/1000))    
  data.append(df_s) 


if __name__ == "__main__":
   app.run()

The below python code is in FastAPI. Here I'm trying to duplicate the above code, but I can't get request/input latitudes-longitudes, as when I run the code, it says latitude1 is not defined. Also, I think there is some error in the code, as the html template For_posting_lat_lon.html does not work when ran here, otherwise it works.

app = FastAPI()

!pip install uvicorn
import uvicorn
from fastapi import FastAPI, Form, Request
import asyncio
from pydantic import BaseModel

app= FastAPI()

templates = Jinja2Templates(directory='./')

@app.get("/" , response_class = HTMLResponse)
async def home(request: Request):
    return templates.TemplateResponse("For_putting_lat_lon.html",{"request":request})

        
@app.get("/distance" , response_class = HTMLResponse)
async def check(request: Request): 
    
    data = list()
    result = Travel_distance(Latitude1, Longitude1, Latitude2, Longitude2, data)
    
    if(result == 0):
        return templates.TemplateResponse("noavailable.html",{"request":request})
    return templates.TemplateResponse("For_posting_lat_lon.html",{"request":request})#,"Latitude1":Latitude1,"Longitude1":Longitude1,"Latitude2":Latitude2,"Longitude2":Longitude2})  


def Travel_distance(Latitude1, Longitude1, Latitude2, Longitude2, data):
  geolocator = Nominatim(user_agent="geoapiExercises")
  location_name1 = geolocator.geocode(str(Latitude1)+", " +str(Longitude1))                                          
  location_name2 = geolocator.geocode(str(Latitude2)+", "+str(Longitude2))  
  req = requests.get(f"""http://router.project-osrm.org/route/v1/drive/{Longitude1},{Latitude1};{Longitude2},{Latitude2}?overview=false""") #car,bike,foot
  route_1 = json.loads(req.content)
  df_s = list()
  df_s.append(location_name1)  
  df_s.append(location_name2) 
  df_s.append(str((route_1['routes'][0]['distance'])/1000))    
  data.append(df_s) 


nest_asyncio.apply()
uvicorn.run(app, port=8000)
Chris
  • 18,724
  • 6
  • 46
  • 80

2 Answers2

5

In FastAPI, you can fetch the query parameters by either declaring them in your endpoint (as described in FastAPI documentation), or by using the Request object, as described in Starlette documentation and demonstrated below. However, in this way, the data won't be validated, and hence, you have to make sure that the client sends all the required parameters and in the correct form (i.e., float data type). Related answers can be found here and here as well.

from fastapi import FastAPI, Request

app = FastAPI()

@app.get("/distance")
def check(request: Request): 
    Latitude1 = request.query_params['Latitude1']
    Latitude2 = request.query_params['Latitude2']
    #...

Note: Latitude1 is not equal to latitude1. Hence, if you pass the data in the URL as /distance?Latitude1=59.12&..., that means using capital 'L', then you should do the same when fetching the query params on server side (i.e., request.query_params['Latitude1']).

Also, please remember to pass the data object to your template (as you seem to be missing that):

return templates.TemplateResponse("For_posting_lat_lon.html",{"request":request, "data":data})

Alternative solutions can be found in this answer.

Chris
  • 18,724
  • 6
  • 46
  • 80
0

There is no need to fetch the parameters from the request object, you can define them directly in your view function and they'll be populated from the URL arguments:

from fastapi import FastAPI, Request


app = FastAPI()


@app.get("/distance")
async def check(Latitude1: float, Longitude1: float, Latitude2: float, Longitude2: float, request: Request): 
    return {
        'lat': Latitude1, 
        'lon': Longitude1, 
        'lat2': Latitude2, 
        'lon2': Longitude2,
    }

With the request:

/distance?Latitude1=59.12&Longitude1=11.32&Latitude2=59.18&Longitude2=11.58

Gives the expected output:

{"lat":59.12,"lon":11.32,"lat2":59.18,"lon2":11.58}
MatsLindh
  • 49,529
  • 4
  • 53
  • 84