Path Parameters¶
Path parameters are those, as the name suggests, parameters that are part of a URL (path) definition.
You can declare the path parameters (you can think of them as variables) using the same python syntax for strings.
from esmerald import Esmerald, Gateway, JSONResponse, get
@get("/users/{user_id}")
async def read_user(user_id: str) -> JSONResponse: ...
app = Esmerald(
routes=[
Gateway(read_user),
]
)
As you can see, the user_id
declared in the path was also passed and provided in the function user
. This is how
you must declare path parameters in Esmerald.
You can now access the URL:
http://127.0.0.1/users/1
Declaration of the parameters¶
Esmerald being developed on top of Lilya also means that it allows two different syntaxes for the declaration of the parameters.
from esmerald import Esmerald, Gateway, JSONResponse, get
@get("/users/{user_id}")
async def read_user(user_id: str) -> JSONResponse: ...
app = Esmerald(
routes=[
Gateway(read_user),
]
)
from esmerald import Esmerald, Gateway, JSONResponse, get
@get("/users/<user_id>")
async def read_user(user_id: str) -> JSONResponse: ...
app = Esmerald(
routes=[
Gateway(read_user),
]
)
Esmerald allows the use of {}
and <>
syntaxes. Both work in an equal
way and the reasoning for that is only to
allow the users to choose their own preference.
Default parameters¶
When declaring a controller with path parameters, if no type is specified in the string
declaration, Esmerald will assume
it will be of type string
.
from esmerald import Esmerald, Gateway, JSONResponse, get
@get("/users/{user_id}")
async def read_user(user_id: str) -> JSONResponse: ...
app = Esmerald(
routes=[
Gateway(read_user),
]
)
If you wish to specifiy exactly the type for the path parameter, you can do it by liteally specifiying the type of the parameter.
from esmerald import Esmerald, Gateway, JSONResponse, get
@get("/users/{user_id:int}")
async def read_user(user_id: int) -> JSONResponse: ...
app = Esmerald(
routes=[
Gateway(read_user),
]
)
This will make sure it will enforce the type int
and throws an error if an invalid integer is provided.
When providing the path parameters with a proper typing, this will also make sure the OpenAPI documentation will have the right type for you to test.
Custom typing and transformers¶
What if you need to create a custom typing that is not natively supported by Esmerald? Well, Esmerald has your back with the transformers.
This will make sure you have your own transformer for your own unique typing and Esmerald can understand it.
Since Esmerald is built on top of Lilya, that means it also supports natively the same types.
You can check here for more details.
Enums¶
Esmerald also supports Enum
types as typing. Yes, that's right, natively Esmerald handles Enums for you. This will
trigger automatic validations of Esmerald in case a wrong value is provided.
from enum import Enum
from esmerald import Esmerald, Gateway, JSONResponse, get
class UserEnum(Enum):
user = "user"
admin = "admin"
@get("/users/{user_type}")
async def read_user(user_type: UserEnum) -> JSONResponse: ...
app = Esmerald(
routes=[
Gateway(read_user),
]
)
You can now call:
http://127.0.0.1/users/admin
If you, for example, provide something like this:
http://127.0.0.1/users/something
And since something
is not declared in the Enum type, you will get an error similar to this:
{
"detail": "Validation failed for http://127.0.0.1/users/something with method GET.",
"errors": [
{
"type": "enum",
"loc": ["item_type"],
"msg": "Input should be 'user' or 'admin'",
"input": "something",
"ctx": {"expected": "'user' or 'admin'"},
"url": "https://errors.pydantic.dev/2.8/v/enum",
}
],
}