The Form¶
This is a special way of sending a form directly using Esmerald. The Form
like the
File, inherits from the Body and applies the special
media_type
as application/x-www-form-urlencoded
.
This also means that you can also use the Body
directly to send a form with your API by simply
declaring Body(media_type="application/x-www-form-urlencoded")
.
The Form is a simple and cleaner shortcut for it.
The simplest way is by importing the Form
object from Esmerald.
from typing import Any, Dict
from esmerald import Esmerald, Form, Gateway, post
@post("/create")
async def create_user(data: Dict[str, Any] = Form()) -> None:
"""
Creates a user in the system and does not return anything.
Default status_code: 201
"""
app = Esmerald(routes=[Gateway(handler=create_user)])
You can also import via:
from esmerald.params import Form
As explained here, the handler is expecting a data
field declared and from there
you can pass more details about the form.
Examples¶
You can send the form in many different formats, for example:
- A dictionary - Send as normal dictionary.
- A dataclass - Send as normal dataclass.
- A pydantic dataclass - Send a pydantic dataclass.
- Pydantic model - Send a pydantic BaseModel.
You decide the best format to send. For the following examples, we will be using httpx
for the
requests for explanatory purposes.
Sending as dictionary¶
from typing import Any, Dict
import httpx
from esmerald import Esmerald, Form, Gateway, post
@post("/create")
async def create(data: Dict[str, str] = Form()) -> Dict[str, str]:
"""
Creates a user in the system and does not return anything.
Default status_code: 201
"""
return data
app = Esmerald(routes=[Gateway(handler=create)])
# Payload example
data = {"name": "example", "email": "example@esmerald.dev"}
# Send the request
httpx.post("/create", data=data)
As you can see, we declared the return signature to be Dict[str, str]
and the data
payload to
be a dictionary also Dict[str, str]
. This way we acn simply send the form as you would normally
do.
A dataclass¶
What if you want to type as a dataclass and return it in your response?
from dataclasses import dataclass
import httpx
from esmerald import Esmerald, Form, Gateway, post
@dataclass
class User:
name: str
email: str
@post("/create")
async def create(data: User = Form()) -> User:
"""
Creates a user in the system and does not return anything.
Default status_code: 201
"""
return data
app = Esmerald(routes=[Gateway(handler=create)])
# Payload example
data = {"name": "example", "email": "example@esmerald.dev"}
# Send the request
httpx.post("/create", data=data)
The way the payload is sent to the API will always be the same no matter what, what is important
is how you actually type it. In this example, we declared a User
dataclass with two field
name
and email
and we return exactly what we sent back into the response.
Pydantic dataclass¶
A Pydantic dataclass is the same as a normal python dataclass in the end but with some internal extras from Pydantic but for Esmerald, it is the same.
import httpx
from pydantic.dataclasses import dataclass
from esmerald import Esmerald, Form, Gateway, post
@dataclass
class User:
name: str
email: str
@post("/create")
async def create(data: User = Form()) -> User:
"""
Creates a user in the system and does not return anything.
Default status_code: 201
"""
return data
app = Esmerald(routes=[Gateway(handler=create)])
# Payload example
data = {"name": "example", "email": "example@esmerald.dev"}
# Send the request
httpx.post("/create", data=data)
Pydantic model¶
What if we want to type and return as a Pydantic model? Well, it behaves exactly the same as the dataclasses.
import httpx
from pydantic import BaseModel
from esmerald import Esmerald, Form, Gateway, post
class User(BaseModel):
name: str
email: str
@post("/create")
async def create(data: User = Form()) -> User:
"""
Creates a user in the system and does not return anything.
Default status_code: 201
"""
return data
app = Esmerald(routes=[Gateway(handler=create)])
# Payload example
data = {"name": "example", "email": "example@esmerald.dev"}
# Send the request
httpx.post("/create", data=data)
Notes¶
As you could see from the examples, it is very simple and direct to use the Form
in Esmerald and
the returns are simply clean.
Important¶
Since Form
is Pydantic field (sort of), that also means you can specify for instance,
the other parameters to be evaluated.
You can check the list of available parameters default as well.