{"message": "article show", "http_status": 200, "prev": null, "next": null, "curr_user": null, "data": {"title": "Adding a handler ", "teaser": "Adding a handler for our todo list app", "text": "\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
As you know, all PythonOnWheels apps are Model-View-Controller (or MVC) based. Handler are the controllers in PythonOnWheels. Handlers give us a way to actually do something with our models. In PythonOnWheels they are also creating an API defined by routes which are accessible from the outside, mostly the web. In fact Models hold, store and retrieve the data and handlers hold the logic to deal with the data and make some of their methods and logic externally accessible. Which is your apps API.
Handlers are the brain of your app. They are where your applications logic goes. They create your app's API.
This might seem a little formal or buerocratic but in fact it's really easy. Just think of it like this. We defined a model to hold our todos data (if you have not created a todo model, please read Working with models (NoSQL) first). Remember it looks like this:
class Todo(TinyModel):
schema = {
'title': { 'type': 'string', 'maxlength' : 35 },
'text' : { 'type': 'string'},
'done' : { 'type': 'boolean', \"default\" : False },
\"votes\" : { \"type\" : \"integer\", \"default\" : 0 }
}
As always in PythonOnWheels we want to focus on what we want to do and get rid of the boilerplate. So we generate our handler using the generate_handler script. We give it the name todo and we need to say with which DB model we want to connect. The convention in PoW is that the handler uses the model with the same name. So we just give it the right DB type with -t tinydb. It will lok for models named todo but cannot know what DB you chose for that model. That's due to the fact that PoW supports many different DBs (even at the same time) ... So we point it to the right one. A model named todo (same as the handler) of type tinydb
python generate_handler.py -n todo -t tinydb --rest
We also added the --rest parameter to automatically create a standard REST API for our new handler. This makes working with PythonOnWheels so easy. Most probably you want to create, read, update and delete your data, maybe also show and list it ... And this is exactly what is now already prepared for you.
PythonOnWheels automatically creates a standard REST handler and API for you if you use the --rest parameter
The generated handler is nicely structured an consists of the methods you need to respond to the typical REST requests. You can see in the excerpt below the methods for show, list, page (list with pagination) edit and so on. There are many more things. As you can see some methods are access protected by default (edit). You can of course also create non REST handlers that just offer some specific routes, but we will cover this in more detail later. For now we are on the fast forward path.
You can also see the class decorator
@app.add_rest_routes(\"todo\")
This generates the REST routing which links the methods to actual REST URLs. Like this:
So what this really does is that it links any http GET request to the URL /todo to the list method of the todo handler.
So when you call http://localhost:8080/todo the todo.list() method will be called
Since this really now already works and we already have some todos we can actually start the server and send requests to our app.
python server.py
You should see the PythonOnWheels server starting. It will display information about the configured DBs and routes. It should look something like this:
We can see the REST routes for our todo handler starting from route number #20. But let's not focus on the boilerplate cause that's what PoW should take out of our sight and minds. (But it's good to know it's there and it's just standard routing)
We can now already access your todo handler (and models) on port 8080 (The default port configured in the config.py file)
Make sure that you have created a todo model before. Read: getting started part 1: how to create a model.
Open a new terminal (make sure you have curl installed) and execute the following curl command:
curl -H \"Accept: application/json\" -X GET http://localhost:8080/todo
Our PoW todo app should respond with the json formatted list of our todo models. Should look similar to this:
Or like this (if you haven't added any data so far..)
khz@~ $ curl -H \"Accept: application/json\" -X GET http://localhost:8080/todo
{\"message\": \"todo, index\", \"http_status\": 200, \"prev\": null, \"next\": null, \"data\": []}
\r\n
curl -H \"Content-Type: application/json\" -X POST -d \"{ \\\"title\\\" : \\\"best todo\\\" }\" http://localhost:8080/todo
(venv) khz@~/devel/pow_devel $ curl -H \"Content-Type: application/json\" -X POST -d \"{ \\\"title\\\" : \\\"best todo\\\" }\" http://localhost:8080/todo
{\"message\": \"todo, successfully created bceddeb6-3268-480f-8b57-080a5579d97f\", \"http_status\": 200, \"prev\": null, \"next\": null, \"data\": {\"title\": \"best todo\", \"text\": \"\", \"done\": false, \"id\": \"bceddeb6-3268-480f-8b57-080a5579d97f\", \"_uuid\": \"bceddeb6-3268-480f-8b57-080a5579d97f\", \"created_at\": \"2019-12-13 22:16:23\", \"last_updated\": \"2019-12-13 22:16:23\"}}(venv)
curl -H \"Accept: application/json\" -X GET http://localhost:8080/todo
(venv) khz@~/devel/pow_devel $ curl -H \"Accept: application/json\" -X GET http://localhost:8080/todo
{\"message\": \"todo, index\", \"http_status\": 200, \"prev\": null, \"next\": null, \"data\": {\"title\": \"best todo\", \"text\": \"\", \"done\": false, \"id\": \"c42a1ac3-0969-45b5-87d1-55c5a180550c\", \"_uuid\": \"c42a1ac3-0969-45b5-87d1-55c5a180550c\", \"created_at\": \"2019-12-13 22:11:57\", \"last_updated\": \"2019-12-13 22:11:57\"}}(venv)
But far more interesting is what we NOT needed to do
And we could really focus on our data/models and logic (REST for the moment). In the next articles we will see how to generate a web frontend with scaffolding and how to add our own methods to handlers.
Follow the last step in the getting started path and scaffold the web views for the todo application
Tweet some thoughts, questions or ideas for enhancements to @pythononwheels.
Send a tweet to @pythononwheels about it, both is very appreciated.
This is also the terminology used in tornado which builds the foundation of PythonOnWheels Web services. Tornado is great. It's not only a python webserver and template engine but also implements a fully blown asynchronous IOloop.