Routage HTTP
Starlette dispose d'un système de routage des demandes simple mais puissant. les tables de routage sont définies comme des listes de routage et sont passées lorsqu 'une application est instanciée.
de starlette. applications import Starlette
from starlette.responses import PlainTextResponse
de starlette.routing Route d'importation
async def homepage (demande):
return PlainTextResponse ("Accueil ")
async def about (demande):
return PlainTextResponse ("À propos ")
Routes =[
Route ("/", endpoint = homepage),
Route ("/about ", endpoint = about),
]
app = Starlette (routes = routes)
endpoint Les paramètres peuvent être l'un des suivants:
- Une fonction régulière ou asynchrone qui prend un seul argument
requestet devrait retourner une réponse. - Une classe qui implémente une interface ASGI, par exemple HTTPendpoint de Starlette.
Paramètres de chemin
Les chemins peuvent utiliser le style de modèle URI pour capturer les composants de chemin.
Route ('/users/{username}', user)
Par défaut, cela capture les caractères jusqu'à la fin du chemin ou jusqu'à la prochaine /.
Vous pouvez utiliser des convertisseurs pour modifier ce qui est capturé. les convertisseurs disponibles sont:
strUne chaîne est renvoyée et est la valeur par défaut.intRetourne un entier Python.floatRenvoie un nombre à virgule flottante Python.uuidRenvoie une instance de Pythonuuid.UUID.pathRenvoie le reste du chemin, y compris les caractères/supplémentaires.
Le convertisseur est utilisé en le précédant d'un deux-points, comme suit:
Route('/users/{user_id:int}', user)
Route('/floating-point/{number:float}', floating_point)
Route('/uploaded/{rest_of_path:path}', uploaded)
Si vous avez besoin d'un convertisseur différent non défini, vous pouvez créer le vôtre. voir l'exemple ci-dessous pour savoir comment créer un convertisseur datetime et comment l'enregistrer:
de datetime import datetime
depuis starlette.convertors import Convertor, register_url_convertor
Classe DateTimeConverter (Converter):
regex = "[0-9]{4}-[0-9]{2}-[0- 9]{2}T[0- 9]{2}:[0 - 9]{2}:[0 - 9]{2}(.[0-9]+)"
def convert(self, valeur: str) -> datetime:
return datetime.strptime(valeur, "%Y-%m-%dT%H:%M:%S")
def to_string(self, valeur: datetime) -> str:
return value.strftime("%Y-%m-%dT%H:%M:%S")
register_url_convertor("datetime", DateTimeConvertor()))
Une fois inscrit, vous pourrez l'utiliser comme:
Route('/histoire/{date:datetime}', histoire)
Le paramètre chemin est disponible dans la requête, comme un dictionnaire request.path_params.
async def user(demande):
user_id = request.path_params ['user_id']
...
Travailler avec la méthode HTTP
Le routage peut également spécifier quelles méthodes HTTP sont gérées par le point final:
Route('/users/{user_id:int}', user, methods=["GET", "POST"])
Par défaut, le point de terminaison de la fonction n'acceptera que les requêtes GET, sauf indication contraire.
Câblage d'installation pour sous-base
Dans les grandes applications, vous constaterez peut-être que vous souhaitez diviser des parties de la table de routage en fonction des préfixes de chemin communs.
Routes = [
Route('/', homepage),
Mount('/users', routes=[
Route('/', users, methods=[' GET ', 'POST']),
Route('/{username}', user),
])
]
Ce style vous permet de définir différents sous-ensembles de tables de routage dans différentes parties du projet.
de myproject import users, auth
Routes = [
Route('/', homepage),
Mount('/users', routes=users.routes),
Mount('/auth', routes=auth.routes),
]
Vous pouvez également utiliser le montage pour inclure des sous-applications dans votre application Starlette. par exemple…
#Ceci est un serveur de fichiers statiques standard:
app = StaticFiles(directory="static")
#Ceci est un serveur de fichiers statiques monté dans une application Starlette,
# underneath the "/static" path.
Routes = [
...
Mount("/static", app=StaticFiles(directory="static"), name="static")
]
app = Starlette(routes=routes)
Recherche d'URL inversée
Vous voudrez généralement être en mesure de générer des URL pour des itinéraires spécifiques, par exemple dans le cas où une réponse de redirection doit être retournée.
-
Signé par:
url_for(name, **path_params) -> URLroutes = [ Route("/", page d'accueil, nom ="homepage") ]
Nous pouvons utiliser ce qui suit pour renvoyer une URL…
url = request.url_for("Accueil")
Une recherche d'URL peut contenir un paramètre de chemin "
Routes = [
Route("/users/{username}", user, name="user_detail")
]
#Nous pouvons utiliser le following pour retourner une URL...
url = request.url_for("user_detail", username=...)
Si une personne est Mount Contient une name La base doit être utilisée {prefix}:{name} Style pour une recherche d'URL inversée.
Routes = [
Mount("/users", nom ="users", routes=[
Route("/", user, name="user_list"),
Route("/{username}", user, name="user_detail")
])
]
#Nous pouvons utiliser le suivi pour retourner les URLs...
url = request.url_for("users:user_list")
url = request.url_for("users:user_detail", username=...)
L'application installée peut contenir un paramètre path=....
Routes = [
...
Mount("/static", app=StaticFiles(directory="static"), name="static")
]
#Nous pouvons utiliser le suivi pour retourner les URLs...
url = request.url_for("static", path="/css/base.css")
Pour les cas où il n'y a pas d'instance request, vous pouvez effectuer des recherches inversées pour les applications, bien que ces recherches ne renvoient que le chemin d'URL.
url = app.url_path_for("user_detail", username=...)
Routage basé sur hôte
Si vous souhaitez utiliser un itinéraire différent pour le même chemin en fonction de l'en-tête Host.
Veuillez noter que lors du match, il y aura une variation de Host supprimer le port dans l'en-tête. par exemple, même si Host L'en-tête contient ou ne contient pas d'exception 3600 ( example.org:5600 , example.org les ports extérieurs, Host (host='example.org:3600', ...) sont également traitées. ainsi, si vous êtes en url_for Un port doit être utilisé, vous pouvez le spécifier.
Il existe plusieurs façons de connecter le routage basé sur l'hôte à votre application.
site = Router() #Utiliser eg.`@site.route()` pour configure ceci.
api = Router() # Use eg. `@api.route()` Configurer cela.
news = Router() # Use eg.`@news.route()` pour configurer ceci.
Routes = [
Host('api.example.org', api, name="site_api")
]
app = Starlette(routes=routes)
app.host (www.example.org, site, nom ="main_site")
news_host = Host('news.example.org', news)
app.router.routes.append(news_host)
Une requête URL peut contenir des paramètres d'hôte, comme les paramètres de chemin.
Routes = [
Host("{subdomain}. example.org", nom ="sub", app=Router(routes=[]
Mount("/users", nom ="users", routes=[
Route("/", user, name="user_list"),
Route("/{username}", user, name="user_detail")
])
]))
]
...
url = request.url_for("sub:users:user_detail", username=..., subdomain=...)
url = request.url_for("sub:users:user_list", subdomain=...)
priorité de routage
Les chemins entrants sont appariés à chaque Route dans l'ordre.
Dans les cas où il peut y avoir plusieurs itinéraires qui correspondent au chemin entrant, vous devriez prendre soin de vous assurer que les itinéraires plus spécifiques sont répertoriés avant le cas général.
Par exemple:
# Don't do this:`/users/me` ne correspondra jamais aux demandes entrantes.
Routes = [
Route('/users/{username}', user),
Route('/users/me', current_user),
]
#Faites ceci:`/users/me` est testé en premier.
Routes = [
Route('/users/me', current_user),
Route('/users/{username}', user),
]
Travailler avec des instances de routeur
Si vous travaillez à un niveau inférieur, vous voudrez peut-être utiliser une instance normale de Router plutôt que de créer une application Starlette, ce qui vous donne une application ASGI légère qui fournit uniquement le routage de l'application sans l'envelopper dans un middleware.
app = Router(routes=[
Route('/', homepage),
Mount('/users', routes=[
Route('/', users, methods=[' GET ', 'POST']),
Route('/{username}', utilisateur)
])
])
Routage avec WebSocket
Lorsque vous utilisez des points de terminaison WebSocket, vous devez utiliser WebSocketRoute au lieu de l'habituel Route.
Les paramètres de chemin, ainsi que les recherches d'URL inversées pour WebSocketRoute, fonctionnent de la même manière que HTTP Route, que vous pouvez trouver dans la section Routage HTTP ci-dessus.
de starlette.applications import Starlette
de starlette.routing import WebSocketRoute
async def websocket_index(websocket):
await websocket.accept()
await websocket.send_text("Hello, websocket!")
await websocket.close()
async def websocket_user(websocket):
name = websocket.path_params["name"]
await websocket.accept()
await websocket.send_text(f"Hello,{name}")
await websocket.close()
Routes = [
WebSocketRoute("/", endpoint=websocket_index),
WebSocketRoute("/{name}", endpoint=websocket_user),
]
app = Starlette(routes=routes)
endpoint Les paramètres peuvent être l'un des suivants:
- Fonction asynchrone qui prend un seul argument
websocket. - Une classe qui implémente une interface ASGI, par exemple WebSocketEndpoint de Starlette.