Skip to content

nghiattran/python-parse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

92 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status [Coverage percentage][coveralls-url]

#Python-parse Python API template for backend system using parse.com as database.

image

Generator    Roadmap    Basic command    API architecture   

#Generator-python-parse Now you can use Generator-python-parse to generate entire project and add custom API endpoint.

###Installation First, install Yeoman and generator-python-parse using npm (we assume you have pre-installed node.js).

npm install -g yo
npm install -g generator-python-parse

###Usage

yo python-parse				#To generate entire project
yo python-parse:app 		#To add an endpoint

#Road map

List of planning features:

  • Limit request per IP
  • Limit request per interval of time
  • Email automation
  • Social network integration
  • Integrate with yeoman

#Basic command

###Installation

# install all dependencies
bin/install

###Start

#start api at port 8000
bin/start

###Testing

# run tests
bin/test
# or run a specific test file
bin/test path/to/file

# run coverage
bin/cover

# clean up
bin/clean

#API architecture

bin
    \- install                          # install all dependencies
    \- start_redis                      # start redis
    \- start                            # start service   
    \- test                             # run tests
    \- cover                            # run coverage
    \- clean                            # clean coverage
app.py                                  # create app and set up endpoints 
src
    \- controllers                      
        \- __init__                     # set up controllers and their associates
        \- user_controller.py           # controller to handle user data
    \- forms
        \- __init__                     # set up base form
        \- user_form.py                 # form to handle user data
    \- models
        \- __init__                     # set up base model
        \- user_model.py                # model to handle user data
    \- utils
        \- __init__                     # utility functions
test
    \- live                             # branch for live tests
        \- integration                  # branch for integration test
            \- test_user.py             # tests for user_controller

#How to use

###Open an API endpoint

Example: open /users endpoint.

####1/ Create <endpoint_name>_form.py in this case user_form.py: This file plays as a filter for incomming data.

from wtforms import\
    StringField,\
    HiddenField,
from src.forms import \
    BaseGetForm,

class UserGetForm(BaseGetForm):
    username = StringField()
    password = HiddenField()

BaseGetForm is for filtering limit, count, keys, . . .

All accessible data need to be placed inUserGetForm or will be ignored. As in this case only username and password are included.

####2/ Create <endpoint_name>_model.py in this case user_model.py: This file is adding headers and sending requests to Parse.com.

from src.models.authentication_model import \
    generate_auth_token
from src.models import BaseModel

class UserModel(BaseModel):
    _parse_class_name = '_User'

    def user_signup(self, payload):
        res = self.signup(payload = payload)
        if 'error' not in res:
            res['token'] = generate_auth_token(res);
        return res

_parse_class_name specifies which class or table you want to access in database

BaseModel is for adding headers.

As you see, user_signup receives payload containing user's credentials and send request to Parse by calling res = self.signup(payload = payload)

If the request success, a session token will be added to 'res' by calling 'res['token'] = generate_auth_token(res);'

####3/ Add Base<endpoint_controller_name>.py in src/controllers/__init__.py:

from src.forms.user_form import\
    UserGetForm

class BaseUserController(BaseController):
    model = UserModel()
    get_form = UserGetForm

####4/ Create <endpoint_name>_controller.py in this case user_controller.py: This file plays as a request receiver and pass it to model.

import json
from src.controllers import\
    BaseUserController
from src.models.authentication_model import\
    requires_auth,\
    limit
    
class UsersController(BaseUserController):
    # Require authentication token
    @requires_auth
    # Limit number of requests per IP
    @limit(requests=100, window=30, by='ip', group=None)
    # Limit number of requests per second
    @limit(requests=30, window=1, by='parse', group='parse')
    def get(self):
        form = self.get_form()
        params = form.data

        res = self.model.get(
            collection='users',
            params=params)
        return res


class UserController(BaseUserController):
    @requires_auth
    @limit(requests=100, window=30, by='ip', group=None)
    @limit(requests=30, window=1, by='parse', group='parse')
    def get(self, object_id):
        where = {
            'objectId': object_id
        }
        params = {
            'where': json.dumps(where)
        }
        res = self.model.get(
            collection='users',
            params=params)
        return res

    @requires_auth
    @limit(requests=100, window=30, by='ip', group=None)
    @limit(requests=30, window=1, by='parse', group='parse')
    def put(self, object_id):
        form = self.put_form()
        payload = form.data

        res = self.model.put(
            collection='users',
            object_id=object_id,
            payload=payload,
            master_key=True)
        return res

@requires_auth will check if the request has authentication token. If not, return error.

@limit(requests=100, window=30, by='ip', group=None) if the number of requests sent from an IP to an endpoint group is greater than request_limit in time interval window. If it is, return error.

@limit(requests=30, window=1, by='parse', group='parse') if the number of requests exceed capability of the server. If it does, return error.

####5/ Create endpoint and its associate controller Just simply add the followings to app.py

api.add_resource(UsersController, 'users')
api.add_resource(UserController, 'users/<string:object_id>')

Where UsersController is the controller to handle users endpoint and UserController handles users/<string:object_id>.

#License    License

#Credits Kien Pham

[coveralls-url]: https://coveralls.io/r/nghiattran/python-parseiattran/LICENSE)

#Credits Kien Pham

About

API service to communicate with parse.com written in python

Resources

License

Stars

Watchers

Forks

Packages

No packages published