diff --git a/docs/build/.doctrees/datastore.doctree b/docs/build/.doctrees/datastore.doctree index 132ccf9..3ff1ab6 100644 Binary files a/docs/build/.doctrees/datastore.doctree and b/docs/build/.doctrees/datastore.doctree differ diff --git a/docs/build/.doctrees/environment.pickle b/docs/build/.doctrees/environment.pickle index e3b0153..36dcc87 100644 Binary files a/docs/build/.doctrees/environment.pickle and b/docs/build/.doctrees/environment.pickle differ diff --git a/docs/build/.doctrees/index.doctree b/docs/build/.doctrees/index.doctree index c8e8cd7..4774476 100644 Binary files a/docs/build/.doctrees/index.doctree and b/docs/build/.doctrees/index.doctree differ diff --git a/docs/build/.doctrees/references.doctree b/docs/build/.doctrees/references.doctree index 30f4d40..11c478e 100644 Binary files a/docs/build/.doctrees/references.doctree and b/docs/build/.doctrees/references.doctree differ diff --git a/docs/build/.doctrees/tutorial.doctree b/docs/build/.doctrees/tutorial.doctree new file mode 100644 index 0000000..db7a651 Binary files /dev/null and b/docs/build/.doctrees/tutorial.doctree differ diff --git a/docs/build/.doctrees/using_user_endpoint.doctree b/docs/build/.doctrees/using_user_endpoint.doctree new file mode 100644 index 0000000..280b6cd Binary files /dev/null and b/docs/build/.doctrees/using_user_endpoint.doctree differ diff --git a/docs/build/_modules/rest_api_framework/controllers.html b/docs/build/_modules/rest_api_framework/controllers.html index 5553141..41ec4d5 100644 --- a/docs/build/_modules/rest_api_framework/controllers.html +++ b/docs/build/_modules/rest_api_framework/controllers.html @@ -70,12 +70,12 @@

Source code for rest_api_framework.controllers

""" return self.wsgi_app(environ, start_response) - def wsgi_app(self, environ, start_response): +

[docs] def wsgi_app(self, environ, start_response): request = Request(environ) response = self.dispatch_request(request) return response(environ, start_response) -
+
[docs]class WSGIDispatcher(DispatcherMiddleware): """ Embed multiple endpoint in one diff --git a/docs/build/_sources/index.txt b/docs/build/_sources/index.txt index 7245871..d4c2c38 100644 --- a/docs/build/_sources/index.txt +++ b/docs/build/_sources/index.txt @@ -12,6 +12,7 @@ Contents: :maxdepth: 2 introduction + tutorial datastore controller pagination diff --git a/docs/build/_sources/tutorial.txt b/docs/build/_sources/tutorial.txt new file mode 100644 index 0000000..1fa00ea --- /dev/null +++ b/docs/build/_sources/tutorial.txt @@ -0,0 +1,128 @@ +Tutorial building an adressebook API +==================================== + +First Step Building a user endpoint +----------------------------------- + +For this project we need users. Users will be helpfull for our adress +book and for our authentication process. + +Users will be define with at least a first name and a last name. We +also need an unique identifier to retreive the user. + +Define a model +~~~~~~~~~~~~~~ + +.. code-block:: python + + from rest_api_framework import models + + class UserModel(models.Model): + + fields = [models.StringField(name="first_name", required=True), + models.StringField(name="last_name", required=True), + models.PkField(name="id", required=True) + ] + +The use of required_true will ensure that a user without this field +cannot be created + +Chose a DataStore +~~~~~~~~~~~~~~~~~ + +We also need a datastore to get a place where we can save our +users. For instance we will use a sqlite3 database. The +SQLiteDataStore is what we need + +.. code-block:: python + + from rest_api_framework.datastore import SQLiteDataStore + +Chose a view +~~~~~~~~~~~~ + +We want results to be rendered as Json. We use the JsonResponse view +for that: + +.. code-block:: python + + from rest_api_framework.views import JsonResponse + +Create The user endpoint +~~~~~~~~~~~~~~~~~~~~~~~~ + +To create an endpoint, we need a controller. This will manage our +endpoint in a RESTFUL fashion. + +.. code-block:: python + + from rest_api_framework.controllers import Controller + + class UserEndPoint(Controller): + ressource = { + "ressource_name": "users", + "ressource": {"name": "adress_book.db", "table": "users"}, + "model": UserModel, + "datastore": SQLiteDataStore + } + + controller = { + "list_verbs": ["GET", "POST"], + "unique_verbs": ["GET", "PUT", "DElETE"] + } + + view = {"response_class": JsonResponse} + +then we must run our application: + +.. code-block:: python + + if __name__ == '__main__': + from werkzeug.serving import run_simple + from rest_api_framework.controllers import WSGIDispatcher + app = WSGIDispatcher([UserEndPoint]) + run_simple('127.0.0.1', 5000, app, use_debugger=True, use_reloader=True) + +Summary +~~~~~~~ + +So far, all of the code should look like this: + +.. code-block:: python + + from rest_api_framework import models + from rest_api_framework.datastore import SQLiteDataStore + from rest_api_framework.views import JsonResponse + from rest_api_framework.controllers import Controller + + + class UserModel(models.Model): + + fields = [models.StringField(name="first_name", required=True), + models.StringField(name="last_name", required=True), + models.PkField(name="id", required=True) + ] + + + class UserEndPoint(Controller): + ressource = { + "ressource_name": "users", + "ressource": {"name": "adress_book.db", "table": "users"}, + "model": UserModel, + "datastore": SQLiteDataStore + } + + controller = { + "list_verbs": ["GET", "POST"], + "unique_verbs": ["GET", "PUT", "DElETE"] + } + + view = {"response_class": JsonResponse} + + if __name__ == '__main__': + from werkzeug.serving import run_simple + from rest_api_framework.controllers import WSGIDispatcher + app = WSGIDispatcher([UserEndPoint]) + run_simple('127.0.0.1', 5000, app, use_debugger=True, use_reloader=True) + +Next: :doc:`using_user_endpoint` diff --git a/docs/build/_sources/using_user_endpoint.txt b/docs/build/_sources/using_user_endpoint.txt new file mode 100644 index 0000000..c797111 --- /dev/null +++ b/docs/build/_sources/using_user_endpoint.txt @@ -0,0 +1,62 @@ +Playing with the newly created endpoint +======================================= + +First you can check that your endpoint is up + +.. code-block:: bash + + curl -i "http://localhost:5000/users/" + + HTTP/1.0 200 OK + Content-Type: application/json + Content-Length: 2 + Server: Werkzeug/0.8.3 Python/2.7.2 + Date: Mon, 14 Oct 2013 12:52:22 GMT + +Your endpoint is responding but does not have any data. Let's add +some: + +Create a user +------------- + +.. code-block:: bash + + curl -i -H "Content-type: application/json" -X POST -d '{"first_name":"John", "last_name": "Doe"}' http://localhost:5000/users/ + + HTTP/1.0 201 CREATED + Location: http://localhost:5000/users/1 + Content-Type: application/json + Content-Length: 0 + Server: Werkzeug/0.8.3 Python/2.7.2 + Date: Mon, 14 Oct 2013 13:00:13 GMT + +Error handling +~~~~~~~~~~~~~~ + +If you don't provide a last_name, the API will raise a BAD REQUEST +explaining your error: + +.. code-block:: bash + + curl -i -H "Content-type: application/json" -X POST -d '{"first_name":"John"}' http://localhost:5000/users/ + + HTTP/1.0 400 BAD REQUEST + Content-Type: application/json + Content-Length: 62 + Server: Werkzeug/0.8.3 Python/2.7.2 + Date: Mon, 14 Oct 2013 13:21:10 GMT + + {"error": "last_name is missing. Cannot create the ressource"} + +The same apply if you dont give coherent data: + +.. code-block:: bash + + curl -i -H "Content-type: application/json" -X POST -d '{"first_name":45, "last_name": "Doe"}' http://localhost:5000/users/ + + HTTP/1.0 400 BAD REQUEST + Content-Type: application/json + Content-Length: 41 + Server: Werkzeug/0.8.3 Python/2.7.2 + Date: Mon, 14 Oct 2013 13:24:53 GMT + {"error": "first_name does not validate"} diff --git a/docs/build/datastore.html b/docs/build/datastore.html index 545d844..44a159b 100644 --- a/docs/build/datastore.html +++ b/docs/build/datastore.html @@ -24,8 +24,8 @@ - - + +