Skip to content

Instantly share code, notes, and snippets.

@lukemarsden
Created February 27, 2011 21:11
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save lukemarsden/846545 to your computer and use it in GitHub Desktop.
Save lukemarsden/846545 to your computer and use it in GitHub Desktop.
Simple function to do an HTTP POST using Twisted Agent
from twisted.web.iweb import IBodyProducer
from twisted.internet import defer
from twisted.web.client import Agent
from twisted.web.http_headers import Headers
import urllib
class StringProducer(object):
implements(IBodyProducer)
def __init__(self, body):
self.body = body
self.length = len(body)
def startProducing(self, consumer):
consumer.write(self.body)
return succeed(None)
def pauseProducing(self):
pass
def stopProducing(self):
pass
def httpRequest(url, values={}, headers={}, method='POST'):
# Construct an Agent.
agent = Agent(reactor)
data = urllib.urlencode(values)
d = agent.request(method,
url,
Headers(headers),
StringProducer(data) if data else None)
def handle_response(response):
if response.code == 204:
d = defer.succeed('')
else:
class SimpleReceiver(protocol.Protocol):
def __init__(s, d):
s.buf = ''; s.d = d
def dataReceived(s, data):
s.buf += data
def connectionLost(s, reason):
# TODO: test if reason is twisted.web.client.ResponseDone, if not, do an errback
s.d.callback(s.buf)
d = defer.Deferred()
response.deliverBody(SimpleReceiver(d))
return d
d.addCallback(handle_response)
return d
# Sample usage:
d = httpRequest(
"http://...",
{
'query_arg': 'value',
},
headers={'Content-Type': ['application/x-www-form-urlencoded']}
)
@nside
Copy link

nside commented Jan 29, 2014

Missing import: from zope.interface import implements

@nside
Copy link

nside commented Jan 29, 2014

Also line 16 should be

return defer.succeed(None)

@saoili
Copy link

saoili commented Apr 30, 2014

Also missing from twisted.internet import reactor and from twisted.internet import protocol

@yavalvas
Copy link

Also default mutable parameters. It would be better to use values=None, headers=None and after that set values/headers ={} if values/headers is None

@darkman66
Copy link

line 24

def httpRequest(url, values={}, headers={}, method='POST'):

avoid, it's evil ! Python dictionaries are references not a full copies of dictionary objects so you can see very unexpected side effects of such a use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment