Commit 5d238605 authored by Alexandre Leray's avatar Alexandre Leray
Browse files

Continued to work on the API

parent 8fa5cf8e
......@@ -119,3 +119,6 @@ Meeting Skyope long-court 27/04/2012
====================================
- Scroll personalisé
Bug: les messages de commits ne peuvent etre qu'ascii
......@@ -16,115 +16,69 @@ from aawiki.mdx.mdx_sectionedit import (sectionalize, sectionalize_replace)
from tastypie.validation import Validation
#class PageValidation(Validation):
#"""
#The custom validation checks two things:
#1) that there is data
#2) that the CompanyId exists (unique check)
#"""
#def is_valid(self, bundle, request=None):
#if not bundle.data:
#return {'__all__': 'Missing data, please include CompanyName, CompanyId, Contact, Email, and Phone.'}
#errors = {}
#page_name = bundle.data.get('name', None)
## manager method, returns true if the company exists, false otherwise
#if Company.objects.filter(name=page_name).exists():
#errors['name']='Duplicate CompanyId, CompanyId %s already exists.' % page_name
#return errors
#class CSVSerializer(Serializer):
#formats = ['json', 'jsonp', 'xml', 'yaml', 'html', 'plist', 'audacity', 'markdown']
#content_types = {
#'json': 'application/json',
#'jsonp': 'text/javascript',
#'xml': 'application/xml',
#'yaml': 'text/yaml',
#'html': 'text/html',
#'plist': 'application/x-plist',
#'audacity': 'text/plain',
#'markdown': 'text/plain',
#}
#def to_markdown(self, data, options=None):
#options = options or {}
#data = self.to_simple(data, options)
#return data['content']
#def to_audacity(self, data, options=None):
#options = options or {}
#data = self.to_simple(data, options)
#data = srt_to_audacity(data['content'])
#return data
#def from_audacity(self, content):
#raw_data = StringIO.StringIO(content)
#data = []
## Untested, so this might not work exactly right.
#for item in csv.DictReader(raw_data):
#data.append(item)
#return data
#class SectionResource(Resource):
## Just like a Django ``Form`` or ``Model``, we're defining all the
## fields we're going to handle with the API here.
#header = fields.CharField(attribute='header')
#body = fields.CharField(attribute='body')
#index = fields.IntegerField(attribute='index')
#start = fields.IntegerField(attribute='start')
#end = fields.IntegerField(attribute='end')
#class Meta:
#resource_name = 'section'
#authentication = BasicAuthentication()
#authorization = DjangoAuthorization()
class CustomAuthentication(BasicAuthentication):
def is_authenticated(self, request, **kwargs):
if request.method in ('GET', 'OPTIONS', 'HEAD'):
return True
else:
return super(CustomAuthentication, self).is_authenticated(request, **kwargs)
class PageResource(ModelResource):
class Meta:
queryset = Page.objects.all()
resource_name = 'page'
authentication = BasicAuthentication()
authentication = CustomAuthentication()
authorization = DjangoAuthorization()
include_resource_uri = False
excludes = ['id']
#serializer = CSVSerializer(formats=['json', 'plist', 'audacity', 'markdown'])
#excludes = ['id']
def get_resource_uri(self, bundle_or_obj):
"""
Handles generating a resource URI for a single resource.
#def get_resource_uri(self, bundle_or_obj):
#"""
#Handles generating a resource URI for a single resource.
Uses the model's ``pk`` in order to create the URI.
"""
kwargs = {
'resource_name': self._meta.resource_name,
}
#Uses the model's ``pk`` in order to create the URI.
#"""
#kwargs = {
#'resource_name': self._meta.resource_name,
#}
if isinstance(bundle_or_obj, Bundle):
kwargs['name'] = bundle_or_obj.obj.name
else:
kwargs['name'] = bundle_or_obj.name
#if isinstance(bundle_or_obj, Bundle):
#kwargs['name'] = bundle_or_obj.obj.name
#else:
#kwargs['name'] = bundle_or_obj.name
if self._meta.api_name is not None:
kwargs['api_name'] = self._meta.api_name
#if self._meta.api_name is not None:
#kwargs['api_name'] = self._meta.api_name
return self._build_reverse_url("api_dispatch_detail", kwargs=kwargs)
#return self._build_reverse_url("api_dispatch_detail", kwargs=kwargs)
def override_urls(self):
def base_urls(self):
"""
The standard URLs this ``Resource`` should respond to.
"""
# Due to the way Django parses URLs, ``get_multiple`` won't work without
# a trailing slash.
return [
url(r"^(?P<resource_name>%ss)%s$" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('dispatch_list'), name="api_dispatch_list"),
url(r"^(?P<resource_name>%ss)/schema%s$" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('get_schema'), name="api_get_schema"),
url(r"^(?P<resource_name>%ss)/set/(?P<pk_list>\w[\w/;-]*)/$" % self._meta.resource_name,
self.wrap_view('get_multiple'), name="api_get_multiple"),
url(r"^(?P<resource_name>%ss)/(?P<name>\w[\w\d_.-]*)%s$" % (self._meta.resource_name,
trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
url(r"^(?P<resource_name>%s)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_list'), name="api_dispatch_list"),
url(r"^(?P<resource_name>%s)/schema%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_schema'), name="api_get_schema"),
#url(r"^(?P<resource_name>%s)/set/(?P<pk_list>[-\w;-]+)/$" % self._meta.resource_name, self.wrap_view('get_multiple'), name="api_get_multiple"),
url(r"^(?P<resource_name>%s)/(?P<pk>[-\w]+)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
]
#def override_urls(self):
#return [
##url(r"^(?P<resource_name>%ss)%s$" % (self._meta.resource_name, trailing_slash()),
##self.wrap_view('dispatch_list'), name="api_dispatch_list"),
##url(r"^(?P<resource_name>%ss)/schema%s$" % (self._meta.resource_name, trailing_slash()),
##self.wrap_view('get_schema'), name="api_get_schema"),
##url(r"^(?P<resource_name>%ss)/set/(?P<pk_list>\w[\w/;-]*)/$" % self._meta.resource_name,
##self.wrap_view('get_multiple'), name="api_get_multiple"),
#url(r"^(?P<resource_name>%ss)/(?P<name>[-\w]+)%s$" % (self._meta.resource_name,
#trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
#]
#def dehydrate(self, bundle):
## Include the request IP in the bundle.
#section = int(bundle.request.GET.get('section', 0))
......@@ -132,6 +86,7 @@ class PageResource(ModelResource):
#bundle.data['content'] = s['header'] + s['body']
#return bundle
class SectionObject(object):
def __init__(self, initial=None):
self.__dict__['_data'] = {}
......@@ -157,29 +112,40 @@ class SectionResource(Resource):
end = fields.IntegerField(attribute='end', readonly=True)
class Meta:
queryset = Page.objects.all()
resource_name = 'page'
#queryset = Page.objects.all()
resource_name = 'section'
object_class = SectionObject
authentication = BasicAuthentication()
authentication = CustomAuthentication()
authorization = DjangoAuthorization()
include_resource_uri = False
excludes = ['id']
#include_resource_uri = False
#excludes = ['id']
def override_urls(self):
#/pages/Index/sections/
#/pages/Index/sections/schema/
#/pages/Index/sections/set/1;3
#/pages/Index/sections/1/
"""
The standard URLs this ``Resource`` should respond to.
"""
# Due to the way Django parses URLs, ``get_multiple`` won't work without
# a trailing slash.
return [
url(r"^(?P<resource_name>%s)s/(?P<name>[-\w]+)/sections%s$" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('dispatch_list'), name="api_dispatch_list"),
url(r"^(?P<resource_name>%s)s/(?P<name>[-\w]+)/sections/schema%s$" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('get_schema'), name="api_get_schema"),
url(r"^(?P<resource_name>%s)s/(?P<name>[-\w]+)/sections/set/(?P<pk_list>\d+[;-]\d+)%s$" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('get_multiple'), name="api_get_multiple"),
url(r"^(?P<resource_name>%s)s/(?P<name>[-\w]+)/sections/(?P<pk>\d+)%s$" % (self._meta.resource_name,
trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
url(r"^page/(?P<resource_name>%s)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_list'), name="api_dispatch_list"),
url(r"^page/(?P<resource_name>%s)/schema%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_schema'), name="api_get_schema"),
url(r"^page/(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)/$" % self._meta.resource_name, self.wrap_view('get_multiple'), name="api_get_multiple"),
url(r"^page/(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
]
##/pages/Index/sections/
##/pages/Index/sections/schema/
##/pages/Index/sections/set/1;3
##/pages/Index/sections/1/
#return [
#url(r"^(?P<resource_name>%s)s/(?P<name>[-\w]+)/sections%s$" % (self._meta.resource_name, trailing_slash()),
#self.wrap_view('dispatch_list'), name="api_dispatch_list"),
#url(r"^(?P<resource_name>%s)s/(?P<name>[-\w]+)/sections/schema%s$" % (self._meta.resource_name, trailing_slash()),
#self.wrap_view('get_schema'), name="api_get_schema"),
#url(r"^(?P<resource_name>%s)s/(?P<name>[-\w]+)/sections/set/(?P<pk_list>\d+[;-]\d+)%s$" % (self._meta.resource_name, trailing_slash()),
#self.wrap_view('get_multiple'), name="api_get_multiple"),
#url(r"^(?P<resource_name>%s)s/(?P<name>[-\w]+)/sections/(?P<pk>\d+)%s$" % (self._meta.resource_name,
#trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
#]
def get_resource_uri(self, bundle_or_obj):
"""
......
......@@ -40,7 +40,7 @@ class Page(models.Model):
last revision of a page for convenience.
"""
name = models.CharField(max_length=255, unique=True)
name = models.CharField(max_length=255, primary_key=True)
content = models.TextField(blank=True)
def __unicode__(self):
......
......@@ -35,8 +35,8 @@ urlpatterns = patterns('aawiki.views',
v1_api = Api(api_name='v1')
#v1_api.register(PageResource())
v1_api.register(SectionResource())
v1_api.register(PageResource())
urlpatterns += patterns('',
(r'^api/', include(v1_api.urls)),
......
.. _ref-api:
========
REST API
========
http://127.0.0.1:8000/api/v1/
http://127.0.0.1:8000/api/v1/page/
http://127.0.0.1:8000/api/v1/page/:name/
http://127.0.0.1:8000/api/v1/page/:name/?section=:section
http://127.0.0.1:8000/api/v1/page/:name/?format=:format
http://127.0.0.1:8000/api/v1/page/:name/section/
http://127.0.0.1:8000/api/v1/page/:name/section/:id/
.. http://127.0.0.1:8000/api/v1/
.. http://127.0.0.1:8000/api/v1/page/
.. http://127.0.0.1:8000/api/v1/page/:name/
.. http://127.0.0.1:8000/api/v1/page/:name/?section=:section
.. http://127.0.0.1:8000/api/v1/page/:name/?format=:format
.. http://127.0.0.1:8000/api/v1/page/:name/section/
.. http://127.0.0.1:8000/api/v1/page/:name/section/:id/
Creating a page
===============
.. code-block:: bash
curl -i -H "Content-Type: application/json" -X PUT -d '{"content": "Hello world"}' -u username:password http://localhost:8000/api/v1/page/Index/
.. code-block:: http
HTTP/1.0 201 CREATED
Date: Sat, 12 May 2012 23:52:59 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Type: text/html; charset=utf-8
Location: http://localhost:8000/api/v1/page/Index/
or
.. code-block:: bash
curl -i -H "Content-Type: application/json" -X POST -d '{"name": "Another_page", "content": "Here comes some content"}' -u username:password http://localhost:8000/api/v1/page/
.. code-block:: http
HTTP/1.0 201 CREATED
Date: Sat, 12 May 2012 23:56:39 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Type: text/html; charset=utf-8
Location: http://localhost:8000/api/v1/page/Another_page/
Getting a page
==============
List all the pages
------------------
.. code-block:: bash
$ curl -i -H "Accept: application/json" -X GET http://127.0.0.1:8000/api/v1/page/
curl -i -H "Accept: application/json" -X GET http://localhost:8000/api/v1/page/Index/
.. code-block:: http
HTTP/1.0 200 OK
Date: Mon, 30 Apr 2012 05:12:58 GMT
Date: Sun, 13 May 2012 00:11:51 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Type: application/json; charset=utf-8
{
meta: {
limit: 20,
next: null,
offset: 0,
previous: null,
total_count: 0
},
objects: []
"content": "Hello world",
"name": "Index"
}
Create a new page
-----------------
Updating a page
===============
.. code-block:: bash
$ curl -i -H "Content-Type: application/json" -X PUT -d '{"content": "Hello World"}' http://localhost:8000/api/v1/page/Hello_world/ -u foo:bar
HTTP/1.0 201 CREATED
Date: Mon, 30 Apr 2012 05:11:56 GMT
curl -i -H "Content-Type: application/json" -X PUT -d '{"content": "Hello universe."}' -u username:password http://localhost:8000/api/v1/page/Index/
.. code-block:: http
HTTP/1.0 204 NO CONTENT
Date: Sun, 13 May 2012 00:03:38 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Length: 0
Content-Type: text/html; charset=utf-8
Location: http://localhost:8000/api/v1/page/6/
or
.. code-block:: bash
$ curl -i -H "Content-Type: application/json" -X POST -d '{"name": "bar", "content": "content2"}' http://localhost:8000/api/v1/page/ -u foo:bar
HTTP/1.0 201 CREATED
Date: Mon, 30 Apr 2012 05:09:21 GMT
curl -i -H "Content-Type: application/json" -X PATCH -d '{"content": "Hello world, hello universe."}' -u username:password http://localhost:8000/api/v1/page/Index/
.. code-block:: http
HTTP/1.0 202 ACCEPTED
Date: Sun, 13 May 2012 00:04:48 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Type: text/html; charset=utf-8
Location: http://localhost:8000/api/v1/page/5/
Update a page
-------------
Listing all the pages
=====================
.. code-block:: bash
$ curl -i -H "Content-Type: application/json" -X PATCH -d '{"content": "Hello World3"}' http://localhost:8000/api/v1/page/Hello_world2/ -u foo:bar
HTTP/1.0 202 ACCEPTED
Date: Mon, 30 Apr 2012 05:15:47 GMT
curl -i -H "Accept: application/json" -X GET http://127.0.0.1:8000/api/v1/page/
or more simply
.. code-block:: bash
curl -i http://127.0.0.1:8000/api/v1/page/
.. code-block:: http
HTTP/1.0 200 OK
Date: Sun, 13 May 2012 00:18:21 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Type: application/json; charset=utf-8
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 2
},
"objects": [
{
"content": "Hello world, hello universe.",
"name": "Index"
},
{
"content": "Here comes some content",
"name": "AnotherPage"
}
]
}
Deleting a page
===============
.. code-block:: bash
curl -i -X DELETE -u username:password http://localhost:8000/api/v1/page/Index/
.. code-block:: http
HTTP/1.0 204 NO CONTENT
Date: Sun, 13 May 2012 00:06:20 GMT
Server: WSGIServer/0.1 Python/2.7.3
Content-Length: 0
Content-Type: text/html; charset=utf-8
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment