Запросы
Starlette включает в себя класс Request, который предоставляет вам более удобный интерфейс для обработки входящих запросов, вместо прямого доступа к диапазону ASGI и приемным каналам.
Запрос
Подпись: Request(scope, receive=None)
Из starlette.requests import Request
От Starlette. Response Import Response
async def app(scope, receive, send):
assert scope ['type'] ='http'
Request = Request(scope, requeive)
content = '%s %s' %' % (request.method, request.url.path)
Response = Response(content, medie_type ='text/plain')
await response(scope, receive, send)
Запросы предоставляют интерфейс привязки, поэтому вы можете использовать их так же, как и scope.
Например,request['path'] возвращает путь ASGI.
Если вам не требуется доступ к объекту запроса, вы можете создать экземпляр запроса без предоставления параметров receive.
Методология
Метод запроса используется с помощью request.method.
Унифицированный указатель ресурсов (часто называемый также URL).
Запрашиваемый URL-адрес доступен в формате request.url.
Свойство представляет собой строковый объект, раскрывающий все компоненты, которые могут быть отобраны из URL-адреса.
Например,request.url.path,request.url.port,request.url.scheme.
Заголовок сообщения
Заголовок отображается как несколько словарей, не зависящих от регистра.
Например: request.headers['content-type']
Параметры запроса
Параметры запроса представлены в виде неизменяемых множественных словарей.
Например: request.query_params['search']
Параметры траектории
Параметры пути маршрутизатора раскрываются в качестве интерфейса словаря.
Например: request.path_params['username']
Адреса клиентов
Удаленный адрес клиента был обнаружен в виде бинарной группы request.client(или None).
Имя хоста или IP-адрес: request.client.host
Номер порта, к которому подключается клиент: request.client.port
Cookies
Файлы cookie представлены в виде обычного словаря интерфейса.
Например: request.cookies.get('mycookie')
В случае недействительных файлов cookie файлы cookie игнорируются.(RFC 2109)
Тело.
Существует несколько различных интерфейсов для возврата к объекту запроса:
Запрос представлен в виде байтов: await request.body()
Субъект запроса, анализируемый как данные формы или несколько частей: async with request.form() as form:
Запрос, интерпретируемый в JSON: await request.json()
Вы также можете использовать синтаксис async for для доступа к объекту запроса в виде потока:
Из starlette. requests import Request
От Starlette. Response import Response
async def app (scope, receive, send):
assert scope ['type']=='http'
Request = Request (scope, requeive)
body = B ''
async for chunk in www.example.com ():
body += chunk
Response = Response(body, media_type ='text/plain')
await response(scope, receive, send)
Если вы заходите к .stream(), вы получите байт-блоки, не сохраняя весь объект в памяти. Любые последующие вызовы .body(),.form() или .json() вызовут ошибку.
В некоторых случаях, таких как длинный опрос или потоковый ответ, вам может потребоваться определить, отключен ли клиент. Вы можете определить это состояние с помощью disconnected = await request.is_disconnected().
Запрос файла
Файл запроса обычно отправляется в виде данных из нескольких частей формы (multipart/form-data).
Подпись: request.form(max_files=1000, max_fields=1000)
Вы можете настроить максимальное количество полей или файлов с параметрами max_files и max_fields:
async with request.form (max_files =1000, max_fields =1000):
...
Данные!!! устанавливают эти ограничения по соображениям безопасности, позволяя неограниченное количество полей или файлов, может привести к атакам отказа в обслуживании, поскольку обработка слишком большого количества пустых полей требует больших объемов процессора и памяти.
Когда вы вызываете async with request.form() as form, вы получаете starlette.datastructures.FormData, неизменяемый многослойный словарь, содержащий как загрузку файлов, так и ввод текста. Загрузка файла представляет собой экземпляр starlette.datastructures.UploadFile.
UploadFile Имеет следующие свойства:
filename:strс исходным именем загруженного файла илиNone, если он недоступен (например,myimage.jpg).content_type:strс типом содержимого (MIME/тип носителя) илиNone, если он недоступен (например,image/jpeg).file:SpooledTemporaryFile(объект, похожий на файл). Это фактический файл Python, который вы можете передать непосредственно другим функциям или библиотекам, которые ожидают «похожие файлы».headers: объектHeaders. Обычно это будет только заголовокContent-Type, но если другие головы включены в несколько полей, они также будут включены здесь. Обратите внимание, что эти головы не связаны с головой вRequest.headers.size: Размер файла загрузки в байтахint. Это значение вычисляется на основе запрашиваемого содержимого, поэтому лучше определить размер загружаемого файла, чемContent-LengthЗаголовок. Если не установлен, тоNone。
UploadFile имеет следующие методы async. Все они вызывают соответствующие файловые методы (используя внутренние SpooledTemporaryFile) на нижнем уровне.
async write(data): записываетdata(bytes) в файл.async read(size)-считывает байт файлаsize(int).async seek(offset): перейдите к файлу, где находится байтыoffset(int).- К примеру,
await myfile.seek(0)Перейти к исходному местоположению файла.
- К примеру,
async close(): Закрытие файла.
Так как все эти методы являются методами async, вам нужно «подождать» их.
Например, имя файла и содержимое можно получить следующими способами:
async with request.form () as form:
filename = form[upload_file].
contents = await form["upload_file"].read()
Информация!!! Как указано в RFC-7578: 4.2, раздел данных формы, содержащий файл, предполагает наличие полей name и filename:Content-Disposition: form-data; name="user"; filename="somefile" в заголовке Content-Disposition. Хотя в соответствии с RFC-7578 поле filename является необязательным, оно помогает Starlette определить, какие данные следует считать файлами. Если доступно поле filename, создается объект UploadFile для доступа к базовому файлу, иначе раздел данных формы будет обрабатываться и доступен в качестве исходной строки.
Приложения
Начальное приложение Starlette доступно через request.app.
Состояние
Если вы хотите сохранить дополнительную информацию в запросе, вы можете сделать это с помощью request.state.
Например:
request.state.time_started = time.time()