Tutorial¶
The main feature of pyrocumulus is automatic create restful APIs for mongodb documents. Let’t try it!
Creating a new project¶
First, create a new project using the pyrocumulus command in your command line:
$ pyrocumulus createproject ~/pyrotut
$ cd ~/pyrotut
Writing your models with mongoengine¶
In this tutorial, we’ll use the same models used on mongoengine tutorial. So, in the file pyrotut/models.py, write these models:
from mongoengine import Document, EmbeddedDocument
from mongoengine.fields import (StringField, ReferenceField, IntField,
EmbeddedDocumentField, ListField)
class User(Document):
email = StringField(required=True)
first_name = StringField(max_length=50)
last_name = StringField(max_length=50)
class Comment(EmbeddedDocument):
content = StringField()
name = StringField(max_length=120)
class Post(Document):
title = StringField(max_length=120, required=True)
# reverse_delete_rule=CASCADE
authors = ListField(ReferenceField(User, reverse_delete_rule=2))
tags = ListField(StringField(max_length=30))
comments = ListField(EmbeddedDocumentField(Comment))
meta = {'allow_inheritance': True}
class TextPost(Post):
content = StringField()
class ImagePost(Post):
image_path = StringField()
class LinkPost(Post):
link_url = StringField()
Configuring the restful api¶
Using the models we created earlier, lets create a pyrocumulus.web.applications.RestApplication instance.
In the file pyrotut/web.py, write the following code:
from pyrocumulus.web.applications import RestApplication
from pyrotut.models import User, TextPost, LinkPost, ImagePost
simple_blog_api = RestApplication(User, TextPost, LinkPost, ImagePost)
And that’s it. You have a rest API for your documents.
Setting up config¶
Before we run our application, we need to set up some config variables. So, in the file settings.py, change your database settings and the APPLICATIONS variable
PROJECT_NAME = 'pyrotut'
TORNADO_PORT = 8888
DATABASE = {'default': {'HOST': 'localhost',
'PORT': 27017,
'NAME': 'pyrotut'}}
# list of applications to be served by tornado
APPLICATIONS = ['pyrotut.web.simple_blog_api',]
And that’s it. We have a new project created. Now, let’s try out something.
Testing the API¶
For testing, we’ll use the package requests, so, install it.
$ pip install requests
Now, is time to test our api, but first, lets see which url were mapped by our RestApplication.
>>> from pyrotut.web import application
>>> application.urls
[('/api/user/(.*)', ...),
('/api/textpost/comments/(.*)', ...),
('/api/textpost/(.*)', ...),
('/api/linkpost/comments/(.*)', ...),
('/api/linkpost/(.*)', ...),
('/api/imagepost/comments/(.*)', ...),
('/api/imagepost/(.*)', ...)]
>>>
As we can see, pyrocumulus.web.applications.RestApplication creates a url for each one of our Documents, and URLs for its EmbeddedDocuments too. Then, we can send HTTP requests to it and use our automatic api.
So, first, lets run a instance of the tornado web server and then open a Python shell and test our application.
$ python pyromanager.py runtorando --daemonize
$ python
Now, inside the python shell, we can start sending requests to our application
>>> import requests
>>> # base url for api
>>> base_url = 'http://localhost:8888/api/'
>>> user_url = base_url + 'user/'
>>> post_url = base_url + 'textpost/'
>>> comments_url = post_url + 'comments/'
First, create a user to be the posts’ author
>>> user_email = 'user@email.com'
>>> first_name = 'user'
>>> last_name = 'niceGuy'
>>> params = {'email': user_email,
... 'first_name': first_name,
... 'last_name': last_name}
...
>>> response = requests.put(user_url, params)
>>> response.connection.close()
>>> user_id = response.json()['id']
>>> user_id
'52ba237a7c1c8452919d03f8'
Now, create a post using the user created earlier
>>> post_title = 'My First Post'
>>> post_content = """Mussum ipsum cacilds, vidis litro abertis. """
>>> params = {'title': post_title,
... 'content': post_content,
... 'tags': ['pyrotut', 'pyrocumulus', 'mussum'],
... 'authors': [user_id]}
...
>>> response = requests.put(post_url, params)
>>> response.connection.close()
>>> post_id = response.json()['id']
>>> post_id
'52ba23be7c1c8452919d03f9'
And then, make a comment!
>>> comment_name = 'john doe'
>>> comment_content = 'bla bla bla...'
>>> params = {'name': comment_name,
... 'content': comment_content,
... 'parent_id': post_id}
...
>>> response = requests.put(comments_url, params)
>>> response.connection.close()
>>> response = requests.get(post_url, params={'id': post_id})
>>> response.connection.close()
post_content = response.json()['content']
>>> print(post_content)
Mussum ipsum cacilds, vidis litro abertis.
>>> post_comments = response.json()['comments']
>>> post_comments
[{'name': 'john doe', 'content': 'bla bla bla...'}]
That’s it. We created a user, a post and then sent a comment to that post. When retrieving the post, we get the comments list together, because our handler has as default depth the value 1. If you want only the comments list, to paginate them, you can use:
>>> requests.get(comments_url + 'list', params={'parent_id': post_id,
... 'page': 1, 'max': 10})