10

So there's this flask app that I'm working on for this project and I need it to run in a loop at timed variables to check for the status of certain variables and then give a output accordingly. However, the problem I have is I need to render a template in Flask before the loop restarts. In the changelog on http://flask.pocoo.org/ it's indicated that it's possible to render templates without using the request context but I haven't seen any real examples of this. So is there a way to render templates in Flask without having to use the request context without getting any errors? Any help that can be given is appreciated.

UPDATE: Here's the code I'm working with

from flask import Flask, render_template, request, flash, redirect, url_for
import flask
import time
from flask.ext.assets import Environment, Bundle
from flask_wtf import Form 
from wtforms import TextField, TextAreaField, SubmitField
from wtforms.validators import InputRequired

CSRF_ENABLED = True
app = Flask(__name__)
app.secret_key = 'development key'
app = flask.Flask('my app')
assets = Environment(app)
assets.url = app.static_url_path
scss = Bundle('scss/app.scss', filters='scss', output='css/app.css')
assets.register('app_scss', scss)

@app.route('/')
def server_1():
    r=1
    g=2
    b=3
    i=g
    if i == g:
        with app.app_context():
            print "Loading Template..."
            rendered = flask.render_template('server_1.html', green=True)
            print "Success! Template was loaded with green server status..."
            time.sleep(5)


if __name__ == '__main__':
    app.run(port=5000, debug=True)
VEDA0095
  • 1,575
  • 4
  • 11
  • 13
  • 1
    You can use Jinja2 without flask at all. Or try this http://stackoverflow.com/questions/30382187/render-jinja2-template-without-a-flask-context – Andrey Aug 05 '15 at 11:05

1 Answers1

26

You can do it by binding your application as the current application. Then you can use render_template() to render a template from your template directory, or render_template_string() to render directly from a template stored in a string:

import flask
app = flask.Flask('my app')

with app.app_context():
    context = {'name': 'bob', 'age': 22}
    rendered = flask.render_template('index.html', **context)

with app.app_context():
    template = '{{ name }} is {{ age }} years old.'
    context = {'name': 'bob', 'age': 22}
    rendered = flask.render_template_string(template, **context)

Alternatively you could bypass Flask and go directly to Jinja2:

import jinja2
template = jinja2.Template('{{ name }} is {{ age }} years old.')
rendered = template.render(name='Ginger', age=10)

Update

It appears that you might be wanting to stream content back to the requesting client. If so you could write a generator. Something like this might work:

import time
from flask import Flask, Response, render_template_string
from flask import stream_with_context

app = Flask(__name__)

@app.route("/")
def server_1():
    def generate_output():
        age = 0
        template = '<p>{{ name }} is {{ age }} seconds old.</p>'
        context = {'name': 'bob'}
        while True:
            context['age'] = age
            yield render_template_string(template, **context)
            time.sleep(5)
            age += 5

    return Response(stream_with_context(generate_output()))

app.run()

Here is some documentation on streaming with Flask.

mhawke
  • 84,695
  • 9
  • 117
  • 138
  • Not to sound like a novice, but what do I do with the "rendered" variable once I have everything set up? I'm still kinda new to using Flask. I'll post my code to give an idea of where I'm at. – VEDA0095 Aug 05 '15 at 21:13
  • Return it from you view function, i.e. add `return flask.render_template('server_1.html', green=True)` to your `server_1()` function. – mhawke Aug 05 '15 at 23:36
  • 1
    I would, except using return prevents `time.sleep(5)` from running the function in a loop. So I've been trying to get the template to render without using return. – VEDA0095 Aug 05 '15 at 23:47