1
<?xml version="1.0"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><title>Twisted Documentation: The Twisted FAQ</title><link href="../howto/stylesheet.css" type="text/css" rel="stylesheet" /></head><body bgcolor="white"><h1 class="title">The Twisted FAQ</h1><div class="toc"><ol><li><a href="#auto0">General</a></li><ul><li><a href="#auto1">What is Twisted?</a></li><li><a href="#auto2">Why should I use Twisted?</a></li><li><a href="#auto3">I have a problem getting Twisted.</a></li><li><a href="#auto4">Why is Twisted so big?</a></li><li><a href="#auto5">But won't Twisted bloat my program, since it's so big?</a></li></ul><li><a href="#auto6">Stability</a></li><ul><li><a href="#auto7">Does the 1.0 release mean that all of Twisted's APIs are stable?</a></li><li><a href="#auto8">Which parts of Twisted are stable?</a></li></ul><li><a href="#auto9">Installation</a></li><ul><li><a href="#auto10">I run mktap (from site-packages/twisted/scripts/mktap.py)
3
and nothing happens!</a></li><li><a href="#auto11">Why do the Debian packages for Alphas and Release Candidates have weird versions containing old version numbers?</a></li></ul><li><a href="#auto12">Core Twisted</a></li><ul><li><a href="#auto13">How can I access self.factory from my Protocol's __init__?</a></li><li><a href="#auto14">Where can I find out how to write Twisted servers?</a></li><li><a href="#auto15">When I try to install my reactor, I get errors about a reactor
4
already being installed. What gives?</a></li><li><a href="#auto16">twistd won't load my .tap file! What's this
5
Ephemeral nonsense?</a></li><li><a href="#auto17">I get Interrupted system call errors when I use os.popen2. How do I read results from a sub-process in
6
Twisted?</a></li><li><a href="#auto18">Why don't my spawnProcess programs see my environment variables?</a></li><li><a href="#auto19">My Deferred or DeferredList never fires, so my program just mysteriously
7
hangs! What's wrong?</a></li><li><a href="#auto20">My exceptions and tracebacks aren't getting printed!</a></li><li><a href="#auto21">How do I use Deferreds to make my blocking code non-blocking?</a></li><li><a href="#auto22">I get exceptions.ValueError: signal only works in main thread when I
8
try to run my Twisted program! What's wrong?</a></li><li><a href="#auto23">I'm trying to stop my program with sys.exit(), but Twisted
9
seems to catch it! How do I exit my program?</a></li><li><a href="#auto24">How do I find out the IP address of the other end of my connection?</a></li></ul><li><a href="#auto25">Web</a></li><ul><li><a href="#auto26">Is the Twisted web server a toy?</a></li><li><a href="#auto27">But can Twisted Web do PHP?</a></li><li><a href="#auto28">And can Twisted Web do virtual hosting?</a></li><li><a href="#auto29">How do I use twisted.web to do complex things?</a></li><li><a href="#auto30">I've been using Woven since before it was called Woven. I just upgraded
10
and now I'm getting a confusing traceback talking about INodeMutator. What
11
gives?</a></li><li><a href="#auto31">My Woven pages are sent to the browser with a trailing slash appended to the
12
URL, which breaks all of the relative links. How do I get rid of the trailing
13
slash?</a></li><li><a href="#auto32">Argh! When using Woven, my newlines get mangled inside a <pre></a></li><li><a href="#auto33">When trying to use Guard, I get infinite redirects to URLs with long
14
hexadecimal numbers. What's the deal?</a></li></ul><li><a href="#auto34">Perspective Broker</a></li><ul><li><a href="#auto35">How can I get the reference to a client from a Perspective?</a></li></ul><li><a href="#auto36">Requests and Contributing</a></li><ul><li><a href="#auto37">Twisted is cool, but I need to add more functionality.</a></li><li><a href="#auto38">I have a patch. How do I maximize the chances the Twisted developers
15
will include it?</a></li><li><a href="#auto39">And to whom do I send it?</a></li><li><a href="#auto40">My company would love to use Twisted, but it's missing feature X, can you implement it?</a></li></ul><li><a href="#auto41">Documentation</a></li><ul><li><a href="#auto42">Twisted really needs documentation for X, Y or Z - how come it's not documented?.</a></li><li><a href="#auto43">Wow the Twisted documentation is nice! I want my docs to look like that
16
too!</a></li></ul><li><a href="#auto44">Communicating with us</a></li><ul><li><a href="#auto45">There's a bug in Twisted. Where do I report it?</a></li><li><a href="#auto46">Where do I go for help?</a></li><li><a href="#auto47">How do I e-mail a Twisted developer?</a></li></ul></ol></div><div class="content"><span></span><h2>General<a name="auto0"></a></h2><h3>What is <q>Twisted</q>?<a name="auto1"></a></h3><p>Please see
17
<a href="http://twistedmatrix.com/products/twisted">Twisted</a></p><h3>Why should I use Twisted?<a name="auto2"></a></h3><p>See <a href="http://twistedmatrix.com/services/twisted-advantage">The
18
Twisted Advantage</a></p><h3>I have a problem <q>getting</q> Twisted.<a name="auto3"></a></h3><p>Did you check the HOWTO collection? There are so many documents there
19
that they might overwhelm you... try starting from the index, reading through
20
the overviews and seeing if there seems to be a chapter which explains what
21
you need to. You can try reading the PostScript or PDF formatted books,
22
inside the distribution. And, remember, the source will be with
23
you... always.</p><h3>Why is Twisted so big?<a name="auto4"></a></h3><p>Twisted is a lot of things, rolled into one big package. We're not sure if
24
it'll stay this way, yet, but for now, if you have only specific needs, we
25
recommend grabbing the big Twisted tarball, and if you want, you can run the
26
'setup.py' script with a modified config file to generate a package with only
27
certain Twisted sub-packages. Twisted as a whole makes it into many operating
28
system distributions (FreeBSD, Debian and Gentoo, at least) so size shouldn't
29
be an issue for the end developer or user. In addition, packaging Twisted
30
as a whole makes sure the end users do not have to worry about versioning
31
parts of Twisted and inter-version compatibility.</p><p>If you are distributing Twisted to end-users, you can base your distribution
32
on the <q>Nodocs</q> packages, which are signficantly smaller.</p><h3>But won't Twisted bloat my program, since it's so big?<a name="auto5"></a></h3><p>No. You only need to import the sub-packages which you want to use, meaning
33
only those will be loaded into memory. So if you write a low-level network
34
protocol, you'd only import twisted.internet, leaving out extraneous things
35
like twisted.web, etc. Twisted itself is very careful with internal
36
dependancies, so importing one subpackage is not likely to import the whole
37
twisted package.</p><h2>Stability<a name="auto6"></a></h2><h3>Does the 1.0 release mean that all of Twisted's APIs are stable?<a name="auto7"></a></h3><p>No, only specific parts of Twisted are stable, i.e. we only promise
38
backwards compatibility for some parts of Twisted. While these APIs may be
39
extended, they will not change in ways that break existing code that uses
40
them. </p><p>While other parts of Twisted are not stable, we will however do
41
our best to make sure that there is backwards compatibility for these parts
42
as well. In general, the more the module or package are used, and the closer they
43
are to being feature complete, the more we will concentrate on providing backwards
44
compatibility when API changes take place.</p><h3>Which parts of Twisted are stable?<a name="auto8"></a></h3><p>Only modules explictily marked as such can be considered stable. Semi-stable
45
modules may change, but not in a large way and some sort of backwards-compatibily
46
will probably be provided. If no comment about API stability is present, assume
47
the module is unstable.</p><p>In Twisted 1.1, <em>most of twisted.internet, .cred and
48
.application are completely stable</em> (excepting of course code
49
marked as deprecated).</p><p>But as always, the only accurate way of knowing a module's stability is reading
50
the module's docstrings.</p><h2>Installation<a name="auto9"></a></h2><h3>I run mktap (from site-packages/twisted/scripts/mktap.py)
51
and nothing happens!<a name="auto10"></a></h3><p>Don't run scripts out of <code>site-packages</code>. The Windows
52
installer should install executable scripts to someplace like
53
<code>C:\Python22\scripts\</code>, *nix installers put them in
54
<code>$PREFIX/bin</code>, which should be in your $PATH.</p><h3>Why do the Debian packages for Alphas and Release Candidates have weird versions containing old version numbers?<a name="auto11"></a></h3><p>
55
An example: 1.0.6+1.0.7rc1-1
58
In Debian versioning, 1.0.7rc1 is <em>greater than</em> 1.0.7. This
59
means that if you install a package with Version: 1.0.7rc1, and then
60
that package gets a new version 1.0.7, apt will not upgrade it for
61
you, because 1.0.7 looks like an older version. So, we prefix the
62
previous version to the actual version. 1.0.6+1.0.7rc1 is <em>less
65
</p><h2>Core Twisted<a name="auto12"></a></h2><h3>How can I access self.factory from my Protocol's __init__?<a name="auto13"></a></h3><p>You can't. A Protocol doesn't have a Factory when it is created. Instead,
66
you should probably be doing that in your Protocol's
67
<code>connectionMade</code> method.</p><p>Similarly you shouldn't be doing <q>real</q> work, like connecting to
68
databases, in a Factory's <code>__init__</code> either. Instead, do that in
69
<code>startFactory</code>.</p><p>See <a href="servers.html">Writing Servers</a> and
70
<a href="clients.html">Writing Clients</a> for more details.</p><h3>Where can I find out how to write Twisted servers?<a name="auto14"></a></h3><p>Try <a href="servers.html">Writing Servers</a>.</p><h3>When I try to install my reactor, I get errors about a reactor
71
already being installed. What gives?<a name="auto15"></a></h3><p>Here's the rule - installing a reactor should always be the
72
<strong>first</strong> thing you do, and I do mean first. Importing other stuff
73
before you install the reactor can break your code.</p><p>Tkinter and wxPython support, as they do not install a new reactor, can be
74
done at any point, IIRC.</p><h3><code>twistd</code> won't load my <code>.tap</code> file! What's this
75
Ephemeral nonsense?<a name="auto16"></a></h3><p>When the pickled application state cannot be loaded for some reason, it
76
is common to get a rather opaque error like so:</p><pre class="shell">
79
Failed to load application: global name 'initRun' is not defined
80
</pre><p>The rest of the error will try to explain how to solve this problem,
81
but a short comment first: this error is indeed terse -- but there is
82
probably more data available elsewhere -- namely, the <code>twistd.log</code>
83
file. Open it up to see the full exception.</p><p>The error might also look like this:</p><pre class="shell">
84
Failed to load application: <twisted.persisted.styles.Ephemeral instance at
85
0x82450a4> is not safe for unpickling
86
</pre><p>To load a <code>.tap</code> file, as with any unpickling operation, all
87
the classes used by all the objects inside it must be accessible at the time
88
of the reload. This may require the PYTHONPATH variable to have the same
89
directories as were available when the application was first pickled.</p><p>A common problem occurs in single-file programs which define a few
90
classes, then create instances of those classes for use in a server of some
91
sort. If the class is used directly, the name of the class will be recorded
92
in the <code>.tap</code> file as something like
93
<code>__main__.MyProtocol</code>. When the application is reloaded, it will
94
look for the class definition in <code>__main__</code>, which probably won't
95
have it. The unpickling routines need to know the module name, and therefore
96
the source file, from which the class definition can be loaded.</p><p>The way to fix this is to import the class from the same source file that
97
defines it: if your source file is called <code>myprogram.py</code> and
98
defines a class called <code>MyProtocol</code>, you will need to do a
99
<code>from myprogram import MyProtocol</code> before (and in the same
100
namespace as) the code that references the MyProtocol class. This makes it
101
important to write the module cleanly: doing an <code>import
102
myprogram</code> should only define classes, and should not cause any other
103
subroutines to get run. All the code that builds the Application and saves
104
it out to a <code>.tap</code> file must be inside an <code>if __name__ ==
105
'__main__'</code> clause to make sure it is not run twice (or more).</p><p>When you import the class from the module using an <q>external</q> name,
106
that name will be recorded in the pickled <code>.tap</code> file. When the
107
<code>.tap</code> is reloaded by <code>twistd</code>, it will look for
108
<code>myprogram.py</code> to provide the definition of
109
<code>MyProtocol</code>.</p><p>Here is a short example of this technique:</p><pre class="python">
110
<span class="py-src-comment"># file dummy.py
111
</span><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span><span class="py-src-op">.</span><span class="py-src-variable">internet</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">protocol</span><span class="py-src-newline">
112
</span><span class="py-src-keyword">class</span> <span class="py-src-identifier">Dummy</span><span class="py-src-op">(</span><span class="py-src-parameter">protocol</span><span class="py-src-op">.</span><span class="py-src-parameter">Protocol</span><span class="py-src-op">)</span><span class="py-src-op">:</span> <span class="py-src-keyword">pass</span><span class="py-src-newline">
113
</span><span class="py-src-keyword">if</span> <span class="py-src-variable">__name__</span> <span class="py-src-op">==</span> <span class="py-src-string">'__main__'</span><span class="py-src-op">:</span><span class="py-src-newline">
114
</span><span class="py-src-indent"> </span><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span><span class="py-src-op">.</span><span class="py-src-variable">application</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">service</span><span class="py-src-op">,</span> <span class="py-src-variable">internet</span><span class="py-src-newline">
115
</span> <span class="py-src-variable">a</span> <span class="py-src-op">=</span> <span class="py-src-variable">service</span><span class="py-src-op">.</span><span class="py-src-variable">Application</span><span class="py-src-op">(</span><span class="py-src-string">"dummy"</span><span class="py-src-op">)</span><span class="py-src-newline">
116
</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">dummy</span><span class="py-src-newline">
117
</span> <span class="py-src-variable">f</span> <span class="py-src-op">=</span> <span class="py-src-variable">protocol</span><span class="py-src-op">.</span><span class="py-src-variable">Factory</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline">
118
</span> <span class="py-src-variable">f</span><span class="py-src-op">.</span><span class="py-src-variable">protocol</span> <span class="py-src-op">=</span> <span class="py-src-variable">dummy</span><span class="py-src-op">.</span><span class="py-src-variable">Dummy</span> <span class="py-src-comment"># Note! Not "Dummy"</span><span class="py-src-newline">
119
</span> <span class="py-src-variable">internet</span><span class="py-src-op">.</span><span class="py-src-variable">TCPServer</span><span class="py-src-op">(</span><span class="py-src-number">2000</span><span class="py-src-op">,</span> <span class="py-src-variable">f</span><span class="py-src-op">)</span><span class="py-src-op">.</span><span class="py-src-variable">setServiceParent</span><span class="py-src-op">(</span><span class="py-src-variable">service</span><span class="py-src-op">.</span><span class="py-src-variable">IServiceCollect</span><span class="py-src-op">(</span><span class="py-src-variable">a</span><span class="py-src-op">)</span><span class="py-src-op">)</span><span class="py-src-newline">
120
</span> <span class="py-src-variable">a</span><span class="py-src-op">.</span><span class="py-src-variable">save</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline">
121
</span><span class="py-src-dedent"></span><span class="py-src-endmarker"></span></pre><h3>I get <q>Interrupted system call</q> errors when I use <code class="python">os.popen2</code>. How do I read results from a sub-process in
122
Twisted?<a name="auto17"></a></h3><p>You should be using <code class="python">reactor.spawnProcess</code> (see
123
<code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.internet.interfaces.IReactorProcess.spawnProcess.html" title="twisted.internet.interfaces.IReactorProcess.spawnProcess">interfaces.IReactorProcess.spawnProcess</a></code>).
124
There's also a convenience function, <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.internet.utils.getProcessOutput.html" title="twisted.internet.utils.getProcessOutput">getProcessOutput</a></code>, in <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.internet.utils.html" title="twisted.internet.utils">twisted.internet.utils</a></code>.</p><h3>Why don't my spawnProcess programs see my environment variables?<a name="auto18"></a></h3><p><code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.internet.interfaces.IReactorProcess.spawnProcess.html" title="twisted.internet.interfaces.IReactorProcess.spawnProcess">spawnProcess</a></code>
125
defaults to clearing the environment of child processes as a security
126
feature. You can either provide a dictionary with exactly the name-value
127
pairs you want the child to use, or you can simply pass in
128
<code>os.environ</code> to inherit the complete environment. </p><h3>My Deferred or DeferredList never fires, so my program just mysteriously
129
hangs! What's wrong?<a name="auto19"></a></h3><p>It really depends on what your program is doing, but the most common cause
130
is this: it <em>is</em> firing -- but it's an error, not a success, and you
131
have forgotten to add an <a href="glossary.html#errback">errback</a>, so
132
nothing happens. Always add errbacks!</p><p>The reason this happens is that unhandled errors in Deferreds get printed
133
when the Deferred is garbage collected. Make sure your Deferred is garbage
134
collected by deleting all references to it when you are done with it, e.g.
135
after <code class="python">callback()</code> is called.</p><h3>My exceptions and tracebacks aren't getting printed!<a name="auto20"></a></h3><p>See previous question.</p><h3>How do I use Deferreds to make my blocking code non-blocking?<a name="auto21"></a></h3><a name="deferreds-aren't-magic"></a><p>You don't. Deferreds don't magically turn a blocking function call into a
136
non-blocking one. A Deferred is just a simple object that represents a
137
<em>deferred result</em>, with methods to allow convenient adding of
138
callbacks. (This is a common misunderstanding; suggestions on how to make this
139
clearer in the <a href="defer.html">Deferred Execution</a> howto are
140
welcome!)</p><p>If you have blocking code that you want to use non-blockingly in Twisted,
141
either rewrite it to be non-blocking, or run it in a thread. There is a
142
convenience function, <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.internet.threads.deferToThread.html" title="twisted.internet.threads.deferToThread">deferToThread</a></code>, to help you with the
143
threaded approach -- but be sure to read <a href="threading.html">Using
144
Threads in Twisted</a>.</p><h3>I get <q>exceptions.ValueError: signal only works in main thread</q> when I
145
try to run my Twisted program! What's wrong?<a name="auto22"></a></h3><p>The default reactor, by default, will install signal handlers to catch
146
events like Ctrl-C, SIGTERM, and so on. However, you can't install signal
147
handlers from non-main threads in Python, which means that
148
<code>reactor.run()</code> will cause an
149
error. Pass the <code>installSignalHandlers=0</code> keyword argument to
150
<code>reactor.run</code> (or <code>Application.run</code>) to work around
151
this.</p><h3>I'm trying to stop my program with <code>sys.exit()</code>, but Twisted
152
seems to catch it! How do I exit my program?<a name="auto23"></a></h3><p>Use <code>reactor.stop()</code> instead. This will cleanly shutdown the
153
reactor.</p><h3>How do I find out the IP address of the other end of my connection?<a name="auto24"></a></h3><p>The <code>.transport</code> object (which implements the <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.internet.interfaces.ITransport.html" title="twisted.internet.interfaces.ITransport">ITransport</a></code> interface) offers a pair
154
of methods named <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.internet.interfaces.ITransport.getPeer.html" title="twisted.internet.interfaces.ITransport.getPeer">getPeer</a></code> and <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.internet.interfaces.ITransport.getHost.html" title="twisted.internet.interfaces.ITransport.getHost">getHost</a></code>.
155
<code>getPeer</code> will give you a tuple that describes the address of the
156
system at the other end of the connection. For example:</p><pre class="python">
157
<span class="py-src-keyword">class</span> <span class="py-src-identifier">MyProtocol</span><span class="py-src-op">(</span><span class="py-src-parameter">protocol</span><span class="py-src-op">.</span><span class="py-src-parameter">Protocol</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline">
158
</span><span class="py-src-indent"> </span><span class="py-src-keyword">def</span> <span class="py-src-identifier">connectionMade</span><span class="py-src-op">(</span><span class="py-src-parameter">self</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline">
159
</span><span class="py-src-indent"> </span><span class="py-src-keyword">print</span> <span class="py-src-string">"connection from"</span><span class="py-src-op">,</span> <span class="py-src-variable">self</span><span class="py-src-op">.</span><span class="py-src-variable">transport</span><span class="py-src-op">.</span><span class="py-src-variable">getPeer</span><span class="py-src-op">(</span><span class="py-src-op">)</span><span class="py-src-newline">
160
</span><span class="py-src-dedent"></span><span class="py-src-dedent"></span><span class="py-src-endmarker"></span></pre><h2>Web<a name="auto25"></a></h2><h3>Is the Twisted web server a toy?<a name="auto26"></a></h3><p>No. It is a production grade server. It is running continously on several
161
sites and has been proven quite stable. The server can take loads of up to 3000
162
users at a time and still keep churning several million requests a day, even on
163
low end hardware. It can serve static files or dynamically rendered pages.</p><h3>But can Twisted Web do PHP?<a name="auto27"></a></h3><p>Yes. It works out-of-the-box, so long as you've got the standalone php
164
interpreter installed.
165
</p><h3>And can Twisted Web do virtual hosting?<a name="auto28"></a></h3><p>Can it ever!</p><p>You can decide to go with one big process for all of them, a front server
166
and a seperate server for each virtual host (for example, for permission
167
reasons), and you can even mix-and-match between Apache and Twisted (for
168
example, put Apache in the front and have Twisted handle some subset of the
169
virtual host).</p><h3>How do I use twisted.web to do complex things?<a name="auto29"></a></h3><p>See <a href="using-twistedweb.html">the Twisted.Web Howto</a>.</p><h3>I've been using Woven since before it was called Woven. I just upgraded
170
and now I'm getting a confusing traceback talking about INodeMutator. What
171
gives?<a name="auto30"></a></h3><p>You probably have code that's survived the upgrade from PyXML's
172
<code>minidom</code> to Twisted's <code>microdom</code>. Try deleting any
173
<code>.pxp</code> files that you have lying around and the error will probably
174
go away.</p><h3>My Woven pages are sent to the browser with a trailing slash appended to the
175
URL, which breaks all of the relative links. How do I get rid of the trailing
176
slash?<a name="auto31"></a></h3><p>If you are subclassing <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.page.Page.html" title="twisted.web.woven.page.Page">Page</a></code>, you can add a class attribute <code class="python">addSlash = 0</code>, like this:</p><pre class="python">
177
<span class="py-src-keyword">class</span> <span class="py-src-identifier">Foo</span><span class="py-src-op">(</span><span class="py-src-parameter">page</span><span class="py-src-op">.</span><span class="py-src-parameter">Page</span><span class="py-src-op">)</span><span class="py-src-op">:</span><span class="py-src-newline">
178
</span><span class="py-src-indent"> </span><span class="py-src-variable">addSlash</span> <span class="py-src-op">=</span> <span class="py-src-number">0</span><span class="py-src-newline">
179
</span><span class="py-src-dedent"></span><span class="py-src-endmarker"></span></pre><p>If you are still subclassing <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.controller.Controller.html" title="twisted.web.woven.controller.Controller">Controller</a></code>, you can put the <code class="python">addSlash = 0</code> there. Consider subclassing <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.page.Page.html" title="twisted.web.woven.page.Page">Page</a></code> instead, as having a <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.model.Model.html" title="twisted.web.woven.model.Model">Model</a></code>, <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.view.View.html" title="twisted.web.woven.view.View">View</a></code>, <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.controller.Controller.html" title="twisted.web.woven.controller.Controller">Controller</a></code> triad as the base of a
180
<code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.page.Page.html" title="twisted.web.woven.page.Page">Page</a></code> will be deprecated
181
in the near future.</p><p>If you're just using the generic <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.page.Page.html" title="twisted.web.woven.page.Page">Page</a></code> instance, you can set it after
182
creation like this:</p><pre class="python">
183
<span class="py-src-variable">resource</span> <span class="py-src-op">=</span> <span class="py-src-variable">page</span><span class="py-src-op">.</span><span class="py-src-variable">Page</span><span class="py-src-op">(</span><span class="py-src-string">"foo"</span><span class="py-src-op">)</span><span class="py-src-newline">
184
</span><span class="py-src-variable">resource</span><span class="py-src-op">.</span><span class="py-src-variable">addSlash</span> <span class="py-src-op">=</span> <span class="py-src-number">0</span><span class="py-src-newline">
185
</span><span class="py-src-endmarker"></span></pre><p>The default behavior of Woven is now to automatically add a slash
186
because it makes creating relative links far easier, ironically ;-)</p><h3>Argh! When using Woven, my newlines get mangled inside a <pre><a name="auto32"></a></h3><p>Use the <code>RawText</code> view.</p><h3>When trying to use Guard, I get infinite redirects to URLs with long
187
hexadecimal numbers. What's the deal?<a name="auto33"></a></h3><p>Are you using an RPY? Add a single line containing <code>cache()</code> as
188
the first line of your RPY.</p><p>An RPY file is executed every time it is accessed, so the call to <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.web.woven.guard.SessionWrapper.html" title="twisted.web.woven.guard.SessionWrapper">guard.SessionWrapper</a></code> is executed
189
once per request, making a new SessionWrapper for each request. There should be
190
only one SessionWrapper object for your application. Caching the RPY file
191
enforces this.</p><h2>Perspective Broker<a name="auto34"></a></h2><h3>How can I get the reference to a client from a Perspective?<a name="auto35"></a></h3><p>Firstly, the client must send a reference when it connects to the
192
perspective broker. This can be done by passing the reference as a parameter to
193
<code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.spread.pb.connect.html" title="twisted.spread.pb.connect">pb.connect</a></code>.</p><p>At the server end, you must override the <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.spread.pb.Perspective.attach.html" title="twisted.spread.pb.Perspective.attach">Perspective.attach</a></code>, which is called when a client attaches
194
to a perspective. The first argument of this method is a remote reference to
195
the client object that was passed to <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.spread.pb.connect.html" title="twisted.spread.pb.connect">pb.connect</a></code>. </p><p>Note that a single perspective can have many attached clients. For further
196
information, see <a href="pclients.html">Managing Clients of Perspectives</a>
197
HOWTO and the <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.spread.pb.html" title="twisted.spread.pb">twisted.spread.pb</a></code> API docs.</p><h2>Requests and Contributing<a name="auto36"></a></h2><h3>Twisted is cool, but I need to add more functionality.<a name="auto37"></a></h3><p>Great! Read our the docs, and if you're feeling generous, contribute
198
patches.</p><h3>I have a patch. How do I maximize the chances the Twisted developers
199
will include it?<a name="auto38"></a></h3><p>Use unified diff. Either use <code class="shell">svn diff</code>
200
or, better yet, make a clean checkout and use <code class="shell">diff
201
-urN</code> between them. Make sure your patch applies cleanly. In
202
your post to the mailing list, make sure it is inlined and without any
203
word wrapping.</p><h3>And to whom do I send it?<a name="auto39"></a></h3><p>Add it to the <a href="http://twistedmatrix.com/bugs/">bug tracker</a>, and if it's an urgent or important issue you may want to tell the <a href="http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python">mailing list</a>. about the issue you added</p><h3>My company would love to use Twisted, but it's missing feature X, can you implement it?<a name="auto40"></a></h3><p>You have 3 options:</p><ul><li>Pay one of the Twisted developers to implement the feature.</li><li>Implement the feature yourself.</li><li>Add a feature request to our bug tracker. We will try to implement the
204
feature, but there are no guarantees when and if this will happen.</li></ul><h2>Documentation<a name="auto41"></a></h2><h3>Twisted really needs documentation for X, Y or Z - how come it's not documented?.<a name="auto42"></a></h3><p>We are doing the best we can, and there is documentation
205
in progress for many parts of Twisted. There is a limit to how much we
206
can do in our free time. See also the answer to the next question.</p><h3>Wow the Twisted documentation is nice! I want my docs to look like that
207
too!<a name="auto43"></a></h3><p>Now you can, with <code class="API"><a href="http://twistedmatrix.com/documents/TwistedDocs/TwistedDocs-1.3.0/api/twisted.lore.html" title="twisted.lore">twisted.lore</a></code>. See the manual
208
page for <code class="shell">lore</code>. For
209
source format documentation, see <a href="policy/doc-standard.html">the documentation
210
standard description</a>. For a more comprehensive explanation, see
211
<a href="lore.html">the Lore HOWTO</a>.</p><h2>Communicating with us<a name="auto44"></a></h2><h3>There's a bug in Twisted. Where do I report it?<a name="auto45"></a></h3><p>Unless it is a show-stopper bug, we usually won't fix it if it's already
212
fixed in <a href="http://twistedmatrix.com/developers/cvs">Subversion</a>, so
213
you would do well to look there. Then send any pertinent information about the
214
bug (hopefully as much information needed to reproduce it: OS, Subversion
215
versions of any important files, Python version, code you wrote or things you
216
did to trigger the bug, etc.) to the <a href="http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python">mailing
217
list</a>. If no one answers immediately, you should add it to the <a href="http://twistedmatrix.com/bugs/">bug tracker</a>.</p><h3>Where do I go for help?<a name="auto46"></a></h3><p>Ask for help <a href="http://twistedmatrix.com/services/online-help">where
218
the Twisted team hangs out</a></p><h3>How do I e-mail a Twisted developer?<a name="auto47"></a></h3><p>First, note that in many cases this is the wrong thing to do: if
219
you have a question about a part of Twisted, it's usually better to
220
e-mail the mailing list. However, the preferred e-mail addresses for
221
all Twisted developers are listed in the file <q>CREDITS</q> in the
222
Subversion repository.</p></div><p><a href="../howto/index.html">Index</a></p><span class="version">Version: 1.3.0</span></body></html>
b'\\ No newline at end of file'