Python's standard urllib and urlparse modules provide a number of URL manipulation functions, but using these functions to perform common URL manipulations proves tedious. Furl makes manipulating URLs easy.
Furl is well tested, Unlicensed in the public domain, and supports both Python 2 and 3.
Query arguments are easy. Really easy.
>>> from furl import furl
>>> f = furl('http://www.google.com/?one=1&two=2')
>>> f.args['three'] = '3'
>>> del f.args['one']
>>> f.url
'http://www.google.com/?two=2&three=3'
Or use furl's inline modification methods.
>>> furl('http://www.google.com/?one=1').add({'two':'2'}).url
'http://www.google.com/?one=1&two=2'
>>> furl('http://www.google.com/?one=1&two=2').set({'three':'3'}).url
'http://www.google.com/?three=3'
>>> furl('http://www.google.com/?one=1&two=2').remove(['one']).url
'http://www.google.com/?two=2'
Encoding is handled for you. Unicode, too.
>>> f = furl('http://www.google.com/')
>>> f.path = 'some encoding here'
>>> f.args['and some encoding'] = 'here, too'
>>> f.url
'http://www.google.com/some%20encoding%20here?and+some+encoding=here,+too'
>>> f.set(host=u'ドメイン.テスト', path=u'джк', query=u'☃=☺')
>>> f.url
'http://xn--eckwd4c7c.xn--zckzah/%D0%B4%D0%B6%D0%BA?%E2%98%83=%E2%98%BA'
Fragments also have a path and a query.
>>> f = furl('http://www.google.com/')
>>> f.fragment.path.segments = ['two', 'directories']
>>> f.fragment.args = {'one':'argument'}
>>> f.url
'http://www.google.com/#two/directories?one=argument'
Or get fancy.
>>> f = furl('http://www.google.com/search?q=query#1')
>>> f.copy().remove(path=True).set(host='taco.com')
... .join('/pumps.html').add(fragment_path='party').url
'http://taco.com/pumps.html#party'
See more furl magic and examples in furl's API document, API.md.
Installing furl with pip is easy.
$ pip install furl