How do I encode this dictionary of URL parameters into a valid string?

Viewed 1818

I've got a Python dictionary params that looks like this:

{
    "request": {
        "metadataOnly":False,
        "latitude": 80.12345,
        "treatmentFlags":[
            "simple_search_1_1",
            "simple_search_desktop_v3_full_bleed",
            "flexible_dates_options_extend_one_three_seven_days"
        ]
    }
}

I want params converted into this string:

%7B%22request%22%3A%7B%22metadataOnly%22%3A%22false%22%2C%22latitude%22%3A%2280.12345%22%2C%22treatmentFlags%22%3A%5B%22simple_search_1_1%22%2C%22simple_search_desktop_v3_full_bleed%22%2C%22flexible_dates_options_extend_one_three_seven_days%22%5D%7D%7D

Because that string works in the URL I'm querying. That string, when decoded using Advanced REST Client, looks like this:

{"request":{"metadataOnly":"false","latitude":"80.12345","treatmentFlags":["simple_search_1_1","simple_search_desktop_v3_full_bleed","flexible_dates_options_extend_one_three_seven_days"]}}

How do I convert params, or any such Python dictionary, into a valid string like I described?

2 Answers

What you are trying to achieve is a combination of two encoding techniques:

  • JSON encoding (to convert the dictionary into a string)
  • URL encoding (to encode the string to make it safe to use in a URL query string)

In this answer, I've included two Python examples, broken down step by step, plus a Tl;Dr minimal encode+decode example for those who don't need/want a full explanation of how this works.

The first shows how to convert a dict/list into a URL encoded JSON string as per your desired end result string in the question, and the second example shows how to reverse the process - converting a URL encoded JSON string back into the original JSON string, and then converting that back into it's original dict object.

TL;DR; full code with bare minimum explanation

Scroll down for the breakdown with full step-by-step explanation. This code block is the TL;DR; example - covering encoding into a URL string, and back into a dict, with minimal comments and space-saving formatting.

import urllib.parse
import json

data = {
    "request": { "metadataOnly":False, "latitude": 80.12345,
        "treatmentFlags":["simple_search_1_1", "simple_search_desktop_v3_full_bleed", "flexible_dates_options_extend_one_three_seven_days"]}
}

j = json.dumps(data)             # Convert 'data' into a JSON string

u = urllib.parse.quote_plus(j)   # URL encode the JSON string
# 'u' now contains the desired result, starting with '%7B%22request%22%3A%7B%22metadataOnly%22%3A%22f' ...

# Reversing the process (url string back to dict)

# Decode the URL encoded string 'u' back into a normal JSON string
dec = urllib.parse.unquote_plus(u)
# Import the JSON string back into a Python dict (jd is effectively the same as 'data')
jd = json.loads(dec)
print(jd['request']['treatmentFlags'])
# Output: ['simple_search_1_1', 'simple_search_desktop_v3_full_bleed', 'flexible_dates_options_extend_one_three_seven_days']

Python Example (encoding a dict / list into URL encoded JSON)

Import the urllib.parse and json modules + create data object

First we need to import two modules: urllib.parse and json. Then declare the original dict that needs to be encoded as the variable data.

import urllib.parse
import json

data = {
    "request": {
        "metadataOnly":False,
        "latitude": 80.12345,
        "treatmentFlags":[
            "simple_search_1_1",
            "simple_search_desktop_v3_full_bleed",
            "flexible_dates_options_extend_one_three_seven_days"
        ]
    }
}

Encode the variable 'data' using JSON, into the variable 'j'

Using dumps from the json module, you can convert a Python dict or list into a JSON encoded string

j = json.dumps(data)

# You can see that 'j' is now a string
print(type(j))
# Output:
#  <class 'str'>

# If we print 'j', you can see the contents have been encoded as JSON
print(j)
# Output:
#
#   {"request": {"metadataOnly": false, "latitude": 80.12345, 
#   "treatmentFlags": ["simple_search_1_1", 
#   "simple_search_desktop_v3_full_bleed", 
#   "flexible_dates_options_extend_one_three_seven_days"]}}

Encode 'j' into the URL encoded variable 'u'

Now we convert the JSON string into encoded URL characters in variable 'u' so that it's safe for use in a URL query string

####
# Now we convert the JSON string into encoded URL characters in variable 'u'
# so that it's safe for use in a URL query string
####
u = urllib.parse.quote_plus(j)

# If we print the variable 'u', you can see it's now encoded in URL safe format
print(u)
# Output:
#
#   %7B%22request%22%3A+%7B%22metadataOnly%22%3A+false%2C+%22latitude
#   %22%3A+80.12345%2C+%22treatmentFlags%22%3A+%5B%22simple_search_1_1
#   %22%2C+%22simple_search_desktop_v3_full_bleed
#   %22%2C+%22flexible_dates_options_extend_one_three_seven_days%22%5D%7D%7D

Reversing the process (decoding URL encoded JSON back into a dict / list)

If you later needed to decode the URL encoded string back into JSON, and/or a dictionary, we can reverse the process like so:

Import modules again + declare URL encoded string 'u'

First we import urllib.parse and json, just like before, and declare the URL encoded string as u

import urllib.parse
import json

u = "%7B%22request%22%3A+%7B%22metadataOnly%22%3A+false%2C+%22latitude" + \
    "%22%3A+80.12345%2C+%22treatmentFlags%22%3A+%5B%22simple_search_1_1" + \
    "%22%2C+%22simple_search_desktop_v3_full_bleed" + \
    "%22%2C+%22flexible_dates_options_extend_one_three_seven_days%22%5D%7D%7D"

Decode the URL encoded string back into the original JSON string

Using unquote_plus from the urllib.parse module, you can decode a string which has been URL encoded (i.e. %22hello%20world%22)

dec = urllib.parse.unquote_plus(u)

print(dec)
# Output:
#
# {"request": {"metadataOnly": false, "latitude": 80.12345, "treatmentFlags": ["simple_search_1_1", "simple_search_desktop_v3_full_bleed", "flexible_dates_options_extend_one_three_seven_days"]}}

Load the JSON string into a standard Python dict/list

Using loads from the json module, you can import a JSON string ( str ) or bytes object into a standard Python dict or list (depending on whether you're decoding a JSON list or dictionary)

jd = json.loads(dec)

print(jd['request']['metadataOnly'])
# Output: False

print(jd['request']['treatmentFlags'])
# Output: 
#
#   ['simple_search_1_1', 'simple_search_desktop_v3_full_bleed', 'flexible_dates_options_extend_one_three_seven_days']

I guess you can you Python library which is urllib
by this it will take your data which is in dict. and give it back in the form of URL
eg:-\

import urllib.parse
data={
    "request": {
        "metadataOnly":False,
        "latitude": 80.12345,
        "treatmentFlags":[
            "simple_search_1_1",
            "simple_search_desktop_v3_full_bleed",
            "flexible_dates_options_extend_one_three_seven_days"
        ]
    }
}
data_in_form_of_URL = urllib.parse.urlencode(data)
print("Your URL is:-",str(data_in_form_of_URL))

you will get the output like :-

Your URL is:- request=%7B%27metadataOnly%27%3A+False%2C+%27latitude%27%3A+80.12345%2C+%27treatmentFlags%27%3A+%5B%27simple_search_1_1%27%2C+%27simple_search_desktop_v3_full_bleed%27%2C+%27flexible_dates_options_extend_one_three_seven_days%27%5D%7D
Related