URL of an external website

422 views
Skip to first unread message

Louis Amon

unread,
Mar 27, 2014, 9:49:16 AM3/27/14
to web...@googlegroups.com
Hi,

I'm trying to use the URL() function to connect to an external website's API, thus benefitting from web2py's HTML entity encoding feature.

I wrote something like this :

URL(scheme='http', domain='www.example.org', a='API', vars={'locality':'some, city'})

and found that the encoded URL turns out like this : 
http://www.example.org/APP_NAME/API?locality=some%2C+city

With APP_NAME being my current application in web2py...


I found a monkeypatch solution like this :
URL(scheme='http', domain='www.example.org', a='API', c=' ', f=' ', vars={'locality':'some, city'})
 
Which gives me an ugly but functional URL :
http://www.example.org/API/ / ?locality=some%2C+city



Is there a more elegant solution to this ?

Jonathan Lundell

unread,
Mar 27, 2014, 12:25:15 PM3/27/14
to web2py
URL() doesn't anticipate being used to generate external URLs, only web2py URLs. You'd be better off, I think, writing your own utility routine to do what you're after. urllib.urlencode does the magic for your query string (vars).

So for your example, something like:

encodeURL("http://www.example.org", path=['API'], query={'locality':'some, city'})

...would be pretty trivial to write (path is a list of URL path elements to be suitable encoded and joined with '/').

villas

unread,
Mar 28, 2014, 9:35:39 AM3/28/14
to web...@googlegroups.com
Hi Louis
 

>>> URL(a='a',c='c',f='f')
'/a/c/f'

>>> URL(a='a',c=' ',f=' ')
'/a/ / '

>>> URL(a='a')
'/APPNAME/a'

>>> URL(a='a',c='',f='')
'/APPNAME/a'


In the last two commands,  APPNAME appears.  Why?  That's looks like a bug.

@Jonathan,  I cannot see why URL() cannot generate external urls in principle.  Otherwise why have scheme and host arguments?

Regards,
David


Massimo Di Pierro

unread,
Mar 28, 2014, 10:41:30 AM3/28/14
to web...@googlegroups.com
URL('function') -> /<app>/<contr>/function
URL('controller','function') -> /<app>/controller/function
URL('myapp','controller','function') -> /myapp/controller/function

You are specifying an appname (a) but no controller nor function. I believe that behavior is unspecified.

Jonathan Lundell

unread,
Mar 28, 2014, 11:13:54 AM3/28/14
to web2py
We added those primarily to generate absolute URLs for use in (for example) emails and other external references to web2py-generated pages, and to override hostnames in some odd cases of multiple-domain sites (IIRC). 

It's not that you might not be able to induce it to make external URLs, but it doesn't make it easy, and the interactions with routing on the outgoing side could be hard to predict.

The thing is, it's harder to force URL to do the right thing here than it is to use the standard Python library to do the encoding correctly. If we really wanted to wrap those functions, and allow the use of constructs like args and vars in the URL's construction, it'd be better to write another wrapper. Call it XURL for external URL.

villas

unread,
Mar 28, 2014, 12:15:59 PM3/28/14
to web...@googlegroups.com
@Massimo,  Regarding
>>> URL(a='a')
'/APPNAME/a'
>>> URL(a='a',c='c')
'/APPNAME/a/c'

... may be 'unspecified',  but it is still unexpected and confusing.  In the latter case,  the 'a' becomes the controller and the 'c' the function.

@Jonathan,  Re: external urls.  I see,  thanks.

Niphlod

unread,
Mar 28, 2014, 4:04:11 PM3/28/14
to web...@googlegroups.com
its expected if you don't pass the request argument (as the URL() was originally written).
basically, URL() "behaves" with a,c,f consistently only if you pass r=request, else, a c and f are just "positional", and missing pieces are set on current request.

villas

unread,
Mar 29, 2014, 8:04:34 AM3/29/14
to web...@googlegroups.com
@Niphlod
My point was simply this:  if I set a='myapp'  I would expect 'myapp' to replace the appname from r or anywhere else.
This behaviour also caused difficulty for the OP. 
I just mentioned it in case it was a bug.  Thanks for commenting.


Jonathan Lundell

unread,
Mar 29, 2014, 10:02:44 AM3/29/14
to web2py
Sadly, it's not a bug. If it were, we'd fix it. 

Rather, it's for backward compatibility with ancient versions of URL() in which the first argument was treated as positional. 

Louis Amon

unread,
Apr 3, 2014, 10:19:15 AM4/3/14
to web...@googlegroups.com
This is indeed a smart way to do it, thanks for the answer !


On a sidenote, I actually used URL() to do the following to retrieve more geocoding information:
google_geo_url = URL(scheme='http', host='maps.googleapis.com', a='maps', c='api', f='geocode', args=['json'], vars={'sensor':'false', 'address':addr})

Which, I find, is a very elegant way to make a call to an external API.

As Massimo mentioned : this only works if a/c/f are ALL defined, which can be confusing. But then again : URL wasn't designed for external urls.

I think Jonathan's idea to make a XURL() helper would be a nice improvement : it is equivalent to using encodeURL but definitely more web2py-esque.
URL(..., external=True) could also do the trick.

Like villas, I believed that specifying an explicit scheme and host would necessarily make it an external URL...
Reply all
Reply to author
Forward
0 new messages