iyume
iyume

Reputation: 127

FastAPI: Retrieve the endpoint for jinja2 `url_for` to give a jump link

Function description

In flask this code:

@app.route('/')
def index():
    return ...

or

foo_router = Blueprint('foo', __name__)
@foo_router.route('/')
def index():
    return ...

app.register_blueprint(foo_router, url_prefix='/api')

These ways you are able to use url_for('index') to retrieve url like https://hostname:8080/

or use url_for('foo.index') to retrive url like https://hostname:8080/api/foo

Desired function

Use url_for for jump link in fastapi like flask

Additional context

I have found a trick to do the implement

create url_naming.py and add the code below

from starlette.routing import Mount, Route

from .routers.foo.endpoints.area import index as foo_area_index

foo_router_for = Mount('/', routes=[
    Route('/area', foo_area_index, name='foo_area.index'),
])

and in your main.py add

from .url_naming import foo_router_for

app.add_route('/foo', foo_router_for, name='foo_area.index')

In the codeblocks, I define name twice because which name I defined in a Route model cannot be detected by FastAPI, or it is overridden by FastAPI, and this impl make no sense because it is required to write down the real router name rather than the endpoint function name.

Despite that, what if I'd like to name my router in one file, which do not make effect on main.py?

Upvotes: 4

Views: 4389

Answers (1)

iyume
iyume

Reputation: 127

I solve the problem with the following solution.

Just to name your handle function (endpoint) and the name can be normally used by url_for.

router = APIRouter(prefix='/api')

@router.get('/foo')
async def api_foo():
    return ...

This way you can retrieve the url http://hostname:8080/api/foo/ using url_for('api_foo').

I guess this is because all the handle functions in FastAPI are named in the same space, and if they are named in FastAPI repeatedly, no error will be reported.

Upvotes: 7

Related Questions