Перейти к содержанию

HTTP маршрутизация

Starlette имеет простую, но мощную систему маршрутизации запросов. Таблицы маршрутизации определяются как списки маршрутизации и передаются при создании экземпляра приложения.

from Starlette. applications import Starlette
from starlette.responses import PlainTextResponse
От Starlet.routing Import Route


async def homepage (request):
    return PlainTextResponse ("Homepage ")

Async def about (request):
    Return PlainTextResponse ("About ")


routes =]
    Route ('/', endpoint = homepage),
    Route ("/about ", endpoint = about).
]

app = Starlette (routes = routes)

endpoint Параметром может быть один из следующих:

  • -обычная или асинхронная функция, которая принимает один аргумент request и должна вернуть ответ.
  • Класс, реализующий интерфейс ASGI, такой как HTTPENDpoint Starlette.

Параметры траектории

Пути могут использовать стили шаблонов URI для захвата компонентов пути.

Route ('/users/{username}', user)

По умолчанию этот символ захватывает символ до конца контура или до следующего /.

Вы можете использовать конвертер для изменения захваченного содержимого. Доступны следующие конвертеры:

  • str Возвращает строку, которая является значением по умолчанию.
  • int Возвращает целое число Python.
  • float Возвращает число с плавающей точкой Python.
  • uuid Вернуть Python. uuid.UUID Пример.
  • path возвращает остальную часть пути, включая любые дополнительные символы /.

Преобразователь используется с помощью двоеточия перед ним, как показано ниже:

Route ('/users/{user_id:int}', user)
Route ('/floating-point/{number:float}', floating_point)
Route ('/uploaded/{rest_of_path:path}', uploaded)

Если вам нужен другой конвертер, который не определен, вы можете создать свой собственный. См. ниже примеры того, как создать datetime конвертер и как зарегистрировать его:

Из данных Import DateTime

from starlet.convertors import Convertor, register_url_convertor


Dateclass TimeConvertor (Convertor):
    regex = "[0-9]{4}-[0-9]{2}-[0 - 9]{2}T[0- 9]{2}:[0-9]{2}: [0 - 9]{2}:[0-9]{2}(.[0-9]+)?"

    def convert(self, value: str) -> datetime:
        return datetime.strptime(value, "% Y-% m-%dT%H:%M:%S")

    def to_string (self, значение: datetime) -> str:
        return value.strftime ("% Y-% m-%dT%H:%M:%S")

register_url_convertor ("datetime", DateTimeConvertor())

После регистрации вы сможете использовать его как:

Route ('/history/{date:datetime}', history)

Параметры пути доступны в запросе в качестве словаря request.path_params

async def user(запрос):
    user_id = request.pat_params ['user_id']
    ...

Обработка методов HTTP

Маршрутизация также может указать, какие методы HTTP обрабатываются конечной точкой:

Route ('/users/{user_id:int}', user, methods=["GET", "POST"])

По умолчанию конечная точка функции принимает только запросы GET, если не указано иное.

Монтажная проводка подоснования

В больших приложениях можно обнаружить, что нужно разделить часть таблицы маршрутизации на основе префиксов путей.

routes =]
    Route ('/', homepage),
    Mount ('/users', routes=[
        Route ('/', users, methods=['GET', 'POST']),
        Route ('/{username}', user),
    ])
]

Этот стиль позволяет определить различные подмножества таблиц маршрутизации в разных частях проекта.

Из импорта импортеров, auth

routes =]
    Route ('/', homepage),
    Mount ('/users', routes= users.routes),
    Mount ('/auth', routes= auth.routes),
]

Вы также можете включить дочернее приложение в приложение Starlette с помощью монтирования. Например,...

# This is a standalone static files server
app = StatiicFiles (directory="static")

This is a static files server mounted within a Starlette application.
# underneath the "/static" path.
routes =]
    ...
    Mount("/static", app=StaticFiles(directory="static"), name="static")
]

app = Starlette(routes=routes)

Обратный поиск URL

Обычно вам нужно иметь возможность генерировать URL-адрес для определенного маршрута, например, если вам нужно вернуть ответ на перенаправление.

  • Подпись: url_for(name, **path_params) -> URL

    routes = [ Route("/", страница-страница, name="homepage") ]

    Мы можем использовать следующее, чтобы вернуть URL...

    url = request.url_for ("Главная страница")

Поиск по URL может содержать параметры пути...

routes =]
    Route("/users/{username}", user, name="user_detail")
]

Мы можем использовать доллар, чтобы вернуться в URL...
url = request.url_for ("user_detail", username=...)

Если Mount содержит name, то основание должно использовать стиль {prefix}:{name} для обратного поиска URL-адреса.

routes =]
    Mount("/users", name="users", routes=[
        Route("/", user, name="user_list"),
        Route("/{username}", user, name="user_detail")
    ])
]

Мы можем использовать доллар, чтобы вернуться на URL...
url = request.url_for ("users: user_list")
url = request.url_for ("users: user_detail", username=...)

Установленное приложение может содержать параметр path=....

routes = [
    ...
    Mount("/static", app= StatiicFiles (directory="static"), name="static")
]

Мы можем использовать доллар, чтобы вернуться на URL...
url = request.url_for ("static", path="/CSS/base.casss")

В случае отсутствия экземпляра request можно выполнить обратный поиск для приложения, хотя при этом поиск возвращает только URL-путь.

url = app. url_path_for ("user_detail", username=...)

Маршрутизация на основе хостов

Если вы хотите использовать разные маршруты для одного и того же пути в соответствии с заголовком Host.

Обратите внимание, что порт удаляется из заголовка Host при совпадении. Например,Host (host='example.org:3600', ...) обрабатывается, даже если заголовок Host содержит или не содержит порты, отличные от 3600(example.org:5600,example.org). Таким образом, если вам нужен порт в url_for, вы можете указать порт.

Существует несколько способов подключения серверных маршрутов к вашему приложению.

site = Router() # Use eg.`@site.route()` to configure this.
api = Router() # Use eg.`@api.route()` to configure this.
news = Router() # Use eg.`@news.route()` to configure this.

routes =]
    Host ('api.example.org', api, name="sity_api")
]

app = Starlette(routes=routes)

app.host ('www.example.org', site, name="main_site")

news_host = хост ('news.example.org', news)
ap.router.routes.append (news_host)

URL-запросы могут содержать параметры сервера, как и параметры пути

routes = [
    Host("{subdomain}. example.org", name="sub", app=Router(routes=[
        Mount("/users", name="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=…)

Приоритет маршрутизации

Входящие пути соответствуют каждому Route последовательно.

В тех случаях, когда может быть несколько маршрутов, совпадающих с входящим маршрутом, следует позаботиться о том, чтобы более конкретные маршруты были перечислены перед общим.

Например:

Не делай это:`/users/me` будет никогда не делать это без комментариев.
routes = [
    Route ('/users/{username}', user),
    Route ('/users/me', current_user),
]

# Do this:`/users/me` is tested first
routes = [
    Route ('/users/me', current_user),
    Route ('/users/{username}', user),
]

Работа с экземпляром маршрутизатора

Если вы работаете на низком уровне, вы можете использовать обычный экземпляр Router, а не создавать приложение Starlette. Это дает вам легкий ASGI приложение, которое предлагает только маршрутизацию приложения, не упаковывая его в какой-либо промежуточный продукт.

app = routes=[
    Route ('/', homepage),
    Mount ('/users', routes=[
        Route ('/', users, methods=['GET', 'POST']),
        Route ('/{username}', user),
    ])
])

Маршруты WebSocket

При использовании конечных точек WebSocket вы должны использовать WebSocketRoute вместо обычного Route.

Параметры пути и поиск обратного URL-адреса для WebSocketRoute работают так же, как и HTTP Route, что можно найти в разделе HTTP маршрутизации выше.

Из Starlette.applications Import Starlette
from starlett.routing import WebSocketRoute


async def websocket_index (websocket)
    websocket.accept(
    websocket.send_text («Hello, websocket!»)
    websocket.close (


async def websocket_user (websocket):
    name = websocket.path_params ["name"]
    websocket.accept(
    websocket.send_text (f"Hello,{name}")
    websocket.close (


routes = [
    WebSocketRoute("/", endpoint=websocket_index),
    WebSocketRoute("/{name}", endpoint= websockt_user),
]

app = Starlette(routes=routes)

endpoint Параметром может быть один из следующих:

  • -асинхронная функция, которая принимает один аргумент websocket.
  • Класс, реализующий интерфейсы ASGI, например WebSocketEndpoint Starlette.