diff --git a/docs/en/docs/tutorial/path-params.md b/docs/en/docs/tutorial/path-params.md index 6614dfdcb7..8909124799 100644 --- a/docs/en/docs/tutorial/path-params.md +++ b/docs/en/docs/tutorial/path-params.md @@ -2,7 +2,7 @@ You can declare path "parameters" or "variables" with the same syntax used by Python format strings: -{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *} +{_ ../../docs_src/path_params/tutorial001_py310.py hl[6:7] _} The value of the path parameter `item_id` will be passed to your function as the argument `item_id`. @@ -16,7 +16,7 @@ So, if you run this example and go to [http://127.0.0.1:8000/items/foo](http://1 You can declare the type of a path parameter in the function, using standard Python type annotations: -{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *} +{_ ../../docs_src/path_params/tutorial002_py310.py hl[7] _} In this case, `item_id` is declared to be an `int`. @@ -110,27 +110,27 @@ Several of these are explored in the next chapters of the tutorial. ## Order matters { #order-matters } -When creating *path operations*, you can find situations where you have a fixed path. +When creating _path operations_, you can find situations where you have a fixed path. Like `/users/me`, let's say that it's to get data about the current user. And then you can also have a path `/users/{user_id}` to get data about a specific user by some user ID. -Because *path operations* are evaluated in order, you need to make sure that the path for `/users/me` is declared before the one for `/users/{user_id}`: +Because _path operations_ are evaluated in order, you need to make sure that the path for `/users/me` is declared before the one for `/users/{user_id}`: -{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *} +{_ ../../docs_src/path_params/tutorial003_py310.py hl[6,11] _} Otherwise, the path for `/users/{user_id}` would match also for `/users/me`, "thinking" that it's receiving a parameter `user_id` with a value of `"me"`. Similarly, you cannot redefine a path operation: -{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *} +{_ ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] _} The first one will always be used since the path matches first. ## Predefined values { #predefined-values } -If you have a *path operation* that receives a *path parameter*, but you want the possible valid *path parameter* values to be predefined, you can use a standard Python `Enum`. +If you have a _path operation_ that receives a _path parameter_, but you want the possible valid _path parameter_ values to be predefined, you can use a standard Python `Enum`. ### Create an `Enum` class { #create-an-enum-class } @@ -140,7 +140,7 @@ By inheriting from `str` the API docs will be able to know that the values must Then create class attributes with fixed values, which will be the available valid values: -{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *} +{_ ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] _} /// tip @@ -148,33 +148,33 @@ If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine /// -### Declare a *path parameter* { #declare-a-path-parameter } +### Declare a _path parameter_ { #declare-a-path-parameter } -Then create a *path parameter* with a type annotation using the enum class you created (`ModelName`): +Then create a _path parameter_ with a type annotation using the enum class you created (`ModelName`): -{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *} +{_ ../../docs_src/path_params/tutorial005_py310.py hl[16] _} ### Check the docs { #check-the-docs } -Because the available values for the *path parameter* are predefined, the interactive docs can show them nicely: +Because the available values for the _path parameter_ are predefined, the interactive docs can show them nicely: -### Working with Python *enumerations* { #working-with-python-enumerations } +### Working with Python _enumerations_ { #working-with-python-enumerations } -The value of the *path parameter* will be an *enumeration member*. +The value of the _path parameter_ will be an _enumeration member_. -#### Compare *enumeration members* { #compare-enumeration-members } +#### Compare _enumeration members_ { #compare-enumeration-members } -You can compare it with the *enumeration member* in your created enum `ModelName`: +You can compare it with the _enumeration member_ in your created enum `ModelName`: -{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *} +{_ ../../docs_src/path_params/tutorial005_py310.py hl[17] _} -#### Get the *enumeration value* { #get-the-enumeration-value } +#### Get the _enumeration value_ { #get-the-enumeration-value } You can get the actual value (a `str` in this case) using `model_name.value`, or in general, `your_enum_member.value`: -{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *} +{_ ../../docs_src/path_params/tutorial005_py310.py hl[20] _} /// tip @@ -182,13 +182,13 @@ You could also access the value `"lenet"` with `ModelName.lenet.value`. /// -#### Return *enumeration members* { #return-enumeration-members } +#### Return _enumeration members_ { #return-enumeration-members } -You can return *enum members* from your *path operation*, even nested in a JSON body (e.g. a `dict`). +You can return _enum members_ from your _path operation_, even nested in a JSON body (e.g. a `dict`). They will be converted to their corresponding values (strings in this case) before returning them to the client: -{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *} +{_ ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] _} In your client you will get a JSON response like: @@ -201,15 +201,15 @@ In your client you will get a JSON response like: ## Path parameters containing paths { #path-parameters-containing-paths } -Let's say you have a *path operation* with a path `/files/{file_path}`. +Let's say you have a _path operation_ with a path `/files/{file_path}`. -But you need `file_path` itself to contain a *path*, like `home/johndoe/myfile.txt`. +But you need `file_path` itself to contain a _path_, like `home/johndoe/myfile.txt`. So, the URL for that file would be something like: `/files/home/johndoe/myfile.txt`. ### OpenAPI support { #openapi-support } -OpenAPI doesn't support a way to declare a *path parameter* to contain a *path* inside, as that could lead to scenarios that are difficult to test and define. +OpenAPI doesn't support a way to declare a _path parameter_ to contain a _path_ inside, as that could lead to scenarios that are difficult to test and define. Nevertheless, you can still do it in **FastAPI**, using one of the internal tools from Starlette. @@ -217,17 +217,17 @@ And the docs would still work, although not adding any documentation telling tha ### Path convertor { #path-convertor } -Using an option directly from Starlette you can declare a *path parameter* containing a *path* using a URL like: +Using an option directly from Starlette you can declare a _path parameter_ containing a _path_ using a URL like: ``` /files/{file_path:path} ``` -In this case, the name of the parameter is `file_path`, and the last part, `:path`, tells it that the parameter should match any *path*. +In this case, the name of the parameter is `file_path`, and the last part, `:path`, tells it that the parameter should match any _path_. So, you can use it with: -{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *} +{_ ../../docs_src/path_params/tutorial004_py310.py hl[6] _} /// tip @@ -241,11 +241,29 @@ In that case, the URL would be: `/files//home/johndoe/myfile.txt`, with a double With **FastAPI**, by using short, intuitive and standard Python type declarations, you get: -* Editor support: error checks, autocompletion, etc. -* Data "parsing" -* Data validation -* API annotation and automatic documentation +- Editor support: error checks, autocompletion, etc. +- Data "parsing" +- Data validation +- API annotation and automatic documentation And you only have to declare them once. That's probably the main visible advantage of **FastAPI** compared to alternative frameworks (apart from the raw performance). + +### Path Parameters with Validation { #path-params-validation } + +You can also add validation to your path parameters using Path. + +For example, you can define minimum and maximum allowed values: + +{_ ../../docs_src/path_params/tutorial006_py310.py hl[6] _} + +In this example: + +ge=1 means the value must be greater than or equal to 1 + +le=1000 means the value must be less than or equal to 1000 + +If a request is made with a value outside this range, FastAPI will automatically return a validation error. + +This helps ensure that invalid data is rejected early and improves the reliability of your API. diff --git a/docs_src/path_params/tutorial006_py310.py b/docs_src/path_params/tutorial006_py310.py new file mode 100644 index 0000000000..083be07c43 --- /dev/null +++ b/docs_src/path_params/tutorial006_py310.py @@ -0,0 +1,7 @@ +from fastapi import FastAPI, Path + +app = FastAPI() + +@app.get("/items/{item_id}") +def read_item(item_id: int = Path(..., ge=1, le=1000)): + return {"item_id": item_id} \ No newline at end of file