API Documentation

ResourceFactory

class tastytopping.ResourceFactory(api_url, verify=True)

Create classes with which to access the API’s resources.

The resource classes are accessed as member variables on the factory object, via a resource’s name. For example, with a resource at http://localhost/app_name/api/v1/example_resource/, the ResourceFactory will have a member variable called ‘example_resource’ returning a Resource class (more specifically, a subclass of it, specialised for the resource in question):

>>> factory = ResourceFactory('http://localhost/app_name/api/v1/')
>>> old_resource = factory.example_resource.get(name='bob')
>>> new_resource = factory.example_resource(name='new name')
>>> # And to see what resources are available:
>>> factory.resources
['example', 'another_resource', 'entry']
Parameters:
  • api_url (str) – The url of the API!
  • verify (bool) – Sets whether SSL certificates for the API should be verified.
Variables:

resources – (list) - The names of each Resource this factory can create.

add_factory_dependency(factory)

Add another ResourceFactory as a dependency.

If any of the Resources associated with this ResourceFactory (Api on the tastypie side) have foreign keys to Resources associated with a different ResourceFactory, then this ResourceFactory depends on the other to create the Resources. In this case, you will need to pass the other ResourceFactory into this method.

Parameters:factory (ResourceFactory) – The ResourceFactory that this depends on.
auth

(AuthBase) - Update the auth on all resources accessed via this API. Any new Resources will have their auth set to this value too.

Resource

class tastytopping.resource.Resource(**kwargs)

A base class to inherit from, to wrap a TastyPie resource.

To wrap a TastyPie resource, a class must be defined that inherits from Resource. This derived class must specify, as a minimum, the class members ‘api_url’, and ‘resource_name’ (see below for descriptions). ResourceFactory returns instances of this class from its methods. Users are strongly encouraged to use these factory methods instead of directly subclassing from Resource.

Parameters:kwargs (dict) – Keyword arguments detailing the fields for the new resource.
classmethod all()

Returns a QuerySet with no filters applied.

Returns:A new QuerySet.
Return type:QuerySet
classmethod bulk(create=None, update=None, delete=None)

Create, update, and delete to multiple resources in a single request.

Note that this doesn’t return anything, so any created resources will have to be retrieved with get() / update() / all(). Resource objects passed into delete will be marked as deleted, so any attempt to use them afterwards will raise an exception.

Because of the potentially large size of bulk updates, the API will respond with a 202 before completing the request (see wikipedia, and tastypie). This means it’s possible for the request to fail without us knowing. So, while this method can be used for a sizeable optimization, there is a pitfall: You have been warned!

Parameters:
  • create (list) – The dicts of fields for new resources.
  • update (list) – The Resource objects to update.
  • delete (list) – The Resource objects to delete.
Raises:

ResourceDeleted

check_alive()

Check that the Resource has not been deleted.

Note that this only checks locally, so if another client deletes the resource originating from another ResourceFactory, or a different PC, it won’t be picked up.

Raises:ResourceDeleted
classmethod create(resources)

Creates new resources for each dict given.

This method exists purely for convenience and readability - internally it uses bulk().

Parameters:resources (list) – A list of fields (dict) for new resources.
delete()

Delete the object through the API.

Note that any attempt to use this object after calling delete will result in an ResourceDeleted exception.

Raises:ResourceDeleted
fields()

Return the fields according to the API.

Returns:The resource’s fields as {name (str): value (object)}.
Return type:dict
classmethod filter(**kwargs)

Return a QuerySet, with the given filters applied.

Parameters:kwargs (dict) – Keywors arguments to filter the search.
Returns:A new QuerySet.
Return type:QuerySet
classmethod get(**kwargs)

Return an existing object via the API.

Parameters:kwargs (dict) – Keywors arguments to filter the search.
Returns:The resource identified by the kwargs.
Return type:Resource
Raises:NoResourcesExist, MultipleResourcesReturned
classmethod none()

Return an EmptyQuerySet object.

Returns:A new QuerySet.
Return type:QuerySet
refresh()

Retrieve the latest values from the API with the next member access.

save()

Saves a resource back to the API.

Raises:ResourceDeleted
update(**kwargs)

Set multiple fields’ values at once, and call save().

Parameters:kwargs (dict) – The fields to update as keyword arguments.
uri()

Return the resource_uri for this object.

Returns:resource_uri
Return type:str
Raises:ResourceHasNoUri

QuerySet

class tastytopping.queryset.QuerySet(resource, **kwargs)

Allows for easier querying of resources while reducing API access.

The API and function are very similar to Django’s QuerySet class. There are a few differences: slicing this QuerySet will always evaluate the query and return a list; and this QuerySet accepts negative slices/indices [1].

Note that you normally wouldn’t instantiate QuerySets yourself; you’d be using a Resource’s filter(), all(), none(), get() methods to create a QuerySet.

A quick example:

# These will not evaluate the query (ie. hit the API):
some_resources_50_100 = SomeResource.filter(rating__gt=50, rating__lt=100)
some_resources_ordered = some_resources_50_100.order_by('rating')

# These will evaluate the query:
first_resource_above_50 = some_resources_ordered.first()
arbitrary_resource_between_50_and_100 = some_resources_ordered[5]
all_resources_between_50_and_100 = list(some_resources_ordered)
every_third_resource_between_100_and_50 = some_resources_ordered[::-3]
[1]Using negative slices/indices will result in more requests to the API, as the QuerySet needs to find the number of resources this query matches (using count()).
all()

Returns a copy of this QuerySet.

Returns:A new QuerySet.
Return type:QuerySet
count()

Return the number of records for this resource.

Parameters:kwargs (dict) – Keywors arguments to filter the search.
Returns:The number of records for this resource.
Return type:int
delete()

Delete every Resource filtered by this query.

Note that there is an optimization when calling delete() on a full QuerySet (ie. one without filters). So:

# this will be quicker:
Resource.all().filter()
# than this:
Resource.filter(id__gt=0).filter()
earliest(field_name)

Works otherwise like latest() except the direction is changed.

exists()

Returns whether this query matches any resources.

Returns:True if any resources match, otherwise False.
Return type:bool
filter(**kwargs)

Return a new QuerySet, with the given filters additionally applied.

Parameters:kwargs (dict) – Keywors arguments to filter the search.
Returns:A new QuerySet.
Return type:QuerySet
first()

Return the first resource from the query.

Returns:The first Resource, or None if the QuerySet is empty.
Return type:Resource
get(**kwargs)

Return an existing object via the API.

Parameters:kwargs (dict) – Keywors arguments to filter the search.
Returns:The resource identified by the kwargs.
Return type:Resource
Raises:NoResourcesExist, MultipleResourcesReturned
iterator()

Returns an iterator to the QuerySet’s results.

Evaluates the QuerySet (by performing the query) and returns an iterator over the results. A QuerySet typically caches its results internally so that repeated evaluations do not result in additional queries. In contrast, iterator() will read results directly, without doing any caching at the QuerySet level (internally, the default iterator calls iterator() and caches the return value). For a QuerySet which returns a large number of objects that you only need to access once, this can result in better performance and a significant reduction in memory.

Note that using iterator() on a QuerySet which has already been evaluated will force it to evaluate again, repeating the query.

Returns:An iterator to the QuerySet’s results.
Return type:iterator object
last()

Works like first(), but returns the last resource.

latest(field_name)

Returns the latest resource, by date, using the ‘field_name’ provided as the date field.

Note that earliest() and latest() exist purely for convenience and readability.

Parameters:field_name (str) – The name of the field to order the resources by.
Returns:The latest resource, by date.
Return type:Resource
Raises:NoResourcesExist
none()

Return an EmptyQuerySet object.

order_by(*args)

Order the query’s result according to the fields given.

The first field’s order will be most important, with the importance decending thereafter. Calling this method multiple times will achieve the same. For example, the following are equivalent:

query = query.order_by('path', 'content')
# Is equivalent to:
query = query.order_by('path')
query = query.order_by('content')
Parameters:args (tuple) – The fields according to which to order the Resources.
Returns:A new QuerySet.
Return type:QuerySet

Returns a QuerySet that will automatically retrieve, in a single batch, related objects for each of the specified lookups.

This method simulates an SQL ‘join’ and including the fields of the related object, except that it does a separate lookup for each relationship and does the ‘joining’ in Python.

It will check that the related field hasn’t already been ‘joined’ by setting ‘full=True’ in the Resource’s field in tastypie.

Take note that this method will fetch all the resources of all the given fields to do the ‘joining’, so it only makes sense for QuerySets that will return a large nunmber of resources. Even then, watch the memory usage!

Parameters:args (tuple) – The fields to prefetch.
Returns:A new QuerySet.
Return type:QuerySet
reverse()

Reverse the order of the Resources returned from the QuerySet.

Calling reverse() on an alerady-reversed QuerySet restores the original order of Resources.

Evaluating a QuerySet that is reversed but has no order will result in a OrderByRequiredForReverse exception being raised. So, ensure you call order_by() on any reversed QuerySet.

Returns:A new QuerySet.
Return type:QuerySet
update(**kwargs)

Updates all resources matching this query with the given fields.

This method provides a large optimization to updating each resource individually: This method will only make 2 API calls per thousand resources.

Parameters:kwargs (dict) – The fields to update: {field_name: field_value, ...}

Authentications

class tastytopping.auth.AuthBase[source]

Base class that all auth implementations derive from

class tastytopping.auth.HTTPApiKeyAuth(username, key)

Use TastyPie’s ApiKey authentication when communicating with the API.

class tastytopping.auth.HTTPSessionAuth(csrf_token=None)

Use Django’s Session authentication when communicating with the API.

The CSRF token can either be passed in on construction, or it will be automatically taken from the session’s cookies. If no CSRF token can be found, a MissingCsrfTokenInCookies exception will be raised.

extract_csrf_token(cookies)

Get the CSRF token given a session’s cookies.

Parameters:cookies (CookieJar) – A session’s cookies, one of which should contain the CSRF token.
Raises:MissingCsrfTokenInCookies
class tastytopping.auth.HTTPBasicAuth(username, password)[source]

Attaches HTTP Basic Authentication to the given Request object.

class tastytopping.auth.HTTPDigestAuth(username, password)[source]

Attaches HTTP Digest Authentication to the given Request object.

build_digest_header(method, url)[source]
handle_401(r, **kwargs)[source]

Takes the given response and tries digest-auth, if needed.

handle_redirect(r, **kwargs)[source]

Reset num_401_calls counter on redirects.

Exceptions

exception tastytopping.exceptions.BadUri

Raised when the URI given does not belong to the API.

exception tastytopping.exceptions.CannotConnectToAddress

Raised when no connection was possible at the given address.

exception tastytopping.exceptions.CreatedResourceNotFound

Raised when no resource can be found matching the resource created.

exception tastytopping.exceptions.ErrorResponse

Raised when an error status is returned from the API.

exception tastytopping.exceptions.FieldNotInSchema

Raised when a field should be part of the resource’s schema, but isn’t.

exception tastytopping.exceptions.FieldNotNullable

Raised when attempting to set a field to None, when the API forbids it.

exception tastytopping.exceptions.FilterNotAllowedForField

Raised when the filter used is not in the list of filters for the field in the API.

exception tastytopping.exceptions.IncorrectNestedResourceArgs

Raised when failing to GET a nested resource.

This is caused by tastypie raising a NotFound error in a 202 response. The cause is (almost always) an incorrect number of args to the method.

exception tastytopping.exceptions.IncorrectNestedResourceKwargs

Raised when failing to GET a nested resource.

Specifically, a MultiValueDictKeyError was raised in the nested resource. Since kwargs should have been passed to the Resource method, which the nested resource should be retrieving from the request.GET dict, it is assumed that kwargs were missing.

exception tastytopping.exceptions.InvalidFieldName

Raised when a field name will cause unexpected behaviour.

For instance, if a field is called ‘limit’, or ‘order_by’, it won’t be possible to order or limit the search results.

exception tastytopping.exceptions.InvalidFieldValue

Raised when a field has been passed the wrong type.

exception tastytopping.exceptions.MissingCsrfTokenInCookies

Raised when no CSRF token could be found in a session’s cookies.

This exception normally occurs when no CSRF token was passed to a HTTPSessionAuth object and there was no user authentication prior (which returned a CSRF token).

exception tastytopping.exceptions.MultipleResourcesReturned

Raised when more than one resource was found where only one was expected.

exception tastytopping.exceptions.NoDefaultValueInSchema

Raised when a field has no default value, but the user asked for one.

Note that this can happen if you haven’t yet saved a Resource, and you’re using a field that you haven’t provided a value for. For instance:

>>> res = factory.test_resource(path='test/path')
>>> res.rating      # Exception raised if rating has no default value.
exception tastytopping.exceptions.NoFiltersInSchema

Raised when the resource has no filters listed in the schema.

exception tastytopping.exceptions.NoResourcesExist

Raised when getting resources, but none were found.

exception tastytopping.exceptions.NoUniqueFilterableFields

Raised when the object has no fields with unique values to filter on.

exception tastytopping.exceptions.OrderByRequiredForReverse

Raised by QuerySet when attempting to reverse a query without an order.

This exception will be raised when attempting to evaluate a QuerySet that should be reversed (ie. reverse() has been called at least once), but does not have an order.

exception tastytopping.exceptions.PrettyException

Ensure the JSON dicts fed into the exceptions are formatted nicely.

exception tastytopping.exceptions.ReadOnlyField

Raised when attempting to update a read-only field.

exception tastytopping.exceptions.ResourceDeleted

Raised when attempting to use a deleted resource.

exception tastytopping.exceptions.ResourceHasNoUri

Raised when trying to use a not-yet-created Resource’s uri().

This can almost always be solved by saving the Resource first.

exception tastytopping.exceptions.RestMethodNotAllowed

Raised when the API does not allow a certain REST method (get/post/put/delete).