Answer a question

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

  • Flask: url_for(...)
  • Django: reverse(...)

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

Answers

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

  • If we are using APIRouter, router.url_path_for('hello_world') may not work since router isn't an instance of FastAPI class. That is, we must have the FastAPI instance to resolve the URL

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

  • We must include the request parameter in every (or required) view to resolve the URL, which might raise an ugly feel to developers.
Logo

Python社区为您提供最前沿的新闻资讯和知识内容

更多推荐