Iain Samuel McLean Elder
Iain Samuel McLean Elder

Reputation: 20924

How to inject URL query string parameters in Python?

I want to compose an equivalent debug URL for any URL of my organization's website. I have Python function to do this:

import urlparse
import urllib

def compose_debug_url(input_url):
    input_url_parts = urlparse.urlsplit(input_url)
    input_query = input_url_parts.query
    input_query_dict = urlparse.parse_qs(input_query)

    modified_query_dict = dict(input_query_dict.items() + [('debug', 'sp')])
    modified_query = urllib.urlencode(modified_query_dict)
    modified_url_parts = (
      input_url_parts.scheme,
      input_url_parts.netloc,
      input_url_parts.path,
      modified_query,
      input_url_parts.fragment
    )

    modified_url = urlparse.urlunsplit(modified_url_parts)

    return modified_url



print compose_debug_url('http://www.example.com/content/page?name=john&age=35')
print compose_debug_url('http://www.example.com/')

If you run the code above, you should see the output:

http://www.example.com/content/page?debug=sp&age=%5B%2735%27%5D&name=%5B%27john%27%5D
http://www.example.com/?debug=sp

Instead I expect:

http://www.example.com/content/page?debug=sp&age=35&name=john
http://www.example.com/?debug=sp

It's because urlparse.parse_qs returns a dict of strings to lists rather than a dict of strings to strings.

Is there another way to do this in Python more simply?

Upvotes: 1

Views: 3721

Answers (2)

xiaq
xiaq

Reputation: 804

Late answer, but urlencode takes a doseq parameter which can be used to flatten the list.

Upvotes: 1

vartec
vartec

Reputation: 134581

urlparse.parse_qs returns a list of values for each key. In your example it's {'age': ['35'], 'name': ['john']}, while what you want is {'age': '35', 'name': 'john'}.

Since you're using key, value pars as a list, use urlparse.parse_qsl

modified_query_dict = dict(urlparse.parse_qsl(input_query) + [('debug', 'sp')])

Upvotes: 1

Related Questions