Skip to content

Instantly share code, notes, and snippets.

@ldjebran
Last active September 23, 2016 08:25
Show Gist options
  • Save ldjebran/4a531e22dec6a439415b46ec50376891 to your computer and use it in GitHub Desktop.
Save ldjebran/4a531e22dec6a439415b46ec50376891 to your computer and use it in GitHub Desktop.
"""
twisted async/await with asyncio reactor
"""
import asyncio
from asyncio.tasks import ensure_future
try:
# as per github source the asyncio reactor is intended to be released in future version
# https://github.com/twisted/twisted/blob/trunk/src/twisted/internet/asyncioreactor.py
from twisted.internet import asyncioreactor
except:
# but for now we can use the reactor in tulip library
import txtulip.reactor as asyncioreactor
asyncioreactor.install()
from twisted.web import server
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints, defer
@defer.inlineCallbacks
def get2(request, resource):
resource.number_of_requests += 1
a = yield "Hello world (number:{0}, IP:{1}, session:{2})".format(resource.number_of_requests,
request.getClientIP(),
request.getSession().uid.decode()).encode()
return a
async def get(request, resource):
# please notice that we are awaiting a twisted deferred
content = await get2(request, resource)
# of course if an exception occur in get2 which is an inlineCallback, "a" will be a Failure instance
# the try except will not help here to catch the exception in differed, an instance check will be appropriate
# eg:
# if isinstance(a, Failure):
# # do some thing set the appropriate http status, log, etc ...
# note the asyncio sleep will work here
await asyncio.sleep(0)
request.setHeader(b"content-length", len(content))
request.write(content)
request.finish()
class HelloWorldResource(Resource):
isLeaf = True
number_of_requests = 0
def render_GET(self, request):
request.setHeader(b"content-type", b"text/plain")
async_func = get(request, self)
# defer a python async function
# replace ensureDeferred (that also work here) by it's asyncio counterpart ensure_future
# defer.ensureDeferred(async_func)
ensure_future(async_func)
return server.NOT_DONE_YET
endpoints.serverFromString(reactor, "tcp:8080").listen(server.Site(HelloWorldResource()))
reactor.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment