hawkesley
Posts: 94
Joined: Tue Jan 12, 2016 10:16 am

Help with Flask

Wed Dec 05, 2018 4:24 pm

I am trying to get a grip of Flask for a project.
I would like to call a python script from a Flask web page which plays a text file using espeak.
I have the following which works, but it only works once when the page is rendered, not if I refresh the page.
I think I am missing a basic concept of how this should be structured.
Any help or tutorials welcome.
My files so far:-
app.py - imports Audio.py

Code: Select all

from flask import Flask, render_template


app = Flask(__name__)


walks = [
    {
        'walk': 'Tintagel',
        'desciption': 'TBA'
    },
    {
        'walk': 'Bude',
        'desciption': 'TBA'
    }
]

@app.route('/')
def index():
    import Audio
    return render_template('index.html', walks=walks)


@app.route('/showmap')
def showmap():
    import Audio
    return render_template('showmap.html', title='Show Map')

@app.route('/hello/<name>')
def hello(name):
    return render_template('page.html', name=name)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
Audio.py

Code: Select all

from subprocess import call
file = open('Audio.txt','r')
text = file.read().strip()
file.close

speech= text
call(["espeak",speech])

Andyroo
Posts: 795
Joined: Sat Jun 16, 2018 12:49 am

Re: Help with Flask

Wed Dec 05, 2018 4:35 pm

I'm learning both but I think the issue is in the audio.py in that the speech command is only called when the module is imported - i.e. it treat as set-up code.

You need to create a function and call that from the page not import it (as that happens once only).

audio.py

Code: Select all

from subprocess import call

def speaktext():
    file = open('Audio.txt','r')
    text = file.read().strip()
    file.close

    speech= text
    call(["espeak",speech])

# Put any set up code you need below this line
then the page code becomes:

Code: Select all

from flask import Flask, render_template
import audio.py

app = Flask(__name__)


walks = [
    {
        'walk': 'Tintagel',
        'desciption': 'TBA'
    },
    {
        'walk': 'Bude',
        'desciption': 'TBA'
    }
]

@app.route('/')
def index():
    speaktext()
    return render_template('index.html', walks=walks)


@app.route('/showmap')
def showmap():
    import Audio
    return render_template('showmap.html', title='Show Map')

@app.route('/hello/<name>')
def hello(name):
    return render_template('page.html', name=name)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

Then when you refresh the index page it should speak each time.

This is untested (my Pi is a bit in bits today)... You with care and caution.
Need Pi spray - these things are breeding in my house...

scotty101
Posts: 3352
Joined: Fri Jun 08, 2012 6:03 pm

Re: Help with Flask

Wed Dec 05, 2018 4:36 pm

You'll need modify the Audio.py file so that it contains a function that can be called from the flask script. An import will only occur once.

Audio.py

Code: Select all

from subprocess import call

def speakFile():
    with open('Audio.txt','r') as file:
        text = file.read().strip()
    call(["espeak",text])
Then in the flask python file you would do something like this

Code: Select all

#import the function at the start! Not later
from Audio import speakFile
.........
.........
@app.route('/showmap')
def showmap():
    speakFile()
    return render_template('showmap.html', title='Show Map')
............
EDIT: Snap!!! Good to see that two people came up with almost identical solutions. Andyroo, no need to have the .py file extension when you import python modules "import Audio" will do.

Code: Select all

file.close
should be

Code: Select all

file.close()

but it is better to do what I've done above and use the "with" context manager to automatically close the file once it has been used.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

Andyroo
Posts: 795
Joined: Sat Jun 16, 2018 12:49 am

Re: Help with Flask

Wed Dec 05, 2018 4:59 pm

@scotty101

Thanks for those corrections :)

Putting the file extension dates back to my Pascal days. Though I had a case on Monday where a program would not run without it (nano edited / cmd line executed) but not got to the bottom of why yet.

I did not know about the 'with' - thanks for that tip.
Need Pi spray - these things are breeding in my house...

hawkesley
Posts: 94
Joined: Tue Jan 12, 2016 10:16 am

Re: Help with Flask

Thu Dec 06, 2018 4:45 pm

Thanks Guys I will try that and let you know

hawkesley
Posts: 94
Joined: Tue Jan 12, 2016 10:16 am

Re: Help with Flask

Fri Dec 07, 2018 2:16 pm

I have updated the files and tested the following which works.
However if I enclose file.close I get a syntax error.
Also the current file plays the Audio before rendering the page so how do I play the Audio after the template has rendered , perhaps with a selection button?
Any help appreciated.

Audio.py

Code: Select all

from subprocess import call

def speakFile
    file = open('Audio.txt','r')
    text = file.read().strip()
    call(["espeak",text])
//including file.close here causes syntax error
app.py

Code: Select all

from flask import Flask, render_template
import Audio


app = Flask(__name__)


walks = [
    {
        'walk': 'Tintagel',
        'desciption': 'TBA'
    },
    {
        'walk': 'Bude',
        'desciption': 'TBA'
    }
]

@app.route('/')
def index():
    
    return render_template('index.html', walks=walks)


@app.route('/showmap')
def showmap():
    speakFile
    return render_template('showmap.html', title='Show Map')

@app.route('/hello/<name>')
def hello(name):
    return render_template('page.html', name=name)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

scotty101
Posts: 3352
Joined: Fri Jun 08, 2012 6:03 pm

Re: Help with Flask

Fri Dec 07, 2018 3:33 pm

I'll repeat what I said above.
scotty101 wrote:
Wed Dec 05, 2018 4:36 pm

Code: Select all

file.close
should be

Code: Select all

file.close()

but it is better to do what I've done above and use the "with" context manager to automatically close the file once it has been used.
Also

Code: Select all

speakFile
Should be

Code: Select all

speakFile()
Also the current file plays the Audio before rendering the page so how do I play the Audio after the template has rendered , perhaps with a selection button?
Flask/Python is the server. Your webbrowser renders the webpage. The code currently plays the audio before the server sends the response back to the browser.
You could theoretically have the flask request function schedule the sound to be played after a delay but you can't (easily) sync the playing with the webpage being rendered.
Another method is that you modify the HTML so that the browser plays the audio rather than flask.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

hawkesley
Posts: 94
Joined: Tue Jan 12, 2016 10:16 am

Re: Help with Flask

Fri Dec 07, 2018 4:08 pm

Thanks for the corrections and advice.

Return to “Advanced users”