pythonpython-3.xfastapi

FastAPI: Retrieve URL from view name ( route name )


Suppose I have following views,

from fastapi import FastAPI

app = FastAPI()


@app.get('/hello/')
def hello_world():
    return {"msg": "Hello World"}


@app.get('/hello/{number}/')
def hello_world_number(number: int):
    return {"msg": "Hello World Number", "number": number}

I have been using these functions in Flask and Django

So, how can I obtain/build the URLs of hello_world and hello_world_number in a similar way?


Solution

  • We have got Router.url_path_for(...) method which is located inside the starlette package

    Method-1: Using FastAPI instance

    This method is useful when you are able to access the FastAPI instance in your current context. (Thanks to @Yagizcan Degirmenci)

    from fastapi import FastAPI
    
    app = FastAPI()
    
    
    @app.get('/hello/')
    def hello_world():
        return {"msg": "Hello World"}
    
    
    @app.get('/hello/{number}/')
    def hello_world_number(number: int):
        return {"msg": "Hello World Number", "number": number}
    
    
    print(app.url_path_for('hello_world'))
    print(app.url_path_for('hello_world_number', number=1))
    print(app.url_path_for('hello_world_number', number=2))
    
    # Results
    
    "/hello/"
    "/hello/1/"
    "/hello/2/"
    

    Drawback

    Method-2: Request instance

    This method is useful when you are able to access the Request instance (the incoming request), usually, within a view.

    from fastapi import FastAPI, Request
    
    app = FastAPI()
    
    
    @app.get('/hello/')
    def hello_world():
        return {"msg": "Hello World"}
    
    
    @app.get('/hello/{number}/')
    def hello_world_number(number: int):
        return {"msg": "Hello World Number", "number": number}
    
    
    @app.get('/')
    def named_url_reveres(request: Request):
        return {
            "URL for 'hello_world'": request.url_for("hello_world"),
            "URL for 'hello_world_number' with number '1'": request.url_for("hello_world_number", number=1),
            "URL for 'hello_world_number' with number '2''": request.url_for("hello_world_number", number=2})
        }
    
    # Result Response
    
    {
        "URL for 'hello_world'": "http://0.0.0.0:6022/hello/",
        "URL for 'hello_world_number' with number '1'": "http://0.0.0.0:6022/hello/1/",
        "URL for 'hello_world_number' with number '2''": "http://0.0.0.0:6022/hello/2/"
    }
    

    Drawback