Skip to content

Commit

Permalink
Merge master
Browse files Browse the repository at this point in the history
  • Loading branch information
georgedorn committed Jun 16, 2017
2 parents dd8097c + 606d054 commit a26548d
Show file tree
Hide file tree
Showing 187 changed files with 5,902 additions and 3,546 deletions.
57 changes: 39 additions & 18 deletions .travis.yml
@@ -1,36 +1,57 @@
sudo: false

language: python

python:
- "2.6"
- "2.7"
- "3.3"
- "3.4"

env:
- DJANGO_VERSION=1.5
- DJANGO_VERSION=1.6
- DJANGO_VERSION=1.7
- DJANGO_VERSION=1.8
- DJANGO_VERSION=dev
- MODE=flake8
- MODE=flake8-strict
- MODE=docs
- DJANGO_VERSION=dj18
- DJANGO_VERSION=dj111
- DJANGO_VERSION=djdev

matrix:
allow_failures:
- env: DJANGO_VERSION=dev
- env: DJANGO_VERSION=djdev
- env: MODE=flake8-strict
exclude:
- env: DJANGO_VERSION=dev
python: "2.6"
- env: DJANGO_VERSION=1.8
python: "2.6"
- env: DJANGO_VERSION=1.7
python: "2.6"
- python: "3.4"
env: MODE=flake8
- python: "3.4"
env: MODE=flake8-strict
- python: "2.7"
env: DJANGO_VERSION=djdev

addons:
apt:
packages:
- binutils
- libproj-dev
- gdal-bin
- spatialite-bin
- libspatialite-dev

before_install:
- sudo apt-get install python-sphinx python3-sphinx
cache:
directories:
- $HOME/.cache/pip

before_cache:
- rm -f $HOME/.cache/pip/log/debug.log

# command to install dependencies
install:
- pip install tox
- pip install -U pip
- pip install -U wheel virtualenv
- pip install tox coveralls

after_success:
- coveralls

# command to run tests
script:
- tox -e py${TRAVIS_PYTHON_VERSION/./}-${DJANGO_VERSION},docs
- coverage erase
- tox -e py${TRAVIS_PYTHON_VERSION/./}-${DJANGO_VERSION}${MODE}
18 changes: 18 additions & 0 deletions AUTHORS
Expand Up @@ -86,6 +86,24 @@ Contributors:
* Steven Davidson (damycra) for a documentation patch.
* Harish Srinivas for a minor bug fix that raises an exception if a given related resource is none.
* Miguel Carranza (MiguelCarranza) for patching 'filter_value_to_python' to support __in filters in kwargs.
* Renjith Thankachan for a patch that fixes `django.utils.importlib` error in Django 1.9+ release.
* Sean Hayes (SeanHayes) for test suite and CI enhancements, various patches
* Michael Thornhill (mthornhill) for strict dict checking bugfix
* Fedor Baart (siggyf) for an update on the serializer
* Alexey Kotlyarov (koterpillar) - fixing DateField/DateTimeField.
* Yuri Govorushchenko (metametadata) for documentation fixes.
* Guilhem Saurel (Nim65s) for a minor issue with Django 1.9
* Jack Cushman (jcushman) for converting ResourceTestCase to ResourceTestCaseMixin.
* John Lucas (jlucas91) for an improvement to the response for requests with invalid JSON.
* Judit Novak (juditnovak) for related schema updates
* Mike Bryant (mikebryant) for unit tests
* Maxim Filipenko (prokaktus) for changing repr value to str in Python 2
* Thomas Yip (thomasyip) PR #1409
* Sam Thompson(georgedorn) for fixing some docs and tests.
* Matt Cooper (vtbassmatt) for making ApiKey better in Python 3
* Nick Sullivan (gorillamania) for admin improvements.
* Danny Roberts (dannyroberts) for very small change addressing noisy RemovedInDjango20Warning warnings


Thanks to Tav for providing validate_jsonp.py, placed in public domain.

Expand Down
2 changes: 1 addition & 1 deletion BACKWARDS-INCOMPATIBLE.txt
Expand Up @@ -22,4 +22,4 @@ v0.9.12


Backward-incompatible commits were not recorded prior to the release of v0.9.11
but may be found using ``git grep --oneline ...v0.9.11 | grep "BACKWARD-"``.
but may be found using ``git log --oneline ...v0.9.11 | grep "BACKWARD-"``.
13 changes: 11 additions & 2 deletions CONTRIBUTING
Expand Up @@ -33,8 +33,8 @@ So you've found a bug or have a great idea for a feature. Here's the steps you
should take to help get it added/fixed in Tastypie:

* First, check to see if there's an existing issue/pull request for the
bug/feature. All issues are at https://github.com/toastdriven/django-tastypie/issues
and pull reqs are at https://github.com/toastdriven/django-tastypie/pulls.
bug/feature. All issues are at https://github.com/django-tastypie/django-tastypie/issues
and pull reqs are at https://github.com/django-tastypie/django-tastypie/pulls.
* If there isn't one there, please file an issue. The ideal report includes:

* A description of the problem/suggestion.
Expand Down Expand Up @@ -88,6 +88,15 @@ In order to be merged into Tastypie, contributions must have the following:
* Must be appropriately licensed (see "Philosophy").
* Adds yourself to the AUTHORS file.

Please also:

* Unless your change only modifies the documentation, add the issue you're
solving to the list in docs/release_notes/dev.rst, include issue and PR
numbers.
* Squash your changes down to a single commit, or down to one commit containing
your failing tests and one more commit containing the fix that makes those
tests pass.

If your contribution lacks any of these things, they will have to be added
by a core contributor before being merged into Tastypie proper, which may take
substantial time for the all-volunteer team to get to.
Expand Down
56 changes: 44 additions & 12 deletions README.rst
Expand Up @@ -2,9 +2,29 @@
django-tastypie
===============

.. image:: https://readthedocs.org/projects/django-tastypie/badge/
:target: https://django-tastypie.readthedocs.io/
:alt: Docs

.. image:: https://travis-ci.org/django-tastypie/django-tastypie.svg
:target: https://travis-ci.org/django-tastypie/django-tastypie
:alt: CI

.. image:: https://coveralls.io/repos/django-tastypie/django-tastypie/badge.svg?service=github
:target: https://coveralls.io/github/django-tastypie/django-tastypie
:alt: Code Coverage

.. image:: https://img.shields.io/pypi/v/django-tastypie.svg
:target: https://pypi.python.org/pypi/django-tastypie
:alt: Version

.. image:: https://img.shields.io/pypi/dm/django-tastypie.svg
:target: https://pypi.python.org/pypi/django-tastypie
:alt: Downloads

Creating delicious APIs for Django apps since 2010.

Currently in beta (v0.12.0) but being used actively in production on several
Currently in beta (v0.13.3) but being used actively in production on several
sites.


Expand All @@ -14,8 +34,8 @@ Requirements
Core
----

* Python 2.6+ or Python 3.3+
* Django 1.5+
* Python 2.7+ or Python 3.4+
* Django 1.7 through Django 1.9
* dateutil (http://labix.org/python-dateutil) >= 2.1

Format Support
Expand Down Expand Up @@ -51,30 +71,30 @@ A basic example looks like:
# urls.py
# =======
from django.conf.urls.defaults import *
from django.conf.urls import url, include
from tastypie.api import Api
from myapp.api import EntryResource
v1_api = Api(api_name='v1')
v1_api.register(EntryResource())
urlpatterns = patterns('',
urlpatterns = [
# The normal jazz here then...
(r'^api/', include(v1_api.urls)),
)
url(r'^api/', include(v1_api.urls)),
]
That gets you a fully working, read-write API for the ``Entry`` model that
supports all CRUD operations in a RESTful way. JSON/XML/YAML support is already
there, and it's easy to add related data/authentication/caching.

You can find more in the documentation at
http://django-tastypie.readthedocs.org/.
https://django-tastypie.readthedocs.io/.


Why Tastypie?
=============

There are other, better known API frameworks out there for Django. You need to
There are other API frameworks out there for Django. You need to
assess the options available and decide for yourself. That said, here are some
common reasons for tastypie.

Expand All @@ -85,21 +105,33 @@ common reasons for tastypie.
the problem domain.
* You want/need XML serialization that is treated equally to JSON (and YAML is
there too).
* You want to support my perceived NIH syndrome, which is less about NIH and more
about trying to help out friends/coworkers.


Reference Material
==================

* http://github.com/toastdriven/django-tastypie/tree/master/tests/basic shows
* https://django-tastypie.readthedocs.io/en/latest/
* https://github.com/django-tastypie/django-tastypie/tree/master/tests/basic shows
basic usage of tastypie
* http://en.wikipedia.org/wiki/REST
* http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
* http://www.ietf.org/rfc/rfc2616.txt
* http://jacobian.org/writing/rest-worst-practices/


Getting Help
============

There are two primary ways of getting help.

1. Go to `StackOverflow`_ and post a question with the ``tastypie`` tag.
2. We have an IRC channel (`#tastypie on irc.freenode.net`_) to get help,
bounce an idea by us, or generally shoot the breeze.

.. _`StackOverflow`: https://stackoverflow.com/questions/tagged/tastypie
.. _#tastypie on irc.freenode.net: irc://irc.freenode.net/tastypie


Security
========

Expand Down
12 changes: 6 additions & 6 deletions docs/api.rst
Expand Up @@ -17,6 +17,7 @@ Quick Start
A sample api definition might look something like (usually located in a
URLconf)::

from django.conf.urls import url, include
from tastypie.api import Api
from myapp.api.resources import UserResource, EntryResource

Expand All @@ -25,10 +26,11 @@ URLconf)::
v1_api.register(EntryResource())

# Standard bits...
urlpatterns = patterns('',
(r'^api/', include(v1_api.urls)),
)
urlpatterns = [
url(r'^api/', include(v1_api.urls)),
]

For namespaced urls see :ref:`namespaces`

``Api`` Methods
===============
Expand Down Expand Up @@ -83,8 +85,7 @@ Deprecated. Will be removed by v1.0.0. Please use ``Api.prepend_urls`` instead.
A hook for adding your own URLs or matching before the default URLs. Useful for
adding custom endpoints or overriding the built-in ones.

Should return a list of individual URLconf lines (**NOT** wrapped in
``patterns``).
Should return a list of individual URLconf lines.

``urls``
~~~~~~~~
Expand All @@ -103,4 +104,3 @@ Provides URLconf details for the ``Api`` and all registered

A view that returns a serialized list of all resources registers
to the ``Api``. Useful for discovery.

6 changes: 3 additions & 3 deletions docs/authentication.rst
Expand Up @@ -94,10 +94,10 @@ Tastypie includes a signal function you can use to auto-create ``ApiKey``
objects. Hooking it up looks like::

from django.contrib.auth.models import User
from django.db import models
from django.db.models import signals
from tastypie.models import create_api_key

models.signals.post_save.connect(create_api_key, sender=User)
signals.post_save.connect(create_api_key, sender=User)

.. warning::

Expand All @@ -114,7 +114,7 @@ objects. Hooking it up looks like::

.. _`this post`: http://www.nerdydork.com/basic-authentication-on-mod_wsgi.html
.. _`abstract base class`: https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes
.. _`the documentation for this setting`: http://django-tastypie.readthedocs.org/en/latest/settings.html#tastypie-abstract-apikey
.. _`the documentation for this setting`: https://django-tastypie.readthedocs.io/en/latest/settings.html#tastypie-abstract-apikey

``SessionAuthentication``
~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
38 changes: 36 additions & 2 deletions docs/authorization.rst
Expand Up @@ -58,10 +58,44 @@ class and the safe option.
~~~~~~~~~~~~~~~~~~~~~~~

The most advanced form of authorization, this checks the permission a user
has granted to them (via ``django.contrib.auth.models.Permission``). In
has granted to them on the resource's model (via ``django.contrib.auth.models.Permission``). In
conjunction with the admin, this is a very effective means of control.


The permissions required using ``DjangoAuthorization`` follow Django Admin's implementation and are as follows:

+---------------------------------+------------------+-----------------------------------------------+----------------------+
| HTTP + URI | Method | User’s permissions required to grant access | Includes check for |
+=================================+==================+===============================================+======================+
| ``POST <resource>/`` | create\_list | ``add`` | |
+---------------------------------+------------------+-----------------------------------------------+----------------------+
| ``POST <resource>/<id>`` (\*) | create\_detail | ``add`` | |
+---------------------------------+------------------+-----------------------------------------------+----------------------+
| ``GET <resource>/`` | read\_list | ``change`` | |
+---------------------------------+------------------+-----------------------------------------------+----------------------+
| ``GET <resouce>/<id>`` | read\_detail | ``change`` | |
+---------------------------------+------------------+-----------------------------------------------+----------------------+
| ``PUT <resource>/`` | update\_list | ``change`` | ``read_list`` |
+---------------------------------+------------------+-----------------------------------------------+----------------------+
| ``PUT <resource>/<id>`` | update\_detail | ``change`` | ``read_detail`` |
+---------------------------------+------------------+-----------------------------------------------+----------------------+
| ``DELETE <resource>/`` | delete\_list | ``delete`` | ``read_list`` |
+---------------------------------+------------------+-----------------------------------------------+----------------------+
| ``DELETE <resource>/`` | delete\_detail | ``delete`` | ``read_detail`` |
+---------------------------------+------------------+-----------------------------------------------+----------------------+

(*) The permission check for ``create_detail`` is implemented in ``DjangoAuthorization``, however ModelResource does not provide an implementation and raises HttpNotImplemented.


Notes:

* The actual permission checked is `<app_label>.<permission>_<model>` where app_label is derived from the resource's model (e.g. `myapp.change_foomodel`)
* `PUT` may revert to `POST` behavior and create new object(s) if the object(s) are not found. In this case the respective `create` permissions are required, instead of the usual `update` permissions.
* Requiring `change` for both read and update is such to keep consistent with Django Admin. To override this behavior and require a custom permission, override DjangoAuthorization as follows::

class CustomDjangoAuthorization(DjangoAuthorization):
READ_PERM_CODE = 'view` # matching respective Permission.codename
The ``Authorization`` API
=========================

Expand Down
4 changes: 4 additions & 0 deletions docs/code/authentication.py
@@ -0,0 +1,4 @@
import mock


OAuth20Authentication = mock.Mock()
10 changes: 10 additions & 0 deletions docs/code/manage.py
@@ -0,0 +1,10 @@
#!/usr/bin/env python
import os
import sys

if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")

from django.core.management import execute_from_command_line

execute_from_command_line(sys.argv)
File renamed without changes.
Empty file added docs/code/myapp/api/__init__.py
Empty file.
8 changes: 8 additions & 0 deletions docs/code/myapp/api/resources.py
@@ -0,0 +1,8 @@
from tastypie.resources import ModelResource

from ..models import User


class UserResource(ModelResource):
class Meta:
object_class = User.objects.all()
8 changes: 8 additions & 0 deletions docs/code/myapp/models.py
@@ -0,0 +1,8 @@
import mock

from django.contrib.auth.models import User # flake8: noqa


Choice = mock.MagicMock()
Poll = mock.MagicMock()
MyModel = mock.MagicMock()
4 changes: 4 additions & 0 deletions docs/code/myapp/urls.py
@@ -0,0 +1,4 @@
from tastypie.api import Api


my_api = Api()
Empty file added docs/code/myproject/__init__.py
Empty file.

0 comments on commit a26548d

Please sign in to comment.