Friday, January 06, 2006

urlencoder/decoder for python

EDIT (I so stand corrected.):

I could have just used:
urllib.quote
urllib.unquote

---------------------------------------------------

Every once and a while I run into the need for a urlencoder/decoder function that just accepts a string and returns a string.

The one that comes w/ urllib(2) takes a dictionary and returns a "name=val" formatted string.
My only problem is that it does 2 things at once:
1) url encodes.
2) constructs a query or post string.

So I wrote a quick utility to do just #1:


_keys = [
"$", "&", "+", ",", "/", ":", ";", "=", "?", "@", " ", '"',
"<", ">", "#", "%", "{", "}", "|", "\\", "^", "~", "[", "]", "`"]

_vals = [
'%24', '%26', '%2B', '%2C', '%2F', '%3A', '%3B', '%3D', '%3F',
'%40', '%20', '%22', '%3C', '%3E', '%23', '%25', '%7B', '%7D',
'%7C', '%5C', '%5E', '%7E', '%5B', '%5D', '%60']

def encode(str=""):
""" URL Encodes a string with out side effects
"""
return "".join([_swap(x) for x in str])

def decode(str=""):
""" Takes a URL encoded string and decodes it with out side effects
"""
if not str: return None
for v in _vals:
if v in str: str = str.replace(v, _keys[_vals.index(v)])
return str

def _swap(x):
""" Helper function for encode.
"""
if x in _keys: return _vals[_keys.index(x)]
return x

### units ###
if __name__ == "__main__":
assert("".join(_keys) == decode(encode("".join(_keys))))
assert("".join(_vals) == encode(decode("".join(_vals))))
print "passed all unit tests."

5 comments:

Anonymous said...

urllib.quote
urllib.unquote

?

cludwin said...

Good catch.
I totally missed that on thanks.
Courntey

Anonymous said...

thanks a lot!

Richrd said...

Yeah, you could have used urllib.quote BUT for some reason it (and urllib2.urlencode) doesn't work properly with characters like "ä" or "ö".

For instance, javascripts escape("ä") returns %E4 and so does urlencode in php.
Python returns %84 with both functions.

I need special characters encoded properly. I'm trying to get it to work somehow.

Unknown said...

thanks, i'll use it on my google app engine application

cheers