Fastapi: What does a star(*) mean in a method parameter?

Created on 26 Dec 2019  路  4Comments  路  Source: tiangolo/fastapi

Description

I was checking the documentation and saw this code:

from fastapi import FastAPI
from pydantic import BaseModel, EmailStr

app = FastAPI()

class UserIn(BaseModel):
    username: str
    password: str
    email: EmailStr
    full_name: str = None


# Don't do this in production!
@app.post("/user/", response_model=UserIn)
async def create_user(*, user: UserIn):
    return user

What does * mean in the following line:

async def create_user(*, user: UserIn):

question

Most helpful comment

Just to follow up on this, the most common reason you would want to make use of this functionality in a FastAPI context is when you want to include Depends-based injected arguments, or arguments with default values, before arguments without default values in your endpoint functions.

For example, this allows you to write an endpoint like:

@app.get("/")
def get_username(*, db: Session = Depends(get_db), user_id: int) -> str:
    return db.query(User).get(user_id).username

Without the *, you'd have to put db after user_id, which you might not want to do for consistency's sake with other endpoints.

(Using * also ensures keyword arguments are used everywhere, which may be otherwise desirable to help reduce issues during refactors, etc., but I personally find that unnecessary when mypy is involved.)

All 4 comments

@ramazanpolat this is a Python question, not a fastapi one. This asterisk is used for keyword-only arguments. Check here for more info: https://www.python.org/dev/peps/pep-3102/

Thanks @pmav99 I had the same question

Just to follow up on this, the most common reason you would want to make use of this functionality in a FastAPI context is when you want to include Depends-based injected arguments, or arguments with default values, before arguments without default values in your endpoint functions.

For example, this allows you to write an endpoint like:

@app.get("/")
def get_username(*, db: Session = Depends(get_db), user_id: int) -> str:
    return db.query(User).get(user_id).username

Without the *, you'd have to put db after user_id, which you might not want to do for consistency's sake with other endpoints.

(Using * also ensures keyword arguments are used everywhere, which may be otherwise desirable to help reduce issues during refactors, etc., but I personally find that unnecessary when mypy is involved.)

Thanks for the help here everyone! :clap: :bow:

Thanks for reporting back and closing the issue :+1:

There's a small section in the docs about that: https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#order-the-parameters-as-you-need-tricks

But still, in that specific example the * is not really needed, so we should update it as it's probably confusing.

I created https://github.com/tiangolo/fastapi/issues/1234 to handle this and update the docs, to avoid confusion.

Was this page helpful?
0 / 5 - 0 ratings