Flask: 'Float' converter in route not working

Created on 6 Sep 2011  路  21Comments  路  Source: pallets/flask

In Flask 0.7.2, I have a route defined as:

@app.route('/venues/<float:lat>/<float:lon>/<float:rad>/')

Trying to access that route at http://127.0.0.1/10/20/30 will produce a "404 Not Found" error. If you change the route to

@app.route('/venues/<lat>/<lon>/<rad>/')

or substitute int for float using the conversion notation, then the route works correctly.

Most helpful comment

That is a mistake. -32.234 is negative and is a float too, so it should definitely be accepted when calling <float:my_number>. Keeping this mistake alive by not wanting to break existing apps is a thing, but one cannot call it a proper behaviour. If this is by design, then the design is broken.

All 21 comments

That is by design. You have to access http://127.0.0.1/10.0/20.0/30.0

Why is the ".0" required? To keep URLs unique.

Okay. It's perhaps worth noting in the documentation for the next round, though -- ".0" may be the way Python distinguishes between int(10) and float(10), but it's not something one necessarily thinks of when constructing a URL. (The client talking to Flask may not be written in Python, after all!)

Also, the float converter apparently doesn't handle negative numbers: '/venues/37.64/-121.817/1.0/' also returns a 404 error. Is this also by design, or is it a genuine bug?

You can automatically handle 301 redirects and normalize urls.
Make them friendly for the user to edit. ;)

No URL converter accepts negative values by design currently, that however might be something we could make configurable as it comes up quite often.

Generally though you can customize app.url_map.converters with custom converters: http://werkzeug.pocoo.org/docs/routing/#custom-converters

I'm just here to say that the way negative numbers aren't recognised by the float converter tripped me up too (and googling about it brought me here).

Same here.

@mitsuhiko, "it comes up quite often" :)

Same issue with Python 3.3 and float:param with negative float numbers. I don't understand why it is not configurable yet or why is set by design in this way. I am using this for a API REST with coordinates and by design it is not acceptable for me with negative coordinate numbers

@app.route('/venues/<int:lat>/<int:lon>/<int:rad>/')
@app.route('/venues/<float:lat>/<float:lon>/<float:rad>/')

It works for integers and floats.

In order to receive coordinates in the URL with negative value, I usually use a workaround to receive as string and convert to float/int in the function/method associated with the route. In case of value ValueError, handle it as a bad parameter value. Example (simplest):

@application.route("/map/<string:latitude>/<string:longitude>")
def view_coords(latitude, longitude):
    try:
        latitude, longitude = float(latitude), float(longitude)
    except ValueError:
        abort(404)

The solution, I chose for this problem, is to pass float numbers as query
parameters and parse them with WTForms.
Looking back now I see that WTForms approach is much more suitable for my
application, because of agile validation rules and form inheritance.

The issue of negative floats not working in url routes with float converter, _ie:_ <float:lat>/<float:lng> not working also tripped me up for at least a full day, I did not find this thread until I had already figured it out my self. I had thought about converting negative signs to cardinal directions _ie:_ E for negative longitudes and S for negative latitude, but that seemed more work then just treating them as strings and coercing to float as @peterdemin ultimately did. Why are negative floats not converted? Such a bummer and clearly unexpected/unintuitive. C'est la vie!

Just to say that I just arrived here for the "negative floats not accepted" problem. What's the logic behind this decision ?

The "float" converter only matches \d+.\d+ (this is from werkzeug). So -12.3, 3., 1E+3 are not valid "floats" despite float(x) accepting them in Python; the "int" converter doesn't handle negatives either (regexp is \d+). Assuming logic is always the answer is a mistake... backward compatibility with early mistakes can be powerful.

That is not a mistake. We attempt to have only one way to represent a given number.

On 22 April 2017 09:53:43 GMT+02:00, Andrea Griffini notifications@github.com wrote:

The "float" converter only matches \d+.\d+ (this is from werkzeug).
So -12.3, 3., 1E+3 are not valid "floats" despite float(x)
accepting them in Python; the "int" converter doesn't handle negatives
either (regexp is \d+). Assuming logic is always the answer is a
mistake... backward compatibility with early mistakes can be powerful.

--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/pallets/flask/issues/315#issuecomment-296355921

--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

Regarding negative numbers, the most popular usecase is to allow only positive numbers. Calling those converters int might have been a mistake though

On 22 April 2017 09:53:43 GMT+02:00, Andrea Griffini notifications@github.com wrote:

The "float" converter only matches \d+.\d+ (this is from werkzeug).
So -12.3, 3., 1E+3 are not valid "floats" despite float(x)
accepting them in Python; the "int" converter doesn't handle negatives
either (regexp is \d+). Assuming logic is always the answer is a
mistake... backward compatibility with early mistakes can be powerful.

--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/pallets/flask/issues/315#issuecomment-296355921

--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

That is a mistake. -32.234 is negative and is a float too, so it should definitely be accepted when calling <float:my_number>. Keeping this mistake alive by not wanting to break existing apps is a thing, but one cannot call it a proper behaviour. If this is by design, then the design is broken.

Also just got tripped up by this. If the developers are unable to modify the existing int and float converters, could new converters be added / documented to account for this? Happy to submit a pull request!

Discussion is in Werkzeug, which is where the converters are implemented: https://github.com/pallets/werkzeug/issues/729

Please only post if you have something new to say about the issue. Constructive discussion and work towards a solution is appreciated.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tomjaguarpaw picture tomjaguarpaw  路  3Comments

maangulo12 picture maangulo12  路  4Comments

ghostbod99 picture ghostbod99  路  4Comments

davidhariri picture davidhariri  路  3Comments

davidism picture davidism  路  3Comments