<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body style="font-family: Verdana,Geneva,sans-serif" text="#000000"
    bgcolor="#FFFFFF">
    <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>
    This is a bugfix release, recommended for all users of Crochet.<br>
    <br>
    Crochet can be downloaded from <a
      href="https://pypi.python.org/pypi/crochet">https://pypi.python.org/pypi/crochet</a>
    or by running:<br>
    <br>
    <tt>    $ pip install crochet</tt><br>
    <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>