Why Use Tastypie

686 views
Skip to first unread message

Andres

unread,
Dec 23, 2010, 5:22:26 PM12/23/10
to Tastypie
Hi,

I'm trying to add a an API to a site and have been looking around for
python frameworks that can help in doing so. I've started playing with
piston but recently came across tastypie. I was wondering what are the
benefits of tastypie over something like piston. Would love to hear
thoughts on this.

Thanks a lot!

Daniel Lindsley

unread,
Dec 24, 2010, 12:03:25 AM12/24/10
to django-...@googlegroups.com
Andres,


I'd love to get you a better answer, but my family is facing a
serious illness and my time is short this weekend. I promise I'll get
you a response, just not this week anymore. Sorry,


Daniel

Andres

unread,
Dec 24, 2010, 12:09:38 AM12/24/10
to Tastypie
I appreciate the response and look forward to the full one. I hope the
situation gets better.

Thanks,

Andres

On Dec 24, 6:03 am, Daniel Lindsley <polarc...@gmail.com> wrote:
> Andres,
>
>    I'd love to get you a better answer, but my family is facing a
> serious illness and my time is short this weekend. I promise I'll get
> you a response, just not this week anymore. Sorry,
>
> Daniel
>

Gregor Müllegger

unread,
Dec 24, 2010, 4:14:04 AM12/24/10
to django-...@googlegroups.com
Until then I try to explain a bit the things I know - at least the
advantages over piston.

I also started with piston since most django guys promoted it as the way to go
for an API. But after playing around with it and trying to get serious it left
me alone. What I mean is that it basically only provides the very simple
infrastructure for dispatching the PUT/POST/DELETE what ever HTTP verbs into
method calls.

Since piston wants to tie into django, it also provides an easy starting point
for creating an API backed by one of your models. However you don't have many
hooks available for customizing pistons behaviour there. You are left alone
if you want to change only a small amount of the returned data format or if
you want to limit the results to a special queryset based on the request etc.

After all I felt very limited with piston unless I want to switch out all the
logic that is already provided in the resources (since it has very low
possibilities for customization). I even tried to fork piston and cleaning up
the things, making it better for a model based API. However I found a
not-so-pretty code base. It wasn't too bad, I don't want to blame the author
(or saying that I could do better) - but in the end it was quite messy to
refactor it. The worst thing was that not even most of the codebase was
properly tested. That left me again with a bad feeling using piston.


Tastypie does a lot of the things better here. I had really no issues with
integrating a lot of custom behaviour. It presents you a lot of hooking points
that allow you to only switch out the bits you need. The authorization /
authentication parts are clearly seperated and well implemented for easy
swapping. Tastypie provides out-of-the box public (and machine-readable!)
documentation of your API.

It follows a different principle, you don't need to overwrite the
POST/PUT/DELETE/GET methods on the resource. You really don't need to touch
the related methods in the resource with tastypie if you want to use a model
backed API. You can use different "fields" like you know from django.forms to
define which fields are returned. Also supporting list fields for m2m
relations etc.

These fields also contain the logic for parsing incoming data, so you don't
need to re-write all the code if you use the same special/strange field on
multiple models.

I also had nice email with Daniel after I found some limiting part of
tastypie. He tackled the issue quite quickly, making it much more worth for me
using the package. Also the code base seems much more tidy and better tested.


What piston and tastypie do both correctly (in my opinion) is the use of
different formatters. Both can return your data as different formats like
JSON, XML, YAML etc.


@Daniel: I wish the best for you and your family. May the spirit of christmas
get through to you, making everybody alright again.

--
Servus,
Gregor

2010/12/24 Andres <andres....@gmail.com>:

Andres

unread,
Dec 24, 2010, 6:03:08 AM12/24/10
to Tastypie
Gregor,

Thanks a lot for the response. Some responses/questions embedded
below.

On Dec 24, 10:14 am, Gregor Müllegger <gre...@muellegger.de> wrote:
> Until then I try to explain a bit the things I know - at least the
> advantages over piston.
>
> I also started with piston since most django guys promoted it as the way to go
> for an API. But after playing around with it and trying to get serious it left
> me alone. What I mean is that it basically only provides the very simple
> infrastructure for dispatching the PUT/POST/DELETE what ever HTTP verbs into
> method calls.
I know all you *really* need for CRUD is PUT/POST/DELETE/GET. How easy
is it to have custom verb urls in tastypie and how would you do it?
i.e. site.com/api/product/flag as opposed to having to use PUT to
update the whole model (there may be some extra logic I need to
handle).
>
> Since piston wants to tie into django, it also provides an easy starting point
> for creating an API backed by one of your models. However you don't have many
> hooks available for customizing pistons behaviour there. You are left alone
> if you want to change only a small amount of the returned data format or if
> you want to limit the results to a special queryset based on the request etc.
How do you do this in tastypie? I wish there was a non-blog, real-
world example, i.e. with Users, UserProfiles (with fk to User, etc),
and more stuff to actually demonstrate all of this.
>
> After all I felt very limited with piston unless I want to switch out all the
> logic that is already provided in the resources (since it has very low
> possibilities for customization). I even tried to fork piston and cleaning up
> the things, making it better for a model based API. However I found a
> not-so-pretty code base. It wasn't too bad, I don't want to blame the author
> (or saying that I could do better) - but in the end it was quite messy to
> refactor it. The worst thing was that not even most of the codebase was
> properly tested. That left me again with a bad feeling using piston.
I've had the same feeling. Also, lack of documentation is a killer.
>
> Tastypie does a lot of the things better here. I had really no issues with
> integrating a lot of custom behaviour. It presents you a lot of hooking points
> that allow you to only switch out the bits you need.
Could you give a particular example here.
> The authorization /
> authentication parts are clearly seperated and well implemented for easy
> swapping. Tastypie provides out-of-the box public (and machine-readable!)
> documentation of your API.
Can you use the Django authentication? Also, I couldn't find any
reference to OAuth, is that correct? The latter seems very important.
>
> It follows a different principle, you don't need to overwrite the
> POST/PUT/DELETE/GET methods on the resource. You really don't need to touch
> the related methods in the resource with tastypie if you want to use a model
> backed API. You can use different "fields" like you know from django.forms to
> define which fields are returned. Also supporting list fields for m2m
> relations etc.
I'm using mongoengine for some of my models. How well will tastypie
play with it? I'll probably have to write a lot of custom code, right?
>
> These fields also contain the logic for parsing incoming data, so you don't
> need to re-write all the code if you use the same special/strange field on
> multiple models.
Could you provide an example?
>
> I also had nice email with Daniel after I found some limiting part of
> tastypie. He tackled the issue quite quickly, making it much more worth for me
> using the package. Also the code base seems much more tidy and better tested.
That's important and nice :)
>
> What piston and tastypie do both correctly (in my opinion) is the use of
> different formatters. Both can return your data as different formats like
> JSON, XML, YAML etc.
Why does tastypie have so many dependencies that piston doesn't
though? That worries me a little bit :(
>
> @Daniel: I wish the best for you and your family. May the spirit of christmas
> get through to you, making everybody alright again.
>
> --
> Servus,
> Gregor
>
> 2010/12/24 Andres <andres.doug...@gmail.com>:

Josh Bohde

unread,
Dec 24, 2010, 10:28:04 AM12/24/10
to django-...@googlegroups.com
Responses inline

On Fri, Dec 24, 2010 at 5:03 AM, Andres <andres....@gmail.com> wrote:
Gregor,

Thanks a lot for the response. Some responses/questions embedded
below.

On Dec 24, 10:14 am, Gregor Müllegger <gre...@muellegger.de> wrote:
> Until then I try to explain a bit the things I know - at least the
> advantages over piston.
>
> I also started with piston since most django guys promoted it as the way to go
> for an API. But after playing around with it and trying to get serious it left
> me alone. What I mean is that it basically only provides the very simple
> infrastructure for dispatching the PUT/POST/DELETE what ever HTTP verbs into
> method calls.
I know all you *really* need for CRUD is PUT/POST/DELETE/GET. How easy
is it to have custom verb urls in tastypie and how would you do it?
i.e. site.com/api/product/flag as opposed to having to use PUT to
update the whole model (there may be some extra logic I need to
handle).
 
This would probably be properly handled by HTTP PATCH (http://tools.ietf.org/html/rfc5789). Fielding specifically mentions this in http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven, where he states the following:

A REST API should not contain any changes to the communication protocols aside from filling-out or fixing the details of underspecified bits of standard protocols, such as HTTP’s PATCH method or Link header field.

Currently, this isn't in Tastypie. I actually encountered a very similar situation a couple of days ago, however. The method I used was to require a PUT, and to override the obj_update method to catch the change in flag state. You can view an example at 

>
> Since piston wants to tie into django, it also provides an easy starting point
> for creating an API backed by one of your models. However you don't have many
> hooks available for customizing pistons behaviour there. You are left alone
> if you want to change only a small amount of the returned data format or if
> you want to limit the results to a special queryset based on the request etc.
How do you do this in tastypie? I wish there was a non-blog, real-
world example, i.e. with Users, UserProfiles (with fk to User, etc),
and more stuff to actually demonstrate all of this.


 
>
> After all I felt very limited with piston unless I want to switch out all the
> logic that is already provided in the resources (since it has very low
> possibilities for customization). I even tried to fork piston and cleaning up
> the things, making it better for a model based API. However I found a
> not-so-pretty code base. It wasn't too bad, I don't want to blame the author
> (or saying that I could do better) - but in the end it was quite messy to
> refactor it. The worst thing was that not even most of the codebase was
> properly tested. That left me again with a bad feeling using piston.
I've had the same feeling. Also, lack of documentation is a killer.
>
> Tastypie does a lot of the things better here. I had really no issues with
> integrating a lot of custom behaviour. It presents you a lot of hooking points
> that allow you to only switch out the bits you need.
Could you give a particular example here.
> The authorization /
> authentication parts are clearly seperated and well implemented for easy
> swapping. Tastypie provides out-of-the box public (and machine-readable!)
> documentation of your API.
Can you use the Django authentication? Also, I couldn't find any
reference to OAuth, is that correct? The latter seems very important.

Do you mean the Django cookie based auth? Assuming it's already setup in your project, then https://gist.github.com/754329 should work for you. 
 
>
> It follows a different principle, you don't need to overwrite the
> POST/PUT/DELETE/GET methods on the resource. You really don't need to touch
> the related methods in the resource with tastypie if you want to use a model
> backed API. You can use different "fields" like you know from django.forms to
> define which fields are returned. Also supporting list fields for m2m
> relations etc.
I'm using mongoengine for some of my models. How well will tastypie
play with it? I'll probably have to write a lot of custom code, right?
>
> These fields also contain the logic for parsing incoming data, so you don't
> need to re-write all the code if you use the same special/strange field on
> multiple models.
Could you provide an example?

 A file upload field example: https://gist.github.com/709890

Andres

unread,
Jan 4, 2011, 5:15:55 PM1/4/11
to Tastypie
Josh,

Thanks a lot. I've been reading through those links and other
literature and I think I'm starting to understand what a RESTful API
really means. Some questions:

Is there OAuth support in Tastypie? I couldn't seem to find any
reference to it.

What about using NoSQL ORMs, such as mongoengine. Any idea on how easy/
difficult it would be?

I was thinking of assigning unique identifiers to each object in the
DB, and using uuid4() to create these unique identifiers. Would it be
unreasonable to do so, and potentially end up with something like
http://site.com/api/users/4955c63185ba45f1a65c4c289d9b5b71?

More embedded below:

On Dec 24 2010, 4:28 pm, Josh Bohde <josh.bo...@gmail.com> wrote:
> Responses inline
>
>
>
>
>
> On Fri, Dec 24, 2010 at 5:03 AM, Andres <andres.doug...@gmail.com> wrote:
> > Gregor,
>
> > Thanks a lot for the response. Some responses/questions embedded
> > below.
>
> > On Dec 24, 10:14 am, Gregor Müllegger <gre...@muellegger.de> wrote:
> > > Until then I try to explain a bit the things I know - at least the
> > > advantages over piston.
>
> > > I also started with piston since most django guys promoted it as the way
> > to go
> > > for an API. But after playing around with it and trying to get serious it
> > left
> > > me alone. What I mean is that it basically only provides the very simple
> > > infrastructure for dispatching the PUT/POST/DELETE what ever HTTP verbs
> > into
> > > method calls.
> > I know all you *really* need for CRUD is PUT/POST/DELETE/GET. How easy
> > is it to have custom verb urls in tastypie and how would you do it?
> > i.e. site.com/api/product/flag as opposed to having to use PUT to
> > update the whole model (there may be some extra logic I need to
> > handle).
>
> This would probably be properly handled by HTTP PATCH (http://tools.ietf.org/html/rfc5789). Fielding specifically mentions this inhttp://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven, where
Although PATCH seems nice, in practice I assume it's not widely used.
This probably represents a problem from a client perspective - i.e.
some clients don't support more than POST/GET (I know!).

In the absence of PATCH, how do people perform updates? Do they submit
the full copy of the resource they want to update?

I think in practice very few people actually create strictly RESTful
APIs as Fielding points out. What if I do want to be one of those
people and allow more custom verbs in my urls, how would I do that
with Tastypie?

> he states the following:
>
> A REST API should not contain any changes to the communication protocols
>
> > aside from filling-out or fixing the details of underspecified bits of
> > standard protocols, such as HTTP’s PATCH method or Link header field.
>
> Currently, this isn't in Tastypie. I actually encountered a very similar
> situation a couple of days ago, however. The method I used was to require a
> PUT, and to override the obj_update method to catch the change in flag
> state. You can view an example athttps://gist.github.com/754323.
>
>
>
> > > Since piston wants to tie into django, it also provides an easy starting
> > point
> > > for creating an API backed by one of your models. However you don't have
> > many
> > > hooks available for customizing pistons behaviour there. You are left
> > alone
> > > if you want to change only a small amount of the returned data format or
> > if
> > > you want to limit the results to a special queryset based on the request
> > etc.
> > How do you do this in tastypie? I wish there was a non-blog, real-
> > world example, i.e. with Users, UserProfiles (with fk to User, etc),
> > and more stuff to actually demonstrate all of this.
>
> There are some examples in the docs.
>
> Filtering based on a request:http://toastdriven.github.com/django-tastypie/authentication_authoriz...
> your project, thenhttps://gist.github.com/754329should work for you.

Josh Bohde

unread,
Jan 4, 2011, 7:31:17 PM1/4/11
to django-...@googlegroups.com
Responses inline. 

On Tue, Jan 4, 2011 at 4:15 PM, Andres <andres....@gmail.com> wrote:
Josh,

Thanks a lot. I've been reading through those links and other
literature and I think I'm starting to understand what a RESTful API
really means. Some questions:

Is there OAuth support in Tastypie? I couldn't seem to find any
reference to it.

 
Not currently. It probably wouldn't be too difficult to make an Authentication class using https://bitbucket.org/david/django-oauth-plus/wiki/Home, based upon a cursory glance. 
 
What about using NoSQL ORMs, such as mongoengine. Any idea on how easy/
difficult it would be?


This depends on the specific tech. I've heard of using it on appengine with a degree of success. Mongoengine doesn't seem to have a close enough API to the Django ORM to reuse the ModelResource class that comes with Tastypie. You'd probably need to write a new Resource subclass to properly support Mongoengine, along with some custom Fields. I don't know how much you could reuse from ModelResource. 
 
I was thinking of assigning unique identifiers to each object in the
DB, and using uuid4() to create these unique identifiers. Would it be
unreasonable to do so, and potentially end up with something like
http://site.com/api/users/4955c63185ba45f1a65c4c289d9b5b71?


As long as it provides the uuid is the pk attribute, this url should work out of the box.
Yes, using a PUT.   
 
I think in practice very few people actually create strictly RESTful
APIs as Fielding points out. What if I do want to be one of those
people and allow more custom verbs in my urls, how would I do that
with Tastypie?


Use the override_urls, as shown in http://toastdriven.github.com/django-tastypie/cookbook.html#using-non-pk-data-for-your-urls. You'd need to write your own views, however.

Daniel Lindsley

unread,
Jan 18, 2011, 1:18:38 AM1/18/11
to django-...@googlegroups.com
Andres,


Adding new non-CRUD endpoints is pretty simple. Write the new
method, override the ``override_urls`` method & put in the URLconf for
that method (making sure you wrap it with ``wrap_view``). You can
probably infer what's needed from looking at
https://github.com/toastdriven/django-tastypie/blob/master/tastypie/resources.py#L247-264
& https://github.com/toastdriven/django-tastypie/blob/master/tastypie/resources.py#L1036-1086
(examples of non-CRUD methods).

Oauth isn't supported yet, though it should be just writing the
necessary ``Authentication`` class & supporting details. I'm waist
deep in an HTTP Basic authentication implementation that'll be
included in Tastypie 1.0. Writing an Oauth variant shouldn't be much
more difficult, but I need time to get there.

As for non-relational stores, Tastypie was *built* for this. You'd
extend ``Resource`` instead of ``ModelResource``, then override a
handful (~7-9 methods). ``ModelResource`` itself is a relatively light
extension of ``Resource`` & diving into it's source should give you an
idea of what needs doing. I've personally hooked Tastypie up to Solr &
Riak to good success (though sadly nothing public yet). And
``uuid.uuid4`` is a good approach to me.

To Gregor & Josh, thanks for the (too) kind words & the help
demonstrating why one might choose Tastypie. The reason (to me) to use
Tastypie is that it was purpose-built to allow for easy extension,
decent test coverage & some of the self-documenting features. I'm not
here to slam Piston (many people like it) but Tastypie was built to be
what I think an API should work like.


Daniel

Martin

unread,
Jan 18, 2011, 7:47:30 AM1/18/11
to django-...@googlegroups.com
Hi Daniel,

glad to see you back on the list!

I just opened the door to the world of RESTful APIs yesterday evening. I started playing around with piston and then found someone on their list mentioning tastypie. So I gave it a try as well and only by reading the docs of both systems and by executing the getting started parts of the documentation I can say that tastypie feels like the better alternative to me already.

Keep up the awesome work!

Best regards,
Martin
Reply all
Reply to author
Forward
0 new messages