Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate execution time for every page in Python's Flask

Tags:

What's a good way to calculate the execution time for every page load using Python's Flask library?

I was thinking of putting a start timer in views/__ init__.py:

@app.before_request
def before_request():
  g.start = time.time()

But where would I put the end part of the timer to calculate the difference, and how would I get it into the footer of my html template?

Thanks.

like image 257
ensnare Avatar asked Sep 05 '12 02:09

ensnare


4 Answers

Put it in teardown_request function:

@app.teardown_request
def teardown_request(exception=None):
    diff = time.time() - g.start
    ...

In teardown_request you are not allowed to change the response, If you want to use the calculated string in your response use after_request:

@app.after_request
def after_request(response):
    diff = time.time() - g.start
    if (response.response):
        response.response[0] = response.response[0].replace('__EXECUTION_TIME__', str(diff))
    return response
like image 176
MostafaR Avatar answered Sep 25 '22 15:09

MostafaR


The other answers are essentially correct, but quite out of date now.

The following works with Python 3.6 / 3.7 and Flask 1.0.2:

import time
from flask import g

@app.before_request
def before_request():
    g.start = time.time()

@app.after_request
def after_request(response):
    diff = time.time() - g.start
    if ((response.response) and
        (200 <= response.status_code < 300) and
        (response.content_type.startswith('text/html'))):
        response.set_data(response.get_data().replace(
            b'__EXECUTION_TIME__', bytes(str(diff), 'utf-8')))
    return response

By using response.set_data, the content-length will be correctly updated by Flask. Please also note the use of byte strings and the encoding.

like image 33
Jordan Dimov Avatar answered Sep 22 '22 15:09

Jordan Dimov


You also need to update the content-length header otherwise browsers get upset (and Chrome seems to give unpredictable results).

@app.after_request
def after_request(response):
    diff = time.time() - g.start
    if app.debug:
        print "Exec time: %s" % str(diff)

    if (response.response):
        response.response[0] = response.response[0].replace('__EXECUTION_TIME__', str(diff))
        response.headers["content-length"] = len(response.response[0])

    return response
like image 3
Peter Farmer Avatar answered Sep 22 '22 15:09

Peter Farmer


Try out this: https://code-maven.com/flask-display-elapsed-time

import time
from flask import Flask, request, render_template, g
app = Flask(__name__)
 
 
@app.before_request
def before_request():
   g.request_start_time = time.time()
   g.request_time = lambda: "%.5fs" % (time.time() - g.request_start_time)
 
 
@app.route("/")
def main():
    return render_template('main.html')

and template html like:

<html>
<head>
</head>
<body>
<h1>Show elapsed time</h1>
 
<hr>
Elapsed time: {{ g.request_time() }}
</body>
</html>
like image 2
romlym Avatar answered Sep 22 '22 15:09

romlym