Маршрутные статические файлы
Статические файлы,такие как изображения или CSS-файлы,не обслуживаются автоматически.Вы должны добавить маршрут и обратный вызов,чтобы контролировать,какие файлы обслуживаются и где их найти:
from bottle import static_file @route('/static/') def server_static(filename): return static_file(filename, root='/path/to/your/static/files')
Функция static_file() помогает безопасно и удобно обслуживать файлы (см. Статические файлы ). Этот пример ограничен файлами непосредственно в каталоге /path/to/your/static/files , поскольку подстановочный знак не будет соответствовать пути с косой чертой. Чтобы обслуживать файлы в подкаталогах, измените подстановочный знак, чтобы использовать фильтр path :
@route('/static/') def server_static(filepath): return static_file(filepath, root='/path/to/your/static/files')
Будьте осторожны при указании относительного корневого пути, такого как root=’./static/files’ . Рабочий каталог ( ./ ) и каталог проекта не всегда совпадают.
Error Pages
Если что-то пойдет не так, Bottle отобразит информативную, но довольно простую страницу с ошибкой. Вы можете переопределить значение по умолчанию для определенного кода состояния HTTP с помощью декоратора error() :
from bottle import error @error(404) def error404(error): return 'Nothing here, sorry'
Отныне ошибки 404 File not Found будут отображать пользовательскую страницу ошибки для пользователя. Единственный параметр, передаваемый обработчику ошибок, — это экземпляр HTTPError . Кроме того, обработчик ошибок очень похож на обычный обратный вызов запроса. Вы можете читать из request , писать в response и возвращать любой поддерживаемый тип данных, кроме экземпляров HTTPError .
Обработчики ошибок используются только в том случае, если ваше приложение возвращает или вызывает исключение HTTPError ( abort() делает именно это). Изменение Request.status или возврат HTTPResponse не вызовет срабатывания обработчика ошибок.
Generating content
В чистом WSGI диапазон типов,которые вы можете вернуть из своей заявки,очень ограничен.Заявки должны возвращать итерабельные байтовые строки.Вы можете вернуть строку (потому что строки являются итерабельными),но это заставляет большинство серверов передавать ваше содержимое char.Строки в юникоде вообще не разрешены.Это не очень практично.
Бутылка гораздо более гибкая и поддерживает широкий спектр типов. Он даже добавляет заголовок Content-Length , если это возможно, и автоматически кодирует юникод, поэтому вам не нужно этого делать. Далее следует список типов данных, которые вы можете вернуть из обратных вызовов вашего приложения, и краткое описание того, как они обрабатываются фреймворком:
Dictionaries Как упоминалось выше, словари Python (или их подклассы) автоматически преобразуются в строки JSON и возвращаются в браузер с заголовком Content-Type , установленным в application/json . Это облегчает реализацию API на основе json. Поддерживаются также форматы данных, отличные от json. Смотрите tutorial-output-filter, чтобы узнать больше. Empty Strings, False, None or other non-true values: Они создают пустой вывод с заголовком Content-Length , установленным в 0. Unicode strings Строки Unicode (или итерации, приводящие к строкам Unicode) автоматически кодируются с помощью кодека, указанного в заголовке Content-Type (по умолчанию utf8), а затем обрабатываются как обычные байтовые строки (см. Ниже). Byte strings Bottle возвращает строки целиком (вместо итерации по каждому символу) и добавляет заголовок Content-Length , основанный на длине строки. Списки байтовых строк объединяются первыми. Другие итерируемые строки с байтовыми строками не объединяются, потому что они могут стать слишком большими, чтобы поместиться в память. Content-Length заголовок не установлен в этом случае. Instances of HTTPError or HTTPResponse Возврат их имеет тот же эффект, что и при вызове их в качестве исключения. В случае HTTPError применяется обработчик ошибок. Подробнее см . Страницы ошибок . File objects Все, что имеет метод .read() , обрабатывается как файл или файлоподобный объект и передается вызываемому wsgi.file_wrapper , определенному инфраструктурой сервера WSGI. Некоторые реализации сервера WSGI могут использовать оптимизированные системные вызовы (sendfile) для более эффективной передачи файлов. В других случаях это просто перебирает куски, которые помещаются в память. Необязательные заголовки, такие как Content-Length или Content-Type ,не устанавливаются автоматически. Используйте send_file() , если это возможно. Подробнее см. Статические файлы . фильтры и генераторы Вам разрешено использовать yield в ваших обратных вызовах или возвращать итерируемый объект, если итерируемый возвращает строки байтов, строки юникода, экземпляры HTTPError или HTTPResponse .Вложенные итерации не поддерживаются, извините. Обратите внимание, что код состояния HTTP и заголовки отправляются в браузер, как только итерируемый объект возвращает свое первое непустое значение. Изменение их позже не имеет никакого эффекта.
Порядок в этом списке важен. Например, вы можете вернуть подкласс str с помощью метода read() . Он по-прежнему рассматривается как строка, а не как файл, потому что сначала обрабатываются строки.
Изменение кодирования по умолчанию
Bottle использует параметр charset заголовка Content-Type , чтобы решить, как кодировать строки Unicode. Этот заголовок по умолчанию имеет значение text/html; charset=UTF8 и может быть изменен с помощью атрибута Response.content_type или путем прямой установки атрибута Response.charset . ( Объект Response описан в разделе Объект Response .)
from bottle import response @route('/iso') def get_iso(): response.charset = 'ISO-8859-15' return u'This will be sent with ISO-8859-15 encoding.' @route('/latin9') def get_latin(): response.content_type = 'text/html; charset=latin9' return u'ISO-8859-15 is also known as latin9.'
В некоторых редких случаях имена кодирования Python отличаются от имен, поддерживаемых спецификацией HTTP. Затем необходимо выполнить оба действия: сначала установить заголовок Response.content_type (который отправляется клиенту без изменений), а затем установить атрибут Response.charset (который используется для кодирования Unicode).
Static Files
Вы можете напрямую возвращать файловые объекты, но static_file() является рекомендуемым способом обслуживания статических файлов. Он автоматически угадывает MIME-тип, добавляет заголовок Last-Modified , ограничивает пути к root каталогу по соображениям безопасности и генерирует соответствующие сообщения об ошибках (403 при ошибках разрешения, 404 при отсутствующих файлах). Он даже поддерживает заголовок If-Modified-Since и в итоге генерирует ответ 304 Not Modified . Вы можете передать пользовательский тип MIME, чтобы отключить угадывание.
from bottle import static_file @route('/images/') def send_image(filename): return static_file(filename, root='/path/to/image/files', mimetype='image/png') @route('/static/') def send_static(filename): return static_file(filename, root='/path/to/static/files')
Вы можете повысить возвращаемое значение static_file() как исключение, если вам действительно нужно.
Forced Download
Большинство браузеров пытаются открыть загруженные файлы,если MIME-тип известен и назначен приложению (например,PDF-файлы).Если это не то,что вы хотите,вы можете заставить диалог загрузки и даже предложить имя файла пользователю:
@route('/download/') def download(filename): return static_file(filename, root='/path/to/static/files', download=filename)
Если параметр download имеет значение True , используется оригинальное имя файла.
HTTP-ошибки и переадресации
Функция abort() является ярлыком для генерации страниц ошибок HTTP.
from bottle import route, abort @route('/restricted') def restricted(): abort(401, "Sorry, access denied.")
Чтобы перенаправить клиента на другой URL-адрес, вы можете отправить 303 See Other ответ с заголовком Location , установленным на новый URL-адрес. redirect() сделает это за вас:
from bottle import redirect @route('/wrong/url') def wrong(): redirect("/right/url")
В качестве второго параметра можно указать другой код статуса HTTP.
Обе функции прервут ваш код обратного вызова, вызвав исключение HTTPError .
Other Exceptions
Все исключения, кроме HTTPResponse или HTTPError , приведут к ответу 500 Internal Server Error , поэтому они не приведут к сбою вашего сервера WSGI. Вы можете отключить это поведение для обработки исключений в промежуточном программном обеспечении, установив для bottle.app().catchall значение False .
Объект ответа Response
Метаданные ответа, такие как код состояния HTTP, заголовки ответа и файлы cookie, хранятся в объекте с именем response до момента, когда они передаются в браузер. Вы можете манипулировать этими метаданными напрямую или использовать для этого предопределенные вспомогательные методы. Полный список API и функций описан в разделе API (см. Response ), но здесь также рассматриваются наиболее распространенные варианты использования и функции.
Status Code
Код состояния HTTP управляет поведением браузера и по умолчанию равен 200 OK . В большинстве сценариев вам не нужно устанавливать атрибут Response.status вручную, но используйте вспомогательную функцию abort() или возвращайте экземпляр HTTPResponse с соответствующим кодом состояния. Допускается любое целое число, но коды, отличные от определенных спецификацией HTTP , только запутают браузер и нарушат стандарты.
Response Header
Заголовки ответа, такие как Cache-Control или Location , определяются через Response.set_header() . Этот метод принимает два параметра, имя заголовка и значение. Часть имени нечувствительна к регистру:
@route('/wiki/') def wiki(page): response.set_header('Content-Language', 'en') .
Большинство заголовков уникальны, это означает, что клиенту отправляется только один заголовок на имя. Однако некоторые специальные заголовки могут появляться более одного раза в ответе. Чтобы добавить дополнительный заголовок, используйте Response.add_header() вместо Response.set_header() :
response.set_header('Set-Cookie', 'name=value') response.add_header('Set-Cookie', 'name2=value2')
Обратите внимание, что это всего лишь пример. Если вы хотите работать с файлами cookie, читайте дальше .