Mercurial > hg > simpypi
annotate tests/multipart.py @ 79:f42df1456565
add a giant example section
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Fri, 02 Mar 2012 16:25:05 -0800 |
parents | bb8d993376aa |
children |
rev | line source |
---|---|
63
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
1 """ |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
2 from |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
3 http://www.doughellmann.com/PyMOTW/urllib2/#uploading-files |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
4 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
5 Very very sad that python2 stdlib doesn't have this |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
6 """ |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
7 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
8 import itertools |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
9 import mimetools |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
10 import mimetypes |
64
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
11 import os |
63
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
12 import urllib |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
13 import urllib2 |
64
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
14 from cStringIO import StringIO |
63
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
15 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
16 class MultiPartForm(object): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
17 """Accumulate the data to be used when posting a form.""" |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
18 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
19 def __init__(self): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
20 self.form_fields = [] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
21 self.files = [] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
22 self.boundary = mimetools.choose_boundary() |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
23 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
24 def get_content_type(self): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
25 return 'multipart/form-data; boundary=%s' % self.boundary |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
26 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
27 def add_field(self, name, value): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
28 """Add a simple field to the form data.""" |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
29 self.form_fields.append((name, value)) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
30 |
64
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
31 def add_file(self, fieldname, path, mimetype=None): |
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
32 filename = os.path.basename(path) |
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
33 f = file(path) |
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
34 self.add_file_obj(fieldname, filename, f, mimetype) |
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
35 f.close() |
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
36 |
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
37 def add_file_obj(self, fieldname, filename, fileHandle, mimetype=None): |
bb8d993376aa
* convenience methods for multipart form
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
38 """Add a file object to be uploaded.""" |
63
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
39 body = fileHandle.read() |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
40 if mimetype is None: |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
41 mimetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream' |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
42 self.files.append((fieldname, filename, mimetype, body)) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
43 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
44 def post(self, url): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
45 request = urllib2.Request(url) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
46 body = str(self) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
47 request.add_header('Content-type', self.get_content_type()) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
48 request.add_header('Content-length', len(body)) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
49 request.add_data(body) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
50 return urllib2.urlopen(request) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
51 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
52 def __str__(self): |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
53 """Return a string representing the form data, including attached files.""" |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
54 # Build a list of lists, each containing "lines" of the |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
55 # request. Each part is separated by a boundary string. |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
56 # Once the list is built, return a string where each |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
57 # line is separated by '\r\n'. |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
58 parts = [] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
59 part_boundary = '--' + self.boundary |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
60 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
61 # Add the form fields |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
62 parts.extend( |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
63 [ part_boundary, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
64 'Content-Disposition: form-data; name="%s"' % name, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
65 '', |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
66 value, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
67 ] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
68 for name, value in self.form_fields |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
69 ) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
70 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
71 # Add the files to upload |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
72 parts.extend( |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
73 [ part_boundary, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
74 'Content-Disposition: file; name="%s"; filename="%s"' % \ |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
75 (field_name, filename), |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
76 'Content-Type: %s' % content_type, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
77 '', |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
78 body, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
79 ] |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
80 for field_name, filename, content_type, body in self.files |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
81 ) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
82 |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
83 # Flatten the list and add closing boundary marker, |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
84 # then return CR+LF separated data |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
85 flattened = list(itertools.chain(*parts)) |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
86 flattened.append('--' + self.boundary + '--') |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
87 flattened.append('') |
af1476a936fc
add a multipart processor so we can post damn files
Jeff Hammel <jhammel@mozilla.com>
parents:
diff
changeset
|
88 return '\r\n'.join(flattened) |