43 Here's a sample session to show how to use this module.
44 At the moment, this is the only documentation.
53 Most of the time you start by creating a cookie. Cookies come in
54 three flavors, each with slighly different encoding semanitcs, but
57 >>> C = Cookie.SimpleCookie()
58 >>> C = Cookie.SerialCookie()
59 >>> C = Cookie.SmartCookie()
61 [Note: Long-time users of Cookie.py will remember using
62 Cookie.Cookie() to create an Cookie object. Although deprecated, it
63 is still supported by the code. See the Backward Compatibility notes
64 for more information.]
66 Once you've created your Cookie, you can add values just as if it were
69 >>> C = Cookie.SmartCookie()
70 >>> C["fig"] = "newton"
71 >>> C["sugar"] = "wafer"
73 Set-Cookie: fig=newton;
74 Set-Cookie: sugar=wafer;
76 Notice that the printable representation of a Cookie is the
77 appropriate format for a Set-Cookie: header. This is the
78 default behavior. You can change the header and printed
79 attributes by using the the .output() function
81 >>> C = Cookie.SmartCookie()
82 >>> C["rocky"] = "road"
83 >>> C["rocky"]["path"] = "/cookie"
84 >>> print C.output(header="Cookie:")
85 Cookie: rocky=road; Path=/cookie;
86 >>> print C.output(attrs=[], header="Cookie:")
89 The load() method of a Cookie extracts cookies from a string. In a
90 CGI script, you would use this method to extract the cookies from the
91 HTTP_COOKIE environment variable.
93 >>> C = Cookie.SmartCookie()
94 >>> C.load("chips=ahoy; vienna=finger")
96 Set-Cookie: chips=ahoy;
97 Set-Cookie: vienna=finger;
99 The load() method is darn-tootin smart about identifying cookies
100 within a string. Escaped quotation marks, nested semicolons, and other
101 such trickeries do not confuse it.
103 >>> C = Cookie.SmartCookie()
104 >>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=\\012;";')
106 Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=\012;";
108 Each element of the Cookie also supports all of the RFC 2109
109 Cookie attributes. Here's an example which sets the Path
112 >>> C = Cookie.SmartCookie()
113 >>> C["oreo"] = "doublestuff"
114 >>> C["oreo"]["path"] = "/"
116 Set-Cookie: oreo=doublestuff; Path=/;
118 Each dictionary element has a 'value' attribute, which gives you
119 back the value associated with the key.
121 >>> C = Cookie.SmartCookie()
122 >>> C["twix"] = "none for you"
130 As mentioned before, there are three different flavors of Cookie
131 objects, each with different encoding/decoding semantics. This
132 section briefly discusses the differences.
136 The SimpleCookie expects that all values should be standard strings.
137 Just to be sure, SimpleCookie invokes the str() builtin to convert
138 the value to a string, when the values are set dictionary-style.
140 >>> C = Cookie.SimpleCookie()
142 >>> C["string"] = "seven"
143 >>> C["number"].value
145 >>> C["string"].value
148 Set-Cookie: number=7;
149 Set-Cookie: string=seven;
154 The SerialCookie expects that all values should be serialized using
155 cPickle (or pickle, if cPickle isn't available). As a result of
156 serializing, SerialCookie can save almost any Python object to a
157 value, and recover the exact same object when the cookie has been
158 returned. (SerialCookie can yield some strange-looking cookie
161 >>> C = Cookie.SerialCookie()
163 >>> C["string"] = "seven"
164 >>> C["number"].value
166 >>> C["string"].value
169 Set-Cookie: number="I7\012.";
170 Set-Cookie: string="S'seven'\012p1\012.";
172 Be warned, however, if SerialCookie cannot de-serialize a value (because
173 it isn't a valid pickle'd object), IT WILL RAISE AN EXCEPTION.
178 The SmartCookie combines aspects of each of the other two flavors.
179 When setting a value in a dictionary-fashion, the SmartCookie will
180 serialize (ala cPickle) the value *if and only if* it isn't a
181 Python string. String objects are *not* serialized. Similarly,
182 when the load() method parses out values, it attempts to de-serialize
183 the value. If it fails, then it fallsback to treating the value
186 >>> C = Cookie.SmartCookie()
188 >>> C["string"] = "seven"
189 >>> C["number"].value
191 >>> C["string"].value
194 Set-Cookie: number="I7\012.";
195 Set-Cookie: string=seven;
198 Backwards Compatibility
199 -----------------------
201 In order to keep compatibilty with earlier versions of Cookie.py,
202 it is still possible to use Cookie.Cookie() to create a Cookie. In
203 fact, this simply returns a SmartCookie.
205 >>> C = Cookie.Cookie()
206 >>> print C.__class__.__name__
219 from UserDict
import UserDict
222 from cPickle
import dumps, loads
224 from pickle
import dumps, loads
229 raise ImportError,
"Cookie.py requires 're' from Python 1.5 or later"
231 __all__ = [
"CookieError",
"BaseCookie",
"SimpleCookie",
"SerialCookie",
232 "SmartCookie",
"Cookie"]
252 _LegalChars = string.ascii_letters + string.digits +
"!#$%&'*+-.^_`|~"
254 '\000' :
'\\000',
'\001' :
'\\001',
'\002' :
'\\002',
255 '\003' :
'\\003',
'\004' :
'\\004',
'\005' :
'\\005',
256 '\006' :
'\\006',
'\007' :
'\\007',
'\010' :
'\\010',
257 '\011' :
'\\011',
'\012' :
'\\012',
'\013' :
'\\013',
258 '\014' :
'\\014',
'\015' :
'\\015',
'\016' :
'\\016',
259 '\017' :
'\\017',
'\020' :
'\\020',
'\021' :
'\\021',
260 '\022' :
'\\022',
'\023' :
'\\023',
'\024' :
'\\024',
261 '\025' :
'\\025',
'\026' :
'\\026',
'\027' :
'\\027',
262 '\030' :
'\\030',
'\031' :
'\\031',
'\032' :
'\\032',
263 '\033' :
'\\033',
'\034' :
'\\034',
'\035' :
'\\035',
264 '\036' :
'\\036',
'\037' :
'\\037',
266 '"' :
'\\"',
'\\' :
'\\\\',
268 '\177' :
'\\177',
'\200' :
'\\200',
'\201' :
'\\201',
269 '\202' :
'\\202',
'\203' :
'\\203',
'\204' :
'\\204',
270 '\205' :
'\\205',
'\206' :
'\\206',
'\207' :
'\\207',
271 '\210' :
'\\210',
'\211' :
'\\211',
'\212' :
'\\212',
272 '\213' :
'\\213',
'\214' :
'\\214',
'\215' :
'\\215',
273 '\216' :
'\\216',
'\217' :
'\\217',
'\220' :
'\\220',
274 '\221' :
'\\221',
'\222' :
'\\222',
'\223' :
'\\223',
275 '\224' :
'\\224',
'\225' :
'\\225',
'\226' :
'\\226',
276 '\227' :
'\\227',
'\230' :
'\\230',
'\231' :
'\\231',
277 '\232' :
'\\232',
'\233' :
'\\233',
'\234' :
'\\234',
278 '\235' :
'\\235',
'\236' :
'\\236',
'\237' :
'\\237',
279 '\240' :
'\\240',
'\241' :
'\\241',
'\242' :
'\\242',
280 '\243' :
'\\243',
'\244' :
'\\244',
'\245' :
'\\245',
281 '\246' :
'\\246',
'\247' :
'\\247',
'\250' :
'\\250',
282 '\251' :
'\\251',
'\252' :
'\\252',
'\253' :
'\\253',
283 '\254' :
'\\254',
'\255' :
'\\255',
'\256' :
'\\256',
284 '\257' :
'\\257',
'\260' :
'\\260',
'\261' :
'\\261',
285 '\262' :
'\\262',
'\263' :
'\\263',
'\264' :
'\\264',
286 '\265' :
'\\265',
'\266' :
'\\266',
'\267' :
'\\267',
287 '\270' :
'\\270',
'\271' :
'\\271',
'\272' :
'\\272',
288 '\273' :
'\\273',
'\274' :
'\\274',
'\275' :
'\\275',
289 '\276' :
'\\276',
'\277' :
'\\277',
'\300' :
'\\300',
290 '\301' :
'\\301',
'\302' :
'\\302',
'\303' :
'\\303',
291 '\304' :
'\\304',
'\305' :
'\\305',
'\306' :
'\\306',
292 '\307' :
'\\307',
'\310' :
'\\310',
'\311' :
'\\311',
293 '\312' :
'\\312',
'\313' :
'\\313',
'\314' :
'\\314',
294 '\315' :
'\\315',
'\316' :
'\\316',
'\317' :
'\\317',
295 '\320' :
'\\320',
'\321' :
'\\321',
'\322' :
'\\322',
296 '\323' :
'\\323',
'\324' :
'\\324',
'\325' :
'\\325',
297 '\326' :
'\\326',
'\327' :
'\\327',
'\330' :
'\\330',
298 '\331' :
'\\331',
'\332' :
'\\332',
'\333' :
'\\333',
299 '\334' :
'\\334',
'\335' :
'\\335',
'\336' :
'\\336',
300 '\337' :
'\\337',
'\340' :
'\\340',
'\341' :
'\\341',
301 '\342' :
'\\342',
'\343' :
'\\343',
'\344' :
'\\344',
302 '\345' :
'\\345',
'\346' :
'\\346',
'\347' :
'\\347',
303 '\350' :
'\\350',
'\351' :
'\\351',
'\352' :
'\\352',
304 '\353' :
'\\353',
'\354' :
'\\354',
'\355' :
'\\355',
305 '\356' :
'\\356',
'\357' :
'\\357',
'\360' :
'\\360',
306 '\361' :
'\\361',
'\362' :
'\\362',
'\363' :
'\\363',
307 '\364' :
'\\364',
'\365' :
'\\365',
'\366' :
'\\366',
308 '\367' :
'\\367',
'\370' :
'\\370',
'\371' :
'\\371',
309 '\372' :
'\\372',
'\373' :
'\\373',
'\374' :
'\\374',
310 '\375' :
'\\375',
'\376' :
'\\376',
'\377' :
'\\377'
313 def _quote(str, LegalChars=_LegalChars,
314 join=string.join, idmap=string._idmap, translate=string.translate):
321 if "" ==
translate(str, idmap, LegalChars):
324 return '"' +
join( map(_Translator.get, str, str),
"" ) +
'"'
328 _OctalPatt = re.compile(
r"\\[0-3][0-7][0-7]")
329 _QuotePatt = re.compile(
r"[\\].")
331 def _unquote(str, join=string.join, atoi=string.atoi):
336 if str[0] !=
'"' or str[-1] !=
'"':
353 Omatch = _OctalPatt.search(str, i)
354 Qmatch = _QuotePatt.search(str, i)
355 if not Omatch
and not Qmatch:
360 if Omatch: j = Omatch.start(0)
361 if Qmatch: k = Qmatch.start(0)
362 if Qmatch
and (
not Omatch
or k < j ):
368 res.append( chr(
atoi(str[j+1:j+4], 8) ) )
381 _weekdayname = [
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat',
'Sun']
384 'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
385 'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec']
387 def _getdate(future=0, weekdayname=_weekdayname, monthname=_monthname):
388 from time
import gmtime, time
390 year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future)
391 return "%s, %02d-%3s-%4d %02d:%02d:%02d GMT" % \
392 (weekdayname[wd], day, monthname[month], year, hh, mm, ss)
417 _reserved = {
"expires" :
"expires",
419 "comment" :
"Comment",
421 "max-age" :
"Max-Age",
423 "version" :
"Version",
425 _reserved_keys = _reserved.keys()
430 UserDict.__init__(self)
434 UserDict.__setitem__(self, K,
"")
441 UserDict.__setitem__(self, K, V)
448 def set(self, key, val, coded_val,
449 LegalChars=_LegalChars,
450 idmap=string._idmap, translate=string.translate ):
454 raise CookieError(
"Attempt to set a reserved key: %s" % key)
455 if "" !=
translate(key, idmap, LegalChars):
464 def output(self, attrs=None, header = "Set-Cookie:
"):
470 return '<%s: %s=%s>' % (self.__class__.__name__,
476 <SCRIPT LANGUAGE="JavaScript">
478 document.cookie = \"%s\"
500 if K
not in attrs:
continue
501 if K ==
"expires" and type(V) == type(1):
502 RA(
"%s=%s;" % (self.
_reserved[K], _getdate(V)))
503 elif K ==
"max-age" and type(V) == type(1):
526 _LegalCharsPatt =
r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=]"
527 _CookiePattern = re.compile(
530 ""+ _LegalCharsPatt +
"+?"
536 ""+ _LegalCharsPatt +
"*"
550 def value_decode(self, val):
551 """real_value, coded_value = value_decode(STRING)
552 Called prior to setting a cookie's value from the network
553 representation. The VALUE is the value read from HTTP
555 Override this function to modify the behavior of cookies.
560 def value_encode(self, val):
561 """real_value, coded_value = value_encode(VALUE)
562 Called prior to setting a cookie's value from the dictionary
563 representation. The VALUE is the value being assigned.
564 Override this function to modify the behavior of cookies.
567 return strval, strval
571 UserDict.__init__(self)
572 if input: self.load(input)
575 def __set(self, key, real_value, coded_value):
576 """Private method for setting a cookie's value"""
577 M = self.get(key,
Morsel())
578 M.set(key, real_value, coded_value)
579 UserDict.__setitem__(self, key, M)
583 """Dictionary style assignment."""
584 rval, cval = self.value_encode(value)
585 self.__set(key, rval, cval)
588 def output(self, attrs=None, header="Set-Cookie:
", sep="\n
"):
589 """Return a string suitable for HTTP."""
594 result.append( V.output(attrs, header) )
605 L.append(
'%s=%s' % (K,
repr(V.value) ) )
606 return '<%s: %s>' % (self.__class__.__name__,
string.join(L))
608 def js_output(self, attrs=None):
609 """Return a string suitable for JavaScript."""
614 result.append( V.js_output(attrs) )
618 def load(self, rawdata):
619 """Load cookies from a string (presumably HTTP_COOKIE) or
620 from a dictionary. Loading cookies from a dictionary 'd'
621 is equivalent to calling:
622 map(Cookie.__setitem__, d.keys(), d.values())
624 if type(rawdata) == type(
""):
625 self.__ParseString(rawdata)
631 def __ParseString(self, str, patt=_CookiePattern):
638 match = patt.search(str, i)
641 K,V = match.group(
"key"), match.group(
"val")
655 rval, cval = self.value_decode(V)
656 self.__set(K, rval, cval)
663 SimpleCookie supports strings as cookie values. When setting
664 the value using the dictionary assignment notation, SimpleCookie
665 calls the builtin str() to convert the value to a string. Values
666 received from HTTP are kept as strings.
669 return _unquote( val ), val
672 return strval, _quote( strval )
677 SerialCookie supports arbitrary objects as cookie values. All
678 values are serialized (using cPickle) before being sent to the
679 client. All incoming values are assumed to be valid Pickle
680 representations. IF AN INCOMING VALUE IS NOT IN A VALID PICKLE
681 FORMAT, THEN AN EXCEPTION WILL BE RAISED.
683 Note: Large cookie values add overhead because they must be
684 retransmitted on every HTTP transaction.
686 Note: HTTP has a 2k limit on the size of a cookie. This class
687 does not check for this limit, so be careful!!!
691 return loads( _unquote(val) ), val
693 return val, _quote(
dumps(val) )
698 SmartCookie supports arbitrary objects as cookie values. If the
699 object is a string, then it is quoted. If the object is not a
700 string, however, then SmartCookie will use cPickle to serialize
701 the object into a string representation.
703 Note: Large cookie values add overhead because they must be
704 retransmitted on every HTTP transaction.
706 Note: HTTP has a 2k limit on the size of a cookie. This class
707 does not check for this limit, so be careful!!!
710 strval = _unquote(val)
712 return loads(strval), val
716 if type(val) == type(
""):
717 return val, _quote(val)
719 return val, _quote(
dumps(val) )
733 import doctest, Cookie
736 if __name__ ==
"__main__":