views:

402

answers:

4

Using Chris Atlee's python poster library is there any way to include cookie handling? I have python http login code, which works with cookies:

cookiejar = cookielib.CookieJar()
urlOpener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
request = urllib2.Request(login_url, params)
result = urlOpener.open(request)

But when I need to upload a file, I don't know how to use both poster lib code and cookie handling code. Poster lib seems to need to call urllib2.urlopen() and not some custom url opener, like in the code above.

For instance, I don't know how to use cookies with the python file post code below:

register_openers()
params = {'file': open("test.txt", "rb"), 'name': 'upload test'}
datagen, headers = multipart_encode(params)
request = urllib2.Request(upload_url, datagen, headers)
result = urllib2.urlopen(request)
A: 

Have you tried this:

cookiejar = cookielib.CookieJar()
urlOpener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
register_openers()
params = {'file': open("test.txt", "rb"), 'name': 'upload test'}
datagen, headers = multipart_encode(params)
request = urllib2.Request(upload_url, datagen, headers)
result = urlOpener.open(request)
THC4k
I have tried that. Using the python script found at http://pastebin.com/f2e8ec53c, it fails to upload. The script errors and I get some tracebacks (http://pastebin.com/m6d7111f6) from the script, along with these tracebacks from the django dev server: http://pastebin.com/m62d1da24. I may be setting things up wrong, but I don't think your suggestion is correct. Thanks for the help
pmates
A: 

I've figured out how to do this. I'm not sure if this is the best way to go about things, but it works, so I'll share it. In order to use the poster lib with cookies one must add urllib2.HTTPCookiProcessor to the opener built in poster.streaminghttp.register_openers().

Essentially, modify poster.streaminghttp.register_openers() to look like the code below, and if you want to cookie handling, pass in a cookiejar object.

def register_openers(cookiejar=None):
    """Register the streaming http handlers in the global urllib2 default
    opener object.

    Returns the created OpenerDirector object."""
    handlers = [StreamingHTTPHandler, StreamingHTTPRedirectHandler]
    if hasattr(httplib, "HTTPS"):
        handlers.append(StreamingHTTPSHandler)

    if cookiejar:
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar), *handlers)
    else:
        opener = urllib2.build_opener(*handlers)


    urllib2.install_opener(opener)

    return opener

Sample Usage:

# Logging in
import urllib, urllib2, cookielib

from poster.encode import multipart_encode
from poster.streaminghttp import register_openers

cookiejar = cookielib.CookieJar()
loginOpener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))

params = urllib.urlencode({'username':'admin', 'password':'default'})
login_url = "http://127.0.0.1:8000/account/login/"
request = urllib2.Request(login_url, params)
login = loginOpener.open(request)

# Upload File
# use the login cookie for file upload
register_openers(cookiejar=cookiejar)

params = {'entity_file': open("test.txt", "rb"),'name': 'test', 'action':'upload'}
upload_url = "http://127.0.0.1:8000/upload/"

datagen, headers = multipart_encode(params)

request = urllib2.Request(upload_url, datagen, headers)
result = urllib2.urlopen(request)
pmates
A: 

You don't have to modify the original source code, just install all required openers manually (without calling register_openers()):

import urllib2
import cookielib
import poster

handlers = [poster.streaminghttp.StreamingHTTPHandler(),
            poster.streaminghttp.StreamingHTTPRedirectHandler(),
            urllib2.HTTPCookieProcessor(cookielib.CookieJar())]

urllib2.install_opener(urllib2.build_opener(*handlers))


datagen, headers = poster.encode.multipart_encode({"image1": open("DSC0001.jpg", "rb")})

request = urllib2.Request("http://localhost:5000/upload_image", datagen, headers)

print urllib2.urlopen(request).read()
Christian Affolter
A: 

I sent an email to Chris AtLee asking whether we could get a basic authentication example. He was very cool about answering my questions and even ran some example code I sent him.

To include cookie handling, you do something like this:

opener = poster.streaminghttp.register_openers()
opener.add_handler(urllib2.HTTPCookieProcessor(cookielib.CookieJar())) # Add cookie handler
params = {'file': open("test.txt", "rb"), 'name': 'upload test'}
datagen, headers = poster.encode.multipart_encode(params)
request = urllib2.Request(upload_url, datagen, headers)
result = urllib2.urlopen(request)

To add basic authentication to the request, you simply do this (I added the base64 encode line for completeness):

opener = poster.streaminghttp.register_openers()
params = {'file': open("test.txt", "rb"), 'name': 'upload test'}
datagen, headers = poster.encode.multipart_encode(params)
request = urllib2.Request(upload_url, datagen, headers)
auth = base64.encodestring('%s:%s' % ('username', 'password'))[:-1] # This is just standard un/pw encoding  
request.add_header('Authorization', 'Basic %s' % auth ) # Add Auth header to request
result = urllib2.urlopen(request)

Hope this helps. And another big thanks to Chris AtLee.

Cameron O'Rourke