I think this script should now be functional enough to post here at ActiveState. When you reply or vote down, please post some information on your problem with the code, and if you can, maybe something about the solution. This interface works, and is designed especially for Python. If you like it, don't be afraid to post that either, constructive criticism is all good, but compliments are even better! ;)
Get the latest version of this code here: http://wiki.sunjay.ca/Python:Contents/Python_Session
Latest Changes:
- Added a new function for making the session cookie last longer. See code for set_expires. Note: This new function is just in case you need to include a session for longer than one brower session (for example, one day instead).
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 | #!/usr/local/bin/python26
"""
Python Session Handling
Note: A user must have cookies enabled!
TODO:
* Support Named Sessions
Copyright 2010 - Sunjay Varma
Latest Version: http://www.sunjay.ca/download/session.py
"""
import cgi
import os
import time
import errno
import hashlib
import datetime
from Cookie import SimpleCookie
from cPickle import dump, load, HIGHEST_PROTOCOL, dumps, loads
if not "HTTP_COOKIE" in os.environ:
	os.environ["HTTP_COOKIE"] = ""
SESSION = None
S_DIR = os.path.expanduser("~/.py_sessions") # expanduser for windows users
S_EXT = ".ps"
S_ID = "__sid__"
TODAY = str(datetime.date.today())
DEBUG = [] # debug messages
if not os.path.exists(S_DIR):
	os.makedirs(S_DIR)
class NoCookiesError(Exception): pass
class NotStarted(Exception): pass
class Session(object):
	def __init__(self):
		self.data = {}
		self.started = False
		self._flock = None
		self.expires = 0 # delete right away
		
		self.__sid = sid = self.__getsid()
		self.path = os.path.join(S_DIR, sid+S_EXT)
	def isset(self, name):
		"""Is the variable set in the session?"""
		if not self.started:
			raise NotStarted("Session must be started")
		return name in self
	def unset(self, name):
		"""Unset the name from the session"""
		if not self.started:
			raise NotStarted("Session must be started")
		del self[name]
	@staticmethod
	def __newsid():
		"""Create a new session ID"""
		h = hashlib.new("ripemd160")
		h.update(str(time.time()/time.clock()**-1)+str(os.getpid()))
		return h.hexdigest()
	def __getsid(self):
		"""Get the current session ID or return a new one"""
		# first, try to load the sid from the GET or POST forms
		form = cgi.FieldStorage()
		if form.has_key(S_ID):
			sid = form[S_ID].value
			return sid
		# then try to load the sid from the HTTP cookie
		self.cookie = SimpleCookie()
		if os.environ.has_key('HTTP_COOKIE'):
			self.cookie.load(os.environ['HTTP_COOKIE'])
			if S_ID in self.cookie:
				sid = self.cookie[S_ID].value
				return sid
		else:
			raise NoCookiesError("Could not find any cookies")
		# if all else fails, return a new sid
		return self.__newsid()
	def getsid(self):
		"""
		Return the name and value that the sid needs to have in a GET or POST
		request
		"""
		if not self.started:
			raise NotStarted("Session must be started")
		return (S_ID, self.__sid)
	def start(self):
		"""Start the session"""
		if self.started:
			return True # session cannot be started more than once per script
		self._flock = FileLock(self.path)
		self._flock.acquire()
		# load the session if it exists
		if os.path.exists(self.path):
			with open(self.path, "rb") as f:
				self.data = dict(load(f))
				self.data["__date_loaded__"] = TODAY
		else: # create a session
			with open(self.path, "wb") as f:
				self.data = {"__date_loaded__":TODAY}
		# the session is officially started!
		self.started = True
		# store the sid in the cookie
		self.cookie[S_ID] = self.__sid
		self.cookie[S_ID]["expires"] = str(self.expires)
		self.cookie[S_ID]["version"] = "1"
		return True
	def commit(self):
		"""Commit the changes to the session"""
		if not self.started:
			raise NotStarted("Session must be started")
		with open(self.path, "wb") as f:
			dump(self.data, f, HIGHEST_PROTOCOL)
	def destroy(self):
		"""Destroy the session"""
		if not self.started:
			raise NotStarted("Session must be started")
		os.delete(self.path)
		if self._flock:
			self._flock.release()
		self.started = False
	def output(self):
		"""Commit changes and send headers."""
		if not self.started:
			raise NotStarted("Session must be started")
		self.commit()
		return self.cookie.output()
	def setdefault(self, item, default=None):
		if not self.started:
			raise NotStarted("Session must be started")
		if not self.isset(item):
			self[item] = default
		return self[item]
		
	def set_expires(self, days):
		"""Sets the expiration of the cookie"""
		date = datetime.date.today() + datetime.timedelta(days=days)
		self.expires = date.strftime("%a, %d-%b-%Y %H:%M:%S PST")
		self.cookie[S_ID]["expires"] = str(self.expires)
	def __getitem__(self, item):
		"""Get the item from the session"""
		if not self.started:
			raise NotStarted("Session must be started")
		return self.data.__getitem__(item)
	def __setitem__(self, item, value):
		"""set the item into the session"""
		if not self.started:
			raise NotStarted("Session must be started")
		self.data.__setitem__(item, value)
	def __delitem__(self, item):
		if not self.started:
			raise NotStarted("Session must be started")
		self.data.__delitem__(item)
	def __contains__(self, item):
		"""Return if item in the session"""
		if not self.started:
			raise NotStarted("Session must be started")
		return self.data.__contains__(item)
	def __iter__(self):
		"""Go through the names of all the session variables"""
		if not self.started:
			raise NotStarted("Session must be started")
		return self.data.__iter__()
def start():
	global SESSION
	SESSION = Session()
	return SESSION.start()
def destroy():
	global SESSION
	if SESSION:
		SESSION.destroy()
def get_session():
	global SESSION
	if not SESSION:
		SESSION = Session()
	return SESSION
### The following is a (little) modified version of this:
# http://www.evanfosmark.com/2009/01/cross-platform-file-locking-support-in-
# python/
class FileLockException(Exception):
	pass
class FileLock(object):
	""" A file locking mechanism that has context-manager support so
		you can use it in a with statement. This should be relatively cross
		compatible as it doesn't rely on msvcrt or fcntl for the locking.
	"""
	def __init__(self, file_name, timeout=10, delay=.05):
		""" Prepare the file locker. Specify the file to lock and optionally
			the maximum timeout and the delay between each attempt to lock.
		"""
		self.is_locked = False
		self.lockfile = os.path.join(os.getcwd(), "%s.lock" % file_name)
		self.file_name = file_name
		self.timeout = timeout
		self.delay = delay
	def acquire(self):
		""" Acquire the lock, if possible. If the lock is in use, it check again
			every `wait` seconds. It does this until it either gets the lock or
			exceeds `timeout` number of seconds, in which case it throws
			an exception.
		"""
		if self.is_locked:
			return
		start_time = time.time()
		while True:
			try:
				self.fd = os.open(self.lockfile, os.O_CREAT|os.O_EXCL|os.O_RDWR)
				break;
			except OSError as e:
				if e.errno != errno.EEXIST:
					raise
				if (time.time() - start_time) >= self.timeout:
					raise FileLockException("Timeout occured.")
				time.sleep(self.delay)
		self.is_locked = True
	def release(self):
		""" Get rid of the lock by deleting the lockfile.
			When working in a `with` statement, this gets automatically
			called at the end.
		"""
		if self.is_locked:
			os.close(self.fd)
			os.unlink(self.lockfile)
			self.is_locked = False
	def __enter__(self):
		""" Activated when used in the with statement.
			Should automatically acquire a lock to be used in the with block.
		"""
		if not self.is_locked:
			self.acquire()
		return self
	def __exit__(self, type, value, traceback):
		""" Activated at the end of the with statement.
			It automatically releases the lock if it isn't locked.
		"""
		if self.is_locked:
			self.release()
	def __del__(self):
		""" Make sure that the FileLock instance doesn't leave a lockfile
			lying around.
		"""
		self.release()
def print_session(session):
	"""
	Prints info from the current session.
	WARNING: ONLY FOR DEBUGGING. MAJOR SECURITY RISK!
	"""
	print "<h3>Session Data</h3>"
	print "<dl>"
	for name in session:
		print "<dt>%s <i>%s</i></dt>"%(name, type(session[name]))
		print "<dd>%s</dd>"%repr(session[name])
	print "</dl>"
def main():
	"""Tester Program"""
	start() # session.start()
	if SESSION.isset("views"):
		SESSION["views"] += 1
	else:
		SESSION["views"] = 1
	print "Content-type: text/html"
	print SESSION.output()
	print
	print "<html><head><title>Session Testing</title></head><body>"
	print "<h2>You have viewed this page %i times.</h2>"%SESSION["views"]
	print_session(SESSION)
	print "<p>", SESSION.path, "</p>"
	for line in DEBUG:
		print "<p>%s</p>"%line
	print "<p>%s</p>"%SESSION.data
	print "</body></html>"
if __name__ == "__main__":
	main()
 | 
There can be some security leaks, but depending on your server, and other things, it should work quite well.
If the client does not have cookies enabled, you may need to pass some query parameters in every single time, or keep track of the session id some other way.
You can get the session id through the getsid method of the session object.
I tried to imitate the PHP session interface as much as possible, although I did add some Python specialties as well.
The setdefault method, was an idea that I stole from Python's dict object. 
Of course, with my lack of PHP knowledge, I cannot say that I completely copied the Session interface. There may be things that I missed. Still consider this though, I was only going for basing this on PHP (even though I may sometimes say otherwise) this is not meant to copy the interface, only give some way into managing it through Python.
For an example on how to use this, go to http://wiki.sunjay.ca/Python:Contents/Python_Session#Examples

 Download
Download Copy to clipboard
Copy to clipboard

Good but IE not run :)
how can i make it work in IE
Hi I have been trying to download an image from website (no username and password required) but every time I am getting an empty file. I have used conventional urllib .retrieve and requests methodologies but getting the same result. One thing more is that if I try to open the same image manually by copy pasting the URL after 15-20 min then that image itself does not open. I am assuming that some sort of session handling is required in this case . Below is my code which returns me empty image.
def savePic(url): uri="C:\Python27\Scripts\Photosurl2.jpg" if url!="": urllib.urlretrieve(url, uri)
savePic("http://www-nass.nhtsa.dot.gov/nass/cds/GetBinary.aspx?ImageView&ImageID=491410290&Desc=Lookback+from+final+rest&Title=Scene+Photos+-+image1&Version=1&Extend=jpg")
Any help is appreciated.