urllib: parsing multidimensional dictionaries

1,479 views
Skip to first unread message

Arthur Gouveia

unread,
Jun 23, 2011, 12:06:22 PM6/23/11
to Montreal Python
Hello, everyone!

I'm having a problem parsing a multidimensional dictionary to a URL...

This are my params:

self.params = {
            'user_key': configs.listInfo['user_key'],
            'client_id': configs.listInfo['client_id'],
            'list_id': configs.listInfo['list_id'],
            'record_id': '1',
            'data': {'email':'conta...@email.com'}
}

It does not work and I'm guessing it has something to do with the urllib.encode not working since I have a dictionary inside my dictionary.

I tried

self.params = {
            'user_key': configs.listInfo['user_key'],
            'client_id': configs.listInfo['client_id'],
            'list_id': configs.listInfo['list_id'],
            'record_id': '1',
            'data': urllib.urlencode({'email':'conta...@email.com'})
}

But no results. I checked on the web some ppl creating methods to recursively go through the params and encoding.
Anyone else faced this problem?

Thanks!












Arthur Gouveia
Web Developer

MSN/GTalk: arthur....@gmail.com
Phone: 514.708.6042 











Simon Law

unread,
Jun 23, 2011, 12:17:25 PM6/23/11
to montrea...@googlegroups.com
URL parameters aren't really made for what you're proposing.

Either flatten your data, to fit how URL parameters work.

Or don't flatten to a URL and instead POST your data as something like 'application/json'.

--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes Montréal-Python.
Pour envoyer un message à ce groupe, adressez un e-mail à montrea...@googlegroups.com.
Pour vous désabonner de ce groupe, envoyez un e-mail à l'adresse montrealpytho...@googlegroups.com.
Pour plus d'options, consultez la page de ce groupe : http://groups.google.com/group/montrealpython?hl=fr-CA



--

Arthur Gouveia

unread,
Jun 23, 2011, 12:28:39 PM6/23/11
to montrea...@googlegroups.com
The API I need to do a POST to only accepts application/x-www-form-urlencoded

Any ideas on how to solve this problem?

My request is basically done like this: http://pastebin.com/KT0TywVP

Joel Perras

unread,
Jun 23, 2011, 12:45:05 PM6/23/11
to montrea...@googlegroups.com
On Thu, Jun 23, 2011 at 12:28 PM, Arthur Gouveia <arthur....@gmail.com> wrote:
The API I need to do a POST to only accepts application/x-www-form-urlencoded

Any ideas on how to solve this problem?

My request is basically done like this: http://pastebin.com/KT0TywVP

`urllib.urlencode({'foo': 'bar', 'baz': 'bing'})` produces 'foo=bar&baz=bing', which all webservers will understand as being the keys 'foo' and 'baz' with the values 'bar' and 'bing', respectively. What you're trying to do with nested dictionaries doesn't make sense if you're forced to post to x-www-form-urlencoded - there is no "standard" for nested keys in URL parameters.

-j.



--
I do know everything, just not all at once. It's a virtual memory problem.
You should follow me on Twitter: http://twitter.com/jperras

Arthur Gouveia

unread,
Jun 23, 2011, 1:05:37 PM6/23/11
to montrea...@googlegroups.com
All the other parameters in param are working fine, but data needs to be presented as data[email]=cont...@email.com&data[name]=some%20name.

So this works:

params = {
            'user_key': configs.listInfo['user_key'],
            'client_id': configs.listInfo['client_id'],
            'list_id': configs.listInfo['list_id'],
            'record_id': '1',
            'data[email]': 'conta...@email.com',
            'data[name]':'somename'
}

But I was wondering if urllib.encode would turn a dictionary inside my dictionary of params into the needed url encoding.

Rory Geoghegan

unread,
Jun 23, 2011, 1:24:01 PM6/23/11
to montrea...@googlegroups.com
Unless the data[foo]=bar is a standard I am not aware of, you are unfortunately going to have to do it by hand:

params.update(
    dict(
        ("data[%s]" % k, v) for (k,v) in params.pop("data").items()
    )
)

--Rory Geoghegan

Yannick Gingras

unread,
Jun 23, 2011, 1:30:00 PM6/23/11
to montrea...@googlegroups.com
On June 23, 2011, Arthur Gouveia wrote:
> But I was wondering if urllib.encode would turn a dictionary inside my
> dictionary of params into the needed url encoding.

The urlencode() function does not serialize nested dictionaries
because nested dicts do not have a universally agreed-on meaning in
URL params. The API that you are using is implementing a very
specific approach and you can't expect the Python standard library to
accommodate every possible API there is out there.

Your solution, "data[email]", is good. There is nothing wrong about it.

--
Yannick Gingras
http://ygingras.net

signature.asc

Arthur Gouveia

unread,
Jun 23, 2011, 1:47:35 PM6/23/11
to montrea...@googlegroups.com
Thank you all for the answers. I had this solution previously but I thought someone had faced it and had a better approach.

I guess in order to make stuff more dynamic I'll have the APIRequest method to check if there's a nested dict inside, and if it does, modify it so that it get well formated before going to urllib.encode, this way I won't need to write everything in such a boring way.

Thanks again.












Arthur Gouveia
Web Developer

MSN/GTalk: arthur....@gmail.com
Phone: 514.708.6042 













Adrian Ghizaru

unread,
Jun 23, 2011, 2:05:31 PM6/23/11
to montrea...@googlegroups.com
You have to be careful. You haven't told us what you're planning to do with this query string, but the field[key]=value trick isn't actually part of any standard. It's become popular because of PHP, which will automatically parse that into an "associative array", so you're well covered if you're talking to a PHP server. Otherwise, for pretty much anything else when you parse that query string you'll get the equivalent of { "field[key]": "value" } and will have to go parse those keys yourself and build the dictionaries when you find [ ]'s

But as far as encoding goes, yeah that's perfectly valid, it shouldn't care what characters you use in the keys.

Reply all
Reply to author
Forward
0 new messages