File: streaming.html

package info (click to toggle)
jinja 1.2-2
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 1,408 kB
  • ctags: 1,171
  • sloc: python: 6,438; ansic: 397; makefile: 74
file content (150 lines) | stat: -rw-r--r-- 10,559 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <title>Streaming Interface &mdash; Jinja Documentation</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <link rel="stylesheet" href="style.css" type="text/css">
  <style type="text/css">
    .syntax  { background: #ffffff; }
.syntax .c { color: #888888 } /* Comment */
.syntax .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.syntax .k { color: #008800; font-weight: bold } /* Keyword */
.syntax .cm { color: #888888 } /* Comment.Multiline */
.syntax .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.syntax .c1 { color: #888888 } /* Comment.Single */
.syntax .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.syntax .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.syntax .ge { font-style: italic } /* Generic.Emph */
.syntax .gr { color: #aa0000 } /* Generic.Error */
.syntax .gh { color: #303030 } /* Generic.Heading */
.syntax .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.syntax .go { color: #888888 } /* Generic.Output */
.syntax .gp { color: #555555 } /* Generic.Prompt */
.syntax .gs { font-weight: bold } /* Generic.Strong */
.syntax .gu { color: #606060 } /* Generic.Subheading */
.syntax .gt { color: #aa0000 } /* Generic.Traceback */
.syntax .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.syntax .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.syntax .kp { color: #008800 } /* Keyword.Pseudo */
.syntax .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.syntax .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.syntax .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.syntax .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.syntax .na { color: #336699 } /* Name.Attribute */
.syntax .nb { color: #003388 } /* Name.Builtin */
.syntax .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.syntax .no { color: #003366; font-weight: bold } /* Name.Constant */
.syntax .nd { color: #555555 } /* Name.Decorator */
.syntax .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.syntax .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.syntax .nl { color: #336699; font-style: italic } /* Name.Label */
.syntax .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.syntax .py { color: #336699; font-weight: bold } /* Name.Property */
.syntax .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.syntax .nv { color: #336699 } /* Name.Variable */
.syntax .ow { color: #008800 } /* Operator.Word */
.syntax .w { color: #bbbbbb } /* Text.Whitespace */
.syntax .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.syntax .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.syntax .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.syntax .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.syntax .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.syntax .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.syntax .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.syntax .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.syntax .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.syntax .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.syntax .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.syntax .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.syntax .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.syntax .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.syntax .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.syntax .bp { color: #003388 } /* Name.Builtin.Pseudo */
.syntax .vc { color: #336699 } /* Name.Variable.Class */
.syntax .vg { color: #dd7700 } /* Name.Variable.Global */
.syntax .vi { color: #3333bb } /* Name.Variable.Instance */
.syntax .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
  </style>
</head>
<body>
  <div id="content">
    
      <h1 class="heading"><span>Jinja</span></h1>
      <h2 class="subheading">Streaming Interface</h2>
    
    
    <div id="toc">
      <h2>Navigation</h2>
      <ul>
        <li><a href="index.html">back to index</a></li>
      </ul>
      
    </div>
    
    <div id="contentwrapper">
      <p>With Jinja 1.1 onwards it's possible to stream the template output. This is
usually a bad idea because it's slower than <cite>render()</cite> but there are some
situations where it's useful.</p>
<p>If you for example generate a file with a couple of megabytes you may want
to pass the stream to the WSGI interface in order to keep the amount of
memory used low and deliver the output to the browser as fast as possible.</p>
<p>The streaming interface is straightforward. Instead of using <cite>render()</cite> you
can call <cite>stream()</cite> which does pretty much the same but doesn't return a
string but a <cite>TemplateStream</cite>:</p>
<div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">tmpl</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">from_string</span><span class="p">(</span><span class="s">&quot;&lt;ul&gt;{</span><span class="si">% f</span><span class="s">or item in seq %}</span><span class="se">\n</span><span class="s">  &lt;li&gt;{{ loop.index &quot;</span>
<span class="gp">... </span>                       <span class="s">&quot;}} - {{ item }}&lt;/li&gt;</span><span class="se">\n</span><span class="s">{</span><span class="si">%- e</span><span class="s">ndfor %}&lt;/ul&gt;&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span> <span class="o">=</span> <span class="n">tmpl</span><span class="o">.</span><span class="n">stream</span><span class="p">(</span><span class="n">seq</span><span class="o">=</span><span class="nb">range</span><span class="p">(</span><span class="mf">4</span><span class="p">))</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="go">&#39;&lt;ul&gt;&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="go">u&#39;\n  &lt;li&gt;1 - 0&lt;/li&gt;&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="go">u&#39;\n  &lt;li&gt;2 - 1&lt;/li&gt;&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="go">u&#39;\n  &lt;li&gt;3 - 2&lt;/li&gt;&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="go">u&#39;\n  &lt;li&gt;4 - 3&lt;/li&gt;&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="go">&#39;&lt;/ul&gt;&#39;</span>
</pre></div>
<p>As you can see each iteration is threated as template event here. But also
other tags trigger events. Basically every tag yields one event, the
<cite>print</cite> tag too. The only exception is the variable substitution syntax which
is inserted into the template text data.</p>
<p>Because some protocols like <cite>WSGI</cite> flush after each iteration if passed as
response iterable it's better to buffer some events internally. You can do
this by enable buffering using <cite>enable_buffering</cite> and passing it the buffer
size which must be greater than one:</p>
<div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">enable_buffering</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mf">3</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="go">u&#39;&lt;ul&gt;\n  &lt;li&gt;1 - 0&lt;/li&gt;\n  &lt;li&gt;2 - 1&lt;/li&gt;&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
<span class="go">u&#39;\n  &lt;li&gt;3 - 2&lt;/li&gt;\n  &lt;li&gt;4 - 3&lt;/li&gt;&lt;/ul&gt;&#39;</span>
</pre></div>
<p>This will buffer 3 events before yielding. Disabling buffering works using the
<cite>disable_buffering</cite> method. You can enable and disable buffering on the fly also
if you have already iterated over that stream. To check if you are in buffered
or unbuffered mode you can use the <cite>.buffered</cite> property:</p>
<div class="syntax"><pre><span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">buffered</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">enable_buffering</span><span class="p">(</span><span class="mf">20</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">buffered</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">disable_buffering</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">stream</span><span class="o">.</span><span class="n">buffered</span>
<span class="go">False</span>
</pre></div>
<div class="admonition-note admonition">
<p class="first admonition-title">Note</p>
<p>Jinja uses buffering internally for some constructs like macros. A macro
call is yielded as one event, independently of the internal structure.</p>
<p class="last">The same applies to recursive for loops and <cite>{% filter %}</cite> tags.</p>
</div>

    </div>
  </div>
</body>
<!-- generated on: 2007-11-17 18:18:07.824343
     file id: streaming -->
</html>