Running twisted reactor in iPython
<p>I'm aware this is normally done with twistd, but I'm wanting to use iPython to test out code 'live' on twisted code.</p>

<p><a href="http://stackoverflow.com/questions/4673375/how-to-start-twisteds-reactor-from-ipython">How to start twisted&#39;s reactor from ipython</a> asked basically the same thing but the first solution no longer works with current ipython/twisted, while the second is also unusable (thread raises multiple errors).</p>

<p><a href="https://gist.github.com/kived/8721434" rel="nofollow">https://gist.github.com/kived/8721434</a> has something called TPython which purports to do this, but running that seems to work except clients never connect to the server (while running the same clients works in the python shell).</p>

<p>Do I <em>have</em> to use Conch Manhole, or is there a way to get iPython to play nice (probably with _threadedselect).</p>

<p>For reference, I'm asking using ipython 5.0.0, python 2.7.12, twisted 16.4.1</p>

<p>Async code in general can be troublesome to run in a live interpreter. It's best just to run an async script in the background and do your iPython stuff in a separate interpreter. You can intercommunicate using files or TCP. If this went over your head, that's because it's not always simple and it might be best to avoid the hassle of possible.</p>

<p>However, you'll be happy to know there is an awesome project called <code>crochet</code> for using Twisted in non-async applications. It truly is one of my favorite modules and I'm shocked that it's not more widely used (you can change that ;D though). The <code>crochet</code> module has a <code>run_in_reactor</code> decorator that runs a Twisted reactor in a separate thread managed by <code>crochet</code> itself. Here is a quick class example that executes requests to a Star Wars RESTFul API, then stores the JSON response in a list.</p>

<pre><code>from __future__ import print_function
import json

from twisted.internet import defer, task
from twisted.web.client import getPage

from crochet import run_in_reactor, setup as setup_crochet
setup_crochet()

class StarWarsPeople(object):
    people_id = [_id for _id in range(1, 89)]
    people = []

    @run_in_reactor
    def requestPeople(self):
        """
        Request Star Wars JSON data from the SWAPI site.
        This occurs in a Twisted reactor in a separate thread.
        """
        for _id in self.people_id:
            url = 'http://swapi.co/api/people/{0}'.format(_id).encode('utf-8')
            d = getPage(url)
            d.addCallback(self.appendJSON)

    def appendJSON(self, response):
        """
        A callback which will take the response from the getPage() request, 
        convert it to JSON, then append it to self.people, which can be 
        accessed outside of the crochet thread.
        """
        response_json = json.loads(response.decode('utf-8'))
        #print(response_json)    # uncomment if you want to see output
        self.people.append(response_json)
</code></pre>

<p>Save this in a file (example: <code>swapi.py</code>), open iPython, import the newly created module, then run a quick test like so:</p>

<pre><code>from swapi import StarWarsPeople
testing = StarWarsPeople()
testing.requestPeople()

from time import sleep
for x in range(5):
    print(len(testing.people))
    sleep(2)
</code></pre>

<p>As you can see it runs in the background and stuff can still occur in the main thread. You can continue using the iPython interpreter as you usually do. You can even have a manhole running in the background for some cool hacking too!</p>

<h1>References</h1>

<ul>
<li><a href="https://crochet.readthedocs.io/en/1.5.0/introduction.html#crochet-use-twisted-anywhere" rel="nofollow">https://crochet.readthedocs.io/en/1.5.0/introduction.html#crochet-use-twisted-anywhere</a></li>
</ul>

python ipython twisted