Package: rfc3986
A Python implementation ofRFC 3986including validation and authority
parsing.InstallationUse pip to installrfc3986like so:pip install rfc3986LicenseApache License Version 2.0Example UsageThe following are the two most common use cases envisioned forrfc3986.ReplacingurlparseTo parse a URI and receive something very similar to the standard library’surllib.parse.urlparsefromrfc3986importurlparsessh=urlparse('ssh://user@git.openstack.org:29418/openstack/glance.git')print(ssh.scheme)# => sshprint(ssh.userinfo)# => userprint(ssh.params)# => Noneprint(ssh.port)# => 29418To create a copy of it with new pieces you can usecopy_with:new_ssh=ssh.copy_with(scheme='https'userinfo='',port=443,path='/openstack/glance')print(new_ssh.scheme)# => httpsprint(new_ssh.userinfo)# => None# etc.Strictly Parsing a URI and Applying ValidationTo parse a URI into a convenient named tuple, you can simply:fromrfc3986importuri_referenceexample=uri_reference('http://example.com')email=uri_reference('mailto:user@domain.com')ssh=uri_reference('ssh://user@git.openstack.org:29418/openstack/keystone.git')With a parsed URI you can access data about the components:print(example.scheme)# => httpprint(email.path)# => user@domain.comprint(ssh.userinfo)# => userprint(ssh.host)# => git.openstack.orgprint(ssh.port)# => 29418It can also parse URIs with unicode present:uni=uri_reference(b'http://httpbin.org/get?utf8=\xe2\x98\x83')# ☃print(uni.query)# utf8=%E2%98%83With a parsed URI you can also validate it:ifssh.is_valid():subprocess.call(['git','clone',ssh.unsplit()])You can also take a parsed URI and normalize it:mangled=uri_reference('hTTp://exAMPLe.COM')print(mangled.scheme)# => hTTpprint(mangled.authority)# => exAMPLe.COMnormal=mangled.normalize()print(normal.scheme)# => httpprint(mangled.authority)# => example.comBut these two URIs are (functionally) equivalent:ifnormal==mangled:webbrowser.open(normal.unsplit())Your paths, queries, and fragments are safe with us though:mangled=uri_reference('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')normal=mangled.normalize()assertnormal=='hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth'assertnormal=='http://example.com/Some/reallY/biZZare/pAth'assertnormal!='http://example.com/some/really/bizzare/path'If you do not actually need a real reference object and just want to normalize
your URI:fromrfc3986importnormalize_uriassert(normalize_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')=='http://example.com/Some/reallY/biZZare/pAth')You can also very simply validate a URI:fromrfc3986importis_valid_uriassertis_valid_uri('hTTp://exAMPLe.COM/Some/reallY/biZZare/pAth')Requiring ComponentsYou can validate that a particular string is a valid URI and require
independent components:fromrfc3986importis_valid_uriassertis_valid_uri('http://localhost:8774/v2/resource',require_scheme=True,require_authority=True,require_path=True)# Assert that a mailto URI is invalid if you require an authority# componentassertis_valid_uri('mailto:user@example.com',require_authority=True)isFalseIf you have an instance of aURIReference, you can pass the same arguments
toURIReference#is_valid, e.g.,fromrfc3986importuri_referencehttp=uri_reference('http://localhost:8774/v2/resource')asserturi.is_valid(require_scheme=True,require_authority=True,require_path=True)# Assert that a mailto URI is invalid if you require an authority# componentmailto=uri_reference('mailto:user@example.com')asserturi.is_valid(require_authority=True)isFalseAlternativesrfc3987This is a direct competitor to this library, with extra features,
licensed under the GPL.uritoolsThis can parse URIs in the manner of RFC 3986 but provides no validation and
only recently added Python 3 support.Standard library’surlparse/urllib.parseThe functions in these libraries can only split a URI (valid or not) and
provide no validation.ContributingThis project follows and enforces the Python Software Foundation’sCode of
Conduct.If you would like to contribute but do not have a bug or feature in mind, feel
free to email Ian and find out how you can help.The git repository for this project is maintained athttps://github.com/python-hyper/rfc3986