Python flask abort 404

#5 Ответ сервера и перехват запросов во Flask

До сих пор этот способ использовался, чтобы отправлять ответ клиенту. Когда Flask видит, что из функции представления возвращается строка, он автоматически конвертирует ее в объект ответа (с помощью метода make_response() ) со строкой, содержащей тело ответа, статус-код HTTP 200 и значение text/html в заголовке content-type . В большинстве случаев это — все, что нужно. Но иногда необходимы дополнительные заголовки перед отправлением ответа клиенту. Для этого создавать ответ нужно с помощью функции make_response() .

Создание ответа с помощью make_response()

Синтаксис make_response() следующий:

res_obj = make_response(res_body, status_code=200) 

res_body — обязательный аргумент, представляющий собой тело ответа, а status_code — опциональный, по умолчанию его значение равно 200.

Следующий код показывает, как добавить дополнительные заголовки с помощью функции make_response() .

from flask import Flask, make_response, @app.route('/books/') def books(genre): res = make_response("All Books in <> category".format(genre)) res.headers['Content-Type'] = 'text/plain' res.headers['Server'] = 'Foobar' return res 

Следующий — демонстрирует, как вернуть ошибку 404 с помощью make_response() .

@app.route('/') def http_404_handler(): return make_response("

404 Error

"
, 400)

Настройка куки — еще одна базовая задача для любого веб-приложения. Функция make_response() максимально ее упрощает. Следующий код устанавливает два куки в клиентском браузере.

@app.route('/set-cookie') def set_cookie(): res = make_response("Cookie setter") res.set_cookie("favorite-color", "skyblue") res.set_cookie("favorite-font", "sans-serif") return res 

Примечание: куки обсуждаются подробно в уроке «Куки во Flask».

Куки, заданные в вышеуказанном коде, будут активны до конца сессии в браузере. Можно указать собственную дату истечения их срока, передав в качестве третьего аргумента в методе set_cookie() количество секунд. Например:

@app.route('/set-cookie') def set_cookie(): res = make_response("Cookie setter") res.set_cookie("favorite-color", "skyblue", 60*60*24*15) res.set_cookie("favorite-font", "sans-serif", 60*60*24*15) return res 

Здесь, у куки будут храниться 15 дней.

Создание ответов с помощью кортежей

Последний способ создать ответ — использовать кортежи в одном из следующих форматов:

(response, status, headers) (response, headers) (response, status) 

response — строка, представляющая собой тело ответа, status — код состояния HTTP, который может быть указан в виде целого числа или строки, а headers — словарь со значениями заголовков.

@app.route('/') def http_500_handler(): return ("

500 Error

"
, 500)

Функция представления вернет ошибку HTTP 500 Internal Server Error. Поскольку при создании кортежей можно не писать скобки, вышеуказанный код можно переписать следующим образом:

@app.route('/') def http_500_handler(): return "

500 Error

"
, 500

Следующий код демонстрирует, как указать заголовки с помощью кортежей:

@app.route('/') def render_markdown(): return "## Heading", 200, 'Content-Type': 'text/markdown'> 

Сможете догадаться, что делает следующая функция?

@app.route('/transfer') def transfer(): return "", 302, 'location': 'https://localhost:5000/login'> 

Функция представления перенаправляет пользователя на https://localhost:5000/login с помощью ответа 302 (временное перенаправление). Перенаправление пользователей — настолько распространенная практика, что во Flask для этого есть даже отдельная функция redirect() .

from flask import Flask, redirect @app.route('/transfer') def transfer(): return redirect("https://localhost:5000/login") 

По умолчанию, redirect() осуществляет 302 редиректы. Чтобы использовать 301, нужно указать это в функции redirect() :

from flask import Flask, redirect @app.route('/transfer') def transfer(): return redirect("https://localhost:5000/login", code=301) 

Перехват запросов

В веб-приложениях часто нужно исполнить определенный код до или после запроса. Например, нужно вывести весь список IP-адресов пользователей, которые используют приложение или авторизовать пользователя до того как показывать ему скрытые страницы. Вместе того чтобы копировать один и тот же код внутри каждой функции представления, Flask предлагает следующие декораторы:

  • before_first_request : этот декоратор выполняет функцию еще до обработки первого запроса
  • before_request : выполняет функцию до обработки запроса
  • after_request : выполняет функцию после обработки запроса. Такая функция не будет вызвана при возникновении исключений в обработчике запросов. Она должна принять объект ответа и вернуть тот же или новый ответ.
  • teardown_request : этот декоратор похож на after_request . Но вызванная функция всегда будет выполняться вне зависимости от того, возвращает ли обработчик исключение или нет.

Стоит отметить, что если функция в before_request возвращает ответ, тогда обработчик запросов не вызывается.

Следующий код демонстрирует, как использовать эти точки перехвата во Flask. Нужно создать новый файл hooks.py с таким кодом:

from flask import Flask, request, g app = Flask(__name__) @app.before_first_request def before_first_request(): print("before_first_request() called") @app.before_request def before_request(): print("before_request() called") @app.after_request def after_request(response): print("after_request() called") return response @app.route("/") def index(): print("index() called") return '

Testings Request Hooks

'
if __name__ == "__main__": app.run(debug=True)

После этого необходимо запустить сервер и сделать первый запрос, перейдя на страницу https://localhost:5000/ . В консоли, где был запущен сервер, должен появиться следующий вывод:

before_first_request() called before_request() called index() called after_request() called 

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

После перезагрузки страницы отобразится следующий вывод.

before_request() called index() called after_request() called 

Поскольку это второй запрос, функция before_first_request() не будет вызываться.

Отмена запроса с помощью abort()

Flask предлагает функцию abort() для отмены запроса с конкретным типом ошибки: 404, 500 и так далее. Например:

from flask import Flask, abort @app.route('/') def index(): abort(404) # код после выполнения abort() не выполняется 

функция вернет страницу ошибки 404

Эта функция представления вернет стандартную страницу ошибки 404, которая выглядит вот так:

abort() покажет похожие страницы для других типов ошибок. Если нужно изменить внешний вид страниц с ошибками, необходимо использовать декоратор errorhandler .

Изменение страниц ошибок

Декоратор errorhandler используется для создания пользовательских страниц с ошибками. Он принимает один аргумент — ошибку HTTP, — для которой создается страница. Откроем файл hooks.py для создания кастомных страниц ошибок 404 и 500 с помощью декоратора:

from flask import Flask, request, g, abort #. #. @app.after_request def after_request(response): print("after_request() called") return response @app.errorhandler(404) def http_404_handler(error): return "

HTTP 404 Error Encountered

"
, 404 @app.errorhandler(500) def http_500_handler(error): return "

HTTP 500 Error Encountered

"
, 500 @app.route("/") def index(): # print("index() called") # return '

Testings Request Hooks

'
abort(404) if __name__ == "__main__": #.

Стоит отметить, что оба обработчика ошибок принимают один аргумент error , который содержит дополнительную информацию о типе ошибки.

кастомная страница ошибки 404

Если сейчас посетить корневой URL, отобразится следующий ответ:

Источник

Custom Error Pages¶

Flask comes with a handy abort() function that aborts a request with an HTTP error code early. It will also provide a plain black and white error page for you with a basic description, but nothing fancy.

Depending on the error code it is less or more likely for the user to actually see such an error.

Common Error Codes¶

The following error codes are some that are often displayed to the user, even if the application behaves correctly:

The good old “chap, you made a mistake typing that URL” message. So common that even novices to the internet know that 404 means: damn, the thing I was looking for is not there. It’s a very good idea to make sure there is actually something useful on a 404 page, at least a link back to the index.

If you have some kind of access control on your website, you will have to send a 403 code for disallowed resources. So make sure the user is not lost when they try to access a forbidden resource.

Did you know that there the “404 Not Found” has a brother named “410 Gone”? Few people actually implement that, but the idea is that resources that previously existed and got deleted answer with 410 instead of 404. If you are not deleting documents permanently from the database but just mark them as deleted, do the user a favour and use the 410 code instead and display a message that what they were looking for was deleted for all eternity.

500 Internal Server Error

Usually happens on programming errors or if the server is overloaded. A terribly good idea is to have a nice page there, because your application will fail sooner or later (see also: Application Errors ).

Error Handlers¶

An error handler is a function that returns a response when a type of error is raised, similar to how a view is a function that returns a response when a request URL is matched. It is passed the instance of the error being handled, which is most likely a HTTPException . An error handler for “500 Internal Server Error” will be passed uncaught exceptions in addition to explicit 500 errors.

An error handler is registered with the errorhandler() decorator or the register_error_handler() method. A handler can be registered for a status code, like 404, or for an exception class.

The status code of the response will not be set to the handler’s code. Make sure to provide the appropriate HTTP status code when returning a response from a handler.

A handler for “500 Internal Server Error” will not be used when running in debug mode. Instead, the interactive debugger will be shown.

Here is an example implementation for a “404 Page Not Found” exception:

from flask import render_template @app.errorhandler(404) def page_not_found(e): # note that we set the 404 status explicitly return render_template('404.html'), 404 
from flask import Flask, render_template def page_not_found(e): return render_template('404.html'), 404 def create_app(config_filename): app = Flask(__name__) app.register_error_handler(404, page_not_found) return app 

An example template might be this:

 extends "layout.html" %>  block title %>Page Not Found endblock %>  block body %> h1>Page Not Foundh1> p>What you were looking for is just not there. p>a href=" <url_for('index') >>">go somewhere nicea>  endblock %> 

Returning API errors as JSON¶

When using Flask for web APIs, you can use the same techniques as above to return JSON responses to API errors. abort() is called with a description parameter. The errorhandler() will use that as the JSON error message, and set the status code to 404.

from flask import abort, jsonify @app.errorhandler(404) def resource_not_found(e): return jsonify(error=str(e)), 404 @app.route("/cheese") def get_one_cheese(): resource = get_resource() if resource is None: abort(404, description="Resource not found") return jsonify(resource) 

Logo

Contents

Источник

Читайте также:  Background size css property
Оцените статью