Starlette: Support route convertors

Created on 6 Nov 2018  路  11Comments  路  Source: encode/starlette

Hi, I've just discovered starlette (seems to be the perfect asgi fw ! great)
Looking into docs/unitests ... but it seems that regex routing is not implemented yet (will look into the code)

Is it possible to declare something like that ?

@app.route("/api/{name:.*}")
def ...

It's the only thing it seems to miss (to quit aiohttp)

All 11 comments

We don't currently have any support for that, no.
And yes, it would be (very) good to do so.

I'm not sure exactly what we'd want to adopt here - if we should use something like flask's URL convertors, or if we should just use regexs. What existing different options do other frameworks currently use? Which options support type coercion, and which always return strings for the path parameters?

I don't known flask at all (I just know that it was a joke against bottle, at the begining ..)

I'm coming from bottle(wsgi) ( https://bottlepy.org/docs/dev/routing.html ). Bottle does type coercions.

And in asgi world: I use aiohttp ( https://aiohttp.readthedocs.io/en/stable/web_quickstart.html#resources-and-routes ), which just return strings.

But in all cases : you'll need to add a sort of "path/catchall" ... to let the developper parse the path as he wants.
Because, currently ; It's impossible to make an endpoint with an abritratry number of subpaths

Currently i do : (it's not pretty, and it works only for 6 ;-)

@app.route('/{p1}/{p2}/{p3}/{p4}/{p5}/{p6}')
@app.route('/{p1}/{p2}/{p3}/{p4}/{p5}')
@app.route('/{p1}/{p2}/{p3}/{p4}')
@app.route('/{p1}/{p2}/{p3}')
@app.route('/{p1}/{p2}')
@app.route('/{p1}')
@app.route('/')
async def gotopath(request):
    fullpath="/".join( request.path_params.values() )

I definitely prefer the type coercion approach. Most of the major frameworks support this and I suspect what most users are already familiar with.

A popular pattern seems to be the use of class converters a la werkzeug or falcon. This would be good approach if in the future we wanted to support custom converters. However, sanic drops straight into regex, which could be less code heavy but also not as organized

Because, currently ; It's impossible to make an endpoint with an abritratry number of subpaths

It's possible to declare your own regex.

@app.route("/(?P<path>.*)")

@Dith3r That's true actually, yeah. (Tho it won't work with request.url_for(...))

Great @Dith3r !

I will use that ! (you can close ;-)

I've retitled the issue with the feature that we'd actually like to have here. Converters for routes.

So, initially just making sure that we can support this kind of thing...

/{something:path} # Allow slashes in the path
/{user_id:int} # Coerced to an integer

How do I get a regex route to work?

@app.route("/base/{someid}/(?P<myvar>.*)")

this gives an error

apilibrary_1  |   File "/home/webapp/.local/share/virtualenvs/src-NCIGkioc/lib/python3.7/site-packages/starlette/routing.py", line 182, in matches
apilibrary_1  |     matched_params[key] = self.param_convertors[key].convert(value)
apilibrary_1  | KeyError: 'myvar'

Look at URL converters pull request. Only option is to extend converters array with ours specific one regex.

Don鈥檛. Just use :path for open ended stuff, and verify or 404 in the endpoint.

馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Immortalin picture Immortalin  路  3Comments

koddr picture koddr  路  6Comments

tomchristie picture tomchristie  路  3Comments

Ekuzkamaza picture Ekuzkamaza  路  3Comments

rlewkowicz picture rlewkowicz  路  3Comments