rlou
rlou

Reputation: 536

Variable not updating in Flask app

I have built this small thing (as a learning exercise for myself) and it works fine:

import urllib.request

url = "http://www.google.com"
print_result = ""
def is_google_down():
    try:
        result = urllib.request.urlopen(url).getcode()
        if result == 200:
            print_result = "google.com is fine"
        else:
            print_result = "google.com is down"   
    except urllib.error.HTTPError as e:
        print_result = "google.com is down"
    print(print_result)
is_google_down()

So now I'm trying to convert it to a flask app so I can build a web page around the result:

from flask import Flask, render_template
import urllib.request
app = Flask(__name__)

@app.route("/")
def is_it_down():
    url = "http://www.google.com"
    print_result = "not working"
    def is_google_down():
        try:
            result = urllib.request.urlopen(url).getcode()
            if result == 200:
                print_result = "google.com is fine"
            else:
                print_result = "google.com is down"   
        except urllib.error.HTTPError as e:
            print_result = "google.com is down"
        print(print_result)
    is_google_down()
    return render_template("is_it_down.html", result=print_result)

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

When I refresh my webpage, I just get the "not working" text which is what print_result is originally set to. Why it is not updating?

Upvotes: 1

Views: 2116

Answers (2)

Andriy Makukha
Andriy Makukha

Reputation: 8304

Short answer:

You need to use the nonlocal statement.

Long answer:

Python thinks that the two variables named print_result are different, as they are declared in two different scopes (inside the functions is_it_down and is_google_down).

So this is a simplified version of your code:

#!/usr/bin/env python3

def is_it_down():
    print_result = "not working"
    def is_google_down():
        print_result = "google.com is fine"
        print(print_result)
    is_google_down()
    print(print_result)

is_it_down()

Output:

google.com is fine
not working

While this is the fixed code, which will work as you expected:

#!/usr/bin/env python3

def is_it_down():
    print_result = "not working"
    def is_google_down():
        nonlocal print_result
        print_result = "google.com is fine"
        print(print_result)
    is_google_down()
    print(print_result)

is_it_down()

Output:

google.com is fine
google.com is fine

Upvotes: 0

Raja Simon
Raja Simon

Reputation: 10305

Your inside function should return print_result.

Answer:

print_result = is_google_down()
return render_template("base.html", result=print_result)

Or Answer:

You don't need is_google_down function. And even that function barely return anything so just remove it.

app.py

@app.route("/")
def is_it_down():
    url = "http://www.google.com"
    print_result = "not working"
    try:
        result = urllib.request.urlopen(url).getcode()
        if result == 200:
            print_result = "google.com is fine"
        else:
            print_result = "google.com is down"   
    except urllib.error.HTTPError as e:
        print_result = "google.com is down"
    return render_template("is_it_down.html", result=print_result)

is_it_down.html

{{ result }}

Upvotes: 1

Related Questions