I have to construct a URL string from smaller substrings. I'll usually have a resource url
, an endpoint
, a query
, but you can imagine even more parts in creating a full URL.
If, for example, I have this resource URL: http://foo.com
, this endpoint: bar/v1
, and this query: q?var1=33,var2='abc'
, I expect the final URL to be:
http://foo.com/bar/v1/q?var1=33,var2='abc'
If the strings are formatted following a simple convention (for example, only have leading slashes on a substring) I could simply concatenate them together. The problem however is that these strings will be given as arguments to some library function calls, and hence it is very probable that some library users will miss the convention. It's so easy to add a trailing '/' or omit a leading '/'. So I do not want to impose a convention on this. Instead, I prefer to check and sanitise the arguments. I thought that urllib.parse.urljoin()
would serve my purpose, but it does not. So I wrote a simple little method:
def slash_join(*args):
'''
Joins a set of strings with a slash (/) between them. Useful for creating URLs.
If the strings already have a trailing or leading slash, it is ignored.
Note that the python's urllib.parse.urljoin() does not offer this functionality.
'''
stripped_strings = []
# strip any leading or trailing slashes
for a in args:
if a[0] == '/': start = 1
else: start = 0
if a[-1] =='/':
stripped_strings.append(a[start:-1])
else:
stripped_strings.append(a[start:])
return '/'.join(stripped_strings)
Usage
>>> slash_join('http://foo.bar/', '/path/', '/query')
>>> 'http://foo.bar/path/query'
>>> slash_join('http://foo.bar', 'path', 'query')
>>> 'http://foo.bar/path/query'
>>> slash_join('http://foo.bar', 'path/', 'query/')
>>> 'http://foo.bar/path/query'
It works fine, but I was wondering if there is a more pythonic way of expressing this, or if I indeed missed a standard library method call that could have helped me.