Handlers¶
Handlers are part of the core of what makes Esmerald
and they are needed to build the APIs and the routing
of the application.
They provide a set of available parameters like status_code
, response_class
, include_in_schema
and many others.
HTTP handlers¶
There different http handlers representing the different HTTP Methods available and special one for special circumstances.
Warning
In every HTTP handler (get, post, put, patch, delete and route)
if a path
is not provided, it will default to /
.
GET¶
from esmerald import Esmerald, Gateway, JSONResponse, Request, get
@get()
async def example(request: Request) -> JSONResponse:
return JSONResponse({"message": "Welcome home!"})
@get(path="/another")
def another() -> str:
return "Another welcome!"
@get(path="/")
def another_read(name: str) -> str:
return f"Another welcome, {name}!"
app = Esmerald(
routes=[
Gateway(handler=example),
# you can the handlers also directly (they are automatically converted to Gateways)
another,
Gateway(path="/last/{name:str}", handler=another_read),
]
)
Default status code: 200
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
POST¶
from pydantic import BaseModel
from esmerald import Esmerald, Gateway, post
class Item(BaseModel):
sku: str
name: str
@post(path="/create")
def create(data: Item) -> None:
# Operations to create here
...
@post(path="/")
def another(name: str) -> str:
return f"Another welcome, {name}!"
app = Esmerald(
routes=[
Gateway(handler=create),
Gateway(path="/last/{name:str}", handler=another),
]
)
Default status code: 201
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
PUT¶
from esmerald import Esmerald, Gateway, JSONResponse, put
@put(path="/update/{item_id:int}")
def update(item_id: int) -> int:
return item_id
@put(path="/")
def another_update(item_id: int) -> JSONResponse:
return JSONResponse({"Success", {item_id}})
app = Esmerald(
routes=[
Gateway(handler=update),
Gateway(path="/last/{item_id:int}", handler=another_update),
]
)
Default status code: 200
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
PATCH¶
from esmerald import Esmerald, Gateway, Include, JSONResponse, patch
@patch(path="/partial/{item_id:int}")
def update(item_id: int) -> int:
return item_id
@patch(path="/")
def another_update(item_id: int) -> JSONResponse:
return JSONResponse({"Success", {item_id}})
app = Esmerald(
routes=[
Include(
"/update",
routes=[
Gateway("/update", handler=update),
Gateway(path="/last/{item_id:int}", handler=another_update),
],
)
]
)
Default status code: 200
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
DELETE¶
from esmerald import Esmerald, Gateway, Include, JSONResponse, delete
@delete(path="/{item_id:int}")
def delete_item(item_id: int) -> int:
# logic that deletes an item
...
@delete(path="/")
def another_delete(item_id: int) -> JSONResponse:
# logic that deletes an item
...
app = Esmerald(
routes=[
Include(
"/delete",
routes=[
Gateway(handler=delete_item),
Gateway(path="/last/{item_id:int}", handler=another_delete),
],
),
]
)
Default status code: 204
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
Route¶
from esmerald import Esmerald, Gateway, JSONResponse, Request, route
@route(methods=["GET", "POST"])
async def my_route(request: Request) -> JSONResponse:
return JSONResponse({"message": "Welcome home!"})
@route(path="/another", methods=["GET", "POST"])
def another_route() -> str:
return "Another welcome!"
@route(path="/", methods=["GET", "POST", "PUT", "PATCH"])
def last_route(name: str) -> str:
return f"Another welcome, {name}!"
@route(path="/", methods=["DELETE", "HEAD"])
def delete(name: str) -> str:
return f"Another welcome, {name}!"
app = Esmerald(
routes=[
Gateway(handler=my_route),
Gateway(handler=another_route),
Gateway(path="/last/{name:str}", handler=last_route),
Gateway(path="/delete", handler=delete),
]
)
Default status code: 200
@route
is a special handler because it is designed to allow more than one HTTP
handler in one go.
Sometimes you might want to have one Gateway that allows more than one HTTP operation but writing two different functions with roughly the same logic can be avoided by using this special handler.
Example:
from esmerald import Esmerald, Gateway, JSONResponse, Request, route
@route(methods=["GET", "POST", "PUT"])
async def multiple_methods_function(request: Request) -> JSONResponse:
method = request.method.upper()
if method == "GET":
return JSONResponse({"message": "I'm a GET!"})
elif method == "PUT":
return JSONResponse({"message": "I'm a PUT!"})
return JSONResponse({"message": "I'm a POST!"})
app = Esmerald(
routes=[
multiple_methods_function,
]
)
There are also three more unique and exotic ones:
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
HEAD¶
from esmerald import Esmerald, Gateway, JSONResponse, Request, head
@head()
async def example(request: Request) -> JSONResponse:
return JSONResponse({"message": "Welcome home!"})
@head(path="/another")
def another() -> str:
return "Another welcome!"
@head(path="/")
def another_read(name: str) -> str:
return f"Another welcome, {name}!"
app = Esmerald(
routes=[
Gateway(handler=example),
Gateway(handler=another),
Gateway(path="/last/{name:str}", handler=another_read),
]
)
Default status code: 200
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
OPTIONS¶
from esmerald import Esmerald, Gateway, JSONResponse, Request, options
@options()
async def example(request: Request) -> JSONResponse:
return JSONResponse({"message": "Welcome home!"})
@options(path="/another")
def another() -> str:
return "Another welcome!"
@options(path="/")
def another_read(name: str) -> str:
return f"Another welcome, {name}!"
app = Esmerald(
routes=[
Gateway(handler=example),
another,
Gateway(path="/last/{name:str}", handler=another_read),
]
)
Default status code: 200
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
TRACE¶
from esmerald import Esmerald, Gateway, JSONResponse, Request, trace
@trace()
async def example(request: Request) -> JSONResponse:
return JSONResponse({"message": "Welcome home!"})
@trace(path="/another")
def another() -> str:
return "Another welcome!"
@trace(path="/")
def another_read(name: str) -> str:
return f"Another welcome, {name}!"
app = Esmerald(
routes=[
Gateway(handler=example),
Gateway(handler=another),
Gateway(path="/last/{name:str}", handler=another_read),
]
)
Default status code: 200
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
HTTP handler summary¶
- Handlers are used alongside Gateway.
- There are
GET
,POST
,PUT
,PATCH
,DELETE
,HEAD
,OPTIONS
,TRACE
available to be used. - There is a
route
special to handle more than one HTTP method at once.
WebSocket handler¶
Websockets are different nature and widely used for applications where the communication between client and server needs usually to be constantly opened. More on websockets.
Warning
Due to the nature of websockets, Esmerald does a direct implementation of the WebSocket from Lilya which also
means no sync
functions.
WebSocket¶
from esmerald import Include, WebSocket, WebSocketGateway, websocket
from esmerald.applications import Esmerald
@websocket(path="/")
async def websocket_endpoint_switch(socket: WebSocket) -> None:
await socket.accept()
await socket.send_json({"URL": str(socket.path_for("websocket_endpoint"))})
await socket.close()
@websocket(path="/")
async def websocket_params_chat(socket: WebSocket, chat: str) -> None:
await socket.accept()
await socket.send_text(f"Hello, {chat}!")
await socket.close()
@websocket(path="/")
async def websocket_endpoint_include(socket: WebSocket) -> None:
await socket.accept()
await socket.send_text("Hello, new world!")
await socket.close()
@websocket(path="/")
async def websocket_endpoint(socket: WebSocket) -> None:
await socket.accept()
await socket.send_text("Hello, world!")
await socket.close()
@websocket(path="/")
async def websocket_params(socket: WebSocket, room: str) -> None:
await socket.accept()
await socket.send_text(f"Hello, {room}!")
await socket.close()
app = Esmerald(
routes=[
WebSocketGateway(path="/", handler=websocket_endpoint_switch, name="websocket_endpoint"),
WebSocketGateway("/ws", handler=websocket_endpoint, name="websocket_endpoint"),
WebSocketGateway("/ws/{room}", handler=websocket_params, name="ws-room"),
Include(
"/websockets",
routes=[
WebSocketGateway("/wsocket", handler=websocket_endpoint_include, name="wsocket"),
WebSocketGateway("/wsocket/{chat}", handler=websocket_params_chat, name="ws-chat"),
],
),
]
)
Parameters¶
All the parameters and defaults are available in the Handlers Reference.
WebSocket handler summary¶
- Handlers are used alongside WebSocketGateway.
- There is only one
websocket
handler available.