librelist archives

« back to archive

regularly update content

regularly update content

From:
David Froger
Date:
2013-01-22 @ 23:20
Hi all,

I'm very new to Flask and web programming in general.

Suppose I have this function (in real case, a C++ scientific library wrapped with
SWIG and loaded as a Python module, that take some time to execute):


    import os
    import time

    import matplotlib
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt

    import numpy as np

    def foo(itermax=11):
        x = np.linspace(0,10)
        for it in range(itermax):
            y = np.cos(x  + it*0.2)
            time.sleep(1.)
            yield x,y

I would like to plot (x,y), using matplotlib, and update the figure regularly.
It's ok if user has to manually refresh the webbrowser page.

I've tried this:

    @app.route('/', methods=['GET', 'POST'])
    def run_foo():
        fig = plt.figure()
        filename = os.path.join('static','foo.png')
        def generate():
            for x,y in foo():
                plt.clf() # Clean matplotlib figure.
                plt.plot(x,y,'ro')
                plt.savefig(filename)
                yield render_template("foo.html", image_url=filename) 
        return Response(generate())

foo.html is:

    {% block body %}
      <img src=" {{ image_url }} " alt="plot" title="plot" >
    {% endblock %}

But when 'generate' is evaluated, the context seems to be lost, the line:
    yield render_template("foo.html", image_url=filename, error=False)

give the error:
      File "(...)/templating.py", line 123, in render_template
        ctx.app.update_template_context(context)
    AttributeError: 'NoneType' object has no attribute 'app'

Is this the good way to make the page being updated? How to make it works?

Thanks a lot,

David

Re: [flask] regularly update content

From:
Sean Whalen
Date:
2013-01-23 @ 04:16
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

What about this?

    @app.route('/', methods=['GET', 'POST'])
    def run_foo():
        fig = plt.figure()
        filename = os.path.join('static','foo.png')
        def generate():
            for x,y in foo():
                plt.clf() # Clean matplotlib figure.
                plt.plot(x,y,'ro')
                plt.savefig(filename)
                yield filename
        return render_template("foo.html", image_url=url_for('static',
 filename)

- - Sean

On Tuesday, January 22, 2013 6:20:02 PM, David Froger wrote:
> Hi all,
> 
> I'm very new to Flask and web programming in general.
> 
> Suppose I have this function (in real case, a C++ scientific 
> library wrapped with SWIG and loaded as a Python module, that take 
> some time to execute):
> 
> 
> import os import time
> 
> import matplotlib matplotlib.use('Agg') import matplotlib.pyplot
> as plt
> 
> import numpy as np
> 
> def foo(itermax=11): x = np.linspace(0,10) for it in 
> range(itermax): y = np.cos(x  + it*0.2) time.sleep(1.) yield x,y
> 
> I would like to plot (x,y), using matplotlib, and update the
> figure regularly. It's ok if user has to manually refresh the
> webbrowser page.
> 
> I've tried this:
> 
> @app.route('/', methods=['GET', 'POST']) def run_foo(): fig = 
> plt.figure() filename = os.path.join('static','foo.png') def 
> generate(): for x,y in foo(): plt.clf() # Clean matplotlib figure.
>  plt.plot(x,y,'ro') plt.savefig(filename) yield 
> render_template("foo.html", image_url=filename) return 
> Response(generate())
> 
> foo.html is:
> 
> {% block body %} <img src=" {{ image_url }} " alt="plot" 
> title="plot" > {% endblock %}
> 
> But when 'generate' is evaluated, the context seems to be lost,
> the line: yield render_template("foo.html", image_url=filename, 
> error=False)
> 
> give the error: File "(...)/templating.py", line 123, in 
> render_template ctx.app.update_template_context(context) 
> AttributeError: 'NoneType' object has no attribute 'app'
> 
> Is this the good way to make the page being updated? How to make
> it works?
> 
> Thanks a lot,
> 
> David
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.17 (MingW32)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBAgAGBQJQ/2QZAAoJELpzbl8t0OpIf5EH/3k6OE9JpcCF6oY5iE/TDhFb
JRACqDkD1Xw0JxTqzP+4eBL83dgKynCssIrsBeVdPbu3sjSYKW1lJBn+zENaozmw
O31q0cT2WQ5gmzlcLxtKsYPAcI5zEDZYkTKS1Ox/Puw5HKEtxw5GOfynQRkLUeBT
bZLH17lyhqN/SWwmgMzDN1OW7y2Xmr6HWwuIOKmFHw0JIHnohnY4krP5MWpGhqs6
57616gzU9gGuvNLNSzKZjq6rInbqLIVTCO/9nI7eR/MAhjE9CjGms81jvAvXth+n
hoPAUw84zO6zzMa1Jp8+MQki96Okm68e/4c4aW1LNyiItNGJ0kuRXbL+g7xBYug=
=8/ZL
-----END PGP SIGNATURE-----

Re: [flask] regularly update content

From:
David Froger
Date:
2013-01-23 @ 07:57
On Tue, 22 Jan 2013 23:16:30 -0500, Sean Whalen <whalenster@gmail.com> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> What about this?
> 
>     @app.route('/', methods=['GET', 'POST'])
>     def run_foo():
>         fig = plt.figure()
>         filename = os.path.join('static','foo.png')
>         def generate():
>             for x,y in foo():
>                 plt.clf() # Clean matplotlib figure.
>                 plt.plot(x,y,'ro')
>                 plt.savefig(filename)
>                 yield filename
>         return render_template("foo.html", image_url=url_for('static',
>  filename)
> 
> - - Sean

Hi Sean,

Thanks for the reply.

>         return render_template("foo.html", image_url=url_for('static',
>  filename)
url_for takes one argument, so it should be just filename? But the arugment of
url_for is a function name, so what would be the function? Sorry if I'm
missing something.

Should'nt the function 'generate' be used in the returned object, like here
http://flask.pocoo.org/docs/patterns/streaming/ ?

Thanks

Re: [flask] regularly update content

From:
David Froger
Date:
2013-01-23 @ 09:36
I think I need to use Ajax, I'm looking at it.