<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html><body style='font-family: Verdana,Geneva,sans-serif'>
<p>Crochet is an MIT-licensed library that makes it easier to use Twisted from regular blocking code. Some use cases include:</p>
<ul class="simple">
<li>Easily use Twisted from a blocking framework like Django or Flask.</li>
<li>Write a library that provides a blocking API, but uses Twisted for its implementation.</li>
<li>Port blocking code to Twisted more easily, by keeping a backwards compatibility layer.</li>
<li>Allow normal Twisted programs that use threads to interact with Twisted more cleanly from their threaded parts. For example this can be useful when using Twisted as a WSGI container.</li>
</ul>
<p>New in this release:</p>
<ul>
<li><tt class="docutils literal">crochet.wait_for</tt> implements the timeout/cancellation pattern documented in previous versions of Crochet.</li>
<li>Functions wrapped with <tt class="docutils literal">wait_for</tt> and <tt class="docutils literal">run_in_reactor</tt> can now be accessed via the <tt class="docutils literal">wrapped_function</tt> attribute, to ease unit testing of the underlying Twisted code.</li>
<li>Bug fixes, documentation improvements and more - for a full list see the</li>
</ul>
<p>Documentation can be found at <a class="reference external" href="https://crochet.readthedocs.org/">http://crochet.readthedocs.org</a></p>
<p>Bugs and feature requests should be filed at the project <a href="https://github.com/itamarst/crochet">https://github.com/itamarst/crochet</a></p>
<p> </p>
<p>Here’s an example of a program using Crochet. Notice that you get a completely blocking interface to Twisted and do not need to run the Twisted reactor, the event loop, yourself.</p>
<div class="highlight">
<pre style="padding-left: 30px;"><span class="c">#!/usr/bin/python</span>
<span class="sd">"""</span>
<span class="sd">Do a DNS lookup using Twisted's APIs.</span>
<span class="sd">"""</span>
<span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">print_function</span>

<span class="c"># The Twisted code we'll be using:</span>
<span class="kn">from</span> <span class="nn">twisted.names</span> <span class="kn">import</span> <span class="n">client</span>

<span class="kn">from</span> <span class="nn">crochet</span> <span class="kn">import</span> <span class="n">setup</span><span class="p">,</span> <span class="n">wait_for</span>
<span class="n">setup</span><span class="p">()</span>


<span class="c"># Crochet layer, wrapping Twisted's DNS library in a blocking call.</span>
<span class="nd">@wait_for</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mf">5.0</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">gethostbyname</span><span class="p">(</span><span class="n">name</span><span class="p">):</span>
    <span class="sd">"""Lookup the IP of a given hostname.</span>

<span class="sd">    Unlike socket.gethostbyname() which can take an arbitrary amount of time</span>
<span class="sd">    to finish, this function will raise crochet.TimeoutError if more than 5</span>
<span class="sd">    seconds elapse without an answer being received.</span>
<span class="sd">    """</span>
    <span class="n">d</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">lookupAddress</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
    <span class="n">d</span><span class="o">.</span><span class="n">addCallback</span><span class="p">(</span><span class="k">lambda</span> <span class="n">result</span><span class="p">:</span> <span class="n">result</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">payload</span><span class="o">.</span><span class="n">dottedQuad</span><span class="p">())</span>
    <span class="k">return</span> <span class="n">d</span>


<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
    <span class="c"># Application code using the public API - notice it works in a normal</span>
    <span class="c"># blocking manner, with no event loop visible:</span>
    <span class="kn">import</span> <span class="nn">sys</span>
    <span class="n">name</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
    <span class="n">ip</span> <span class="o">=</span> <span class="n">gethostbyname</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
    <span class="k">print</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="s">"->"</span><span class="p">,</span> <span class="n">ip</span><span class="p">)</span>
</pre>
</div>
<p> </p>
<p>Run on the command line:</p>
<div class="highlight-python">
<blockquote type="cite" style="padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px">
<pre>$ python blockingdns.py twistedmatrix.com
twistedmatrix.com -> 66.35.39.66</pre>
</blockquote>
</div>
<p> </p>
<div> </div>
</body></html>