Extracting arguments to web service methods

10 views
Skip to first unread message

magus

unread,
Aug 24, 2006, 9:16:42 AM8/24/06
to Django users
>From what I can see django would be a very convenient tool to build
webservices similar to the del.icio.us API (i.e. I'm not interested in
SOAP, XML-RPC, JSON, etc).

The only way I've found of extracting arguments is to use request.GET
like this

request.GET['arg1']

(Optional arguments (i.e. arguments with default values) could be done
using `request.GET.get('arg1', 'default value')`.)

This is a little cumbersome though since I need to enclose it in a
try-catch block to deal with missing arguments. Is there some
convenience function relating to this? Personally I was thinking of
writing a decorator that'd be used something like this:

@extract_arguments(['arg1', 'arg2'], ['arg3', 'arg4'])
def foo(request, arg1, arg2, arg3='default', arg4='default):
...


Another thing I'm wondering here is relating to authentication.
`django.contrib.auth` relies on sessions, which is good for sites but
is unnecessary for web services (again I'm looking at del.icio.us as a
good example). Is there a more light weight module available? Again
I've been thinking a little about it, what I think would be sufficient
is:

1. A minimal model for a user, just username and password.
2. A decorator that inspects the HTTP request for Basic-Auth headers,
does a lookup and calls the decoratee if the username/password matches.

Any thoughts on this?


Neither of these things would be amazingly difficult to write, I think.
I'm more than willing to do it myself, but if solutions are already out
there I'd rather use them (or at least take a look at them before
hacking my own :-).

/M

Jacob Kaplan-Moss

unread,
Aug 24, 2006, 10:51:57 AM8/24/06
to django...@googlegroups.com
On Aug 24, 2006, at 8:16 AM, magus wrote:
> This is a little cumbersome though since I need to enclose it in a
> try-catch block to deal with missing arguments.

Note that ``request.GET`` and friends follow the standard Python
mapping interface, so you can use ``get()`` to provide a default value::

arg1 = request.GET.get("arg1", "default")

(see http://docs.python.org/lib/typesmapping.html for more on Python
mapping interfaces).

> Another thing I'm wondering here is relating to authentication.
> `django.contrib.auth` relies on sessions, which is good for sites but
> is unnecessary for web services (again I'm looking at del.icio.us as a
> good example).

The session stuff is only accessed if you actually try to use it. If
you don't every check ``request.session``, the code'll never run.

Hope that helps!

Oh, and in the future, questions like these are better addressed to
django-users; django-dev is really designed for discussions of
hacking *on* Django, not *with* it.

Thanks!

Jacob

Jacob Kaplan-Moss

unread,
Aug 24, 2006, 10:56:54 AM8/24/06
to Django users
Jacob Kaplan-Moss wrote:
> Oh, and in the future, questions like these are better addressed to
> django-users [...]

Which is, of course, exactly where you posted this.

Sheesh, I'm a moron. Time for more coffee.

Jacob

magus

unread,
Aug 25, 2006, 11:48:09 AM8/25/06
to Django users

Jacob Kaplan-Moss wrote:
[..]

> > Another thing I'm wondering here is relating to authentication.
> > `django.contrib.auth` relies on sessions, which is good for sites but
> > is unnecessary for web services (again I'm looking at del.icio.us as a
> > good example).
>
> The session stuff is only accessed if you actually try to use it. If
> you don't every check ``request.session``, the code'll never run.

Well, the auth module _requires_ the session stuff. Which in this case
is overkill. All I really need is to return a 401 and get a basic
authentication.

/M

Ivan Sagalaev

unread,
Aug 25, 2006, 3:13:55 PM8/25/06
to django...@googlegroups.com
magus wrote:
> Well, the auth module _requires_ the session stuff. Which in this case
> is overkill. All I really need is to return a 401 and get a basic
> authentication.

I've posted some time ago on this list a simple middleware that does
HTTP authorization and sets request.user just like standard cookie-based
authorization:
http://groups.google.com/group/django-users/browse_thread/thread/cc928718a1a6cad5/201b8bed2315fb99?lnk=gst&rnum=1#201b8bed2315fb99

Looks like it'll work for you, even without modifications.

However, more properly would be refactor it as an auth backend but I
wrote it before multi-auth branch and now I'm too lazy ;-)

magus

unread,
Aug 25, 2006, 6:31:35 PM8/25/06
to Django users

Ivan Sagalaev wrote:
> magus wrote:
> > Well, the auth module _requires_ the session stuff. Which in this case
> > is overkill. All I really need is to return a 401 and get a basic
> > authentication.
>
> I've posted some time ago on this list a simple middleware that does
> HTTP authorization and sets request.user just like standard cookie-based
> authorization:
> http://groups.google.com/group/django-users/browse_thread/thread/cc928718a1a6cad5/201b8bed2315fb99?lnk=gst&rnum=1#201b8bed2315fb99
>
> Looks like it'll work for you, even without modifications.

I'll have to look at it in more detail but it looks close to what I
want. It does leave one thing out though--creating a 401 response if
authentication is missing.

> However, more properly would be refactor it as an auth backend but I
> wrote it before multi-auth branch and now I'm too lazy ;-)

Since I'm brand new at this I haven't got the faintest what you're
talking about here. Pointers are welcome :-)

/M

Ivan Sagalaev

unread,
Aug 25, 2006, 6:46:56 PM8/25/06
to django...@googlegroups.com
magus wrote:
> I'll have to look at it in more detail but it looks close to what I
> want. It does leave one thing out though--creating a 401 response if
> authentication is missing.

Ah... Yes, I have it in another place since I have a mixed
authorization. But it's simple to add where it checks

if not authorization:
return

it should be:

if not authorization:
from django.http import HttpResponse
response=HttpResponse()
response.status_code=401
response['WWW-Authenticate']='Basic realm="Your realm"'
return response

And you should also remove first to lines checking for
request.user.is_anonymous since you don't have request.user at this time.

>> However, more properly would be refactor it as an auth backend but I
>> wrote it before multi-auth branch and now I'm too lazy ;-)
>
> Since I'm brand new at this I haven't got the faintest what you're
> talking about here. Pointers are welcome :-)

It's not related to your question exactly... Django recently learned to
use pluggable authorization modules for different authorization schemes
instead of built-in one. So I noted that this thing working as a
middleware should actually be such a module. It would be more clean
architecturally. But it still works :-)

Reply all
Reply to author
Forward
0 new messages