Erich Purpur
Erich Purpur

Reputation: 1529

python Flask - The requested URL was not found on the server. (But why?)

Honestly, I am not sure what question I should ask here. Maybe someone can edit my title to be more descriptive?

I have a python flask app that sometimes returns:

The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

There is a pattern as to when this happens but I cannot figure out why it happens.

I have a home page where the user clicks a marker on google maps and then clicks a hyperlink "see forecast" button, which takes them to a weather forecast page: enter image description here

In my main python file (equivalent to index.py) I create the route for this next page as follows:

@app.route("/weather_forecast/<climbing_area>/<city_id>/<lat>/<lon>/<weather_site>")    #creates url using climbing area name, city id, lat, lon, and location of weather site
def weather_forecast(climbing_area, city_id, lat, lon, weather_site):

    return render_template('weather_forecast.html', 
                       climbing_area=climbing_area, 
                       city_id=city_id, 
                       daily_forecast=wf.format_daily_forecast(city_id), 
                       extended_forecast=wf.format_extended_forecast(city_id), 
                       historical_forecast=wf.get_historical_weather(lat, lon),
                       dates=wf.get_date_range(),
                       lat=lat,
                       lon=lon,
                       weather_site=weather_site,
                       sites=db.create_site_list_sqlite(),
                       api_key=os.environ.get('GOOGLE_MAPS_JS_API_KEY'),
                       image_url=wf.image_choice(lat, lon, city_id))

So as you see, there are many markers on the map and like 95% of them do the correct thing and go to a weather forecast page upon click. But a few of them do not. They consistently do not work.

The URL for each weather forecast site is dynamically generated by this template:

/weather_forecast/<climbing_area>/<city_id>/<lat>/<lon>/<weather_site>

These are variables returned from the /home page route. My first thought was: because these are dynamically generated variables from the back end (SQLite), maybe there is no data returned for those specific sites and this causes the page to fail? But I have verified for these select few sites that the data is available.

This URL works:

http://localhost:5000/weather_forecast/Humboldt%20County/5558953/41.03/-124.113/Arcata

This URL does not work:

http://localhost:5000/weather_forecast/Mount%20Yonah/Tallulah%20Gorge/4188197/34.637/-83.72200000000001/Clarkesville

I don't expect a magic code fix but can someone advise as to what else I could look for? Or what other information would be helpful to include in my question.

Upvotes: 2

Views: 1426

Answers (3)

Erich Purpur
Erich Purpur

Reputation: 1529

I found the solution. It turns out I was passing a bad URL without knowing it.

This URL worked: http://localhost:5000/weather_forecast/Humboldt%20County/5558953/41.03/-124.113/Arcata

This URL did not work: http://localhost:5000/weather_forecast/Mount%20Yonah/Tallulah%20Gorge/4188197/34.637/-83.72200000000001/Clarkesville

The difference is this, in my weather_forecast() function, I created my route like this: @app.route("/weather_forecast/<climbing_area>/<city_id>/<lat>/<lon>/<weather_site>")

The reason why just a few of my sites (and URLs) failed is because the <climbing_area> variable had a / character in it, in the database record. So for example if the <climbing_area> = Mount Yonah/Tallulah Gorge, this added an extra / character into my URL, causing it to fail.

I could have figured out how to make flask accept the literal / character. But in this case I just changed my <climbing_area> names to remove the /. Problem solved.

Upvotes: 0

cizario
cizario

Reputation: 4254

i guess, you need to set the right field and the right precision to store google maps lat and lon as per this thread

in your model try this:

..

    lat = db.Column(db.Numeric(22, 16), nullable=False)
    lon = db.Column(db.Numeric(22, 16), nullable=False)

# or 

    lat = db.Column(db.DECIMAL(22, 16), nullable=False)
    lon = db.Column(db.DECIMAL(22, 16), nullable=False)

..

and i want to suggest you reviewing the code of weather_forecast() function, it returns a data that can be calculated in weather_forecast.html template using the same parameters like image_url

@app.route("/weather_forecast/<climbing_area>/<city_id>/<lat>/<lon>/<weather_site>")
def weather_forecast(climbing_area, city_id, lat, lon, weather_site):

..
    sites=db.create_site_list_sqlite()

..
    return render_template('weather_forecast.html', 
                       climbing_area=climbing_area, 
                       city_id=city_id, 
                       lat=lat,
                       lon=lon,
                       weather_site=weather_site,

                       sites=sites,  # to keep things coherent 
                       
                       wf=wf)

instead of sending

                       daily_forecast=wf.format_daily_forecast(city_id), 
                       extended_forecast=wf.format_extended_forecast(city_id), 
                       historical_forecast=wf.get_historical_weather(lat, lon),
                       dates=wf.get_date_range(),
                       image_url=wf.image_choice(lat, lon, city_id)

just send the wf object and in weather_forecast.html template just use it like:

<img src="{{ wf.image_choice(lat, lon, city_id) }}" atl="">

also you don't need to send api_key since you can get it directly from global config object in your template like

{{ config.GOOGLE_MAPS_JS_API_KEY }}

Upvotes: 1

Anuj Gupta
Anuj Gupta

Reputation: 558

The URL allowed is : /weather_forecast/<climbing_area>/<city_id>/<lat>/<lon>/<weather_site>

You may be trying to access the URL:

/weather_forecast/<climbing_area>/<city_id>/<lat>/<lon>/<weather_site>/

There's a slash in the end of the URL. Since the URL in the flask code doesn't have the slash in the end, it will throw the error.

Also, please post the URL that you're hitting. That'll help providing more accurate solutions.

Upvotes: 1

Related Questions