Skip to content

Latest commit

 

History

History
295 lines (221 loc) · 9.74 KB

README.md

File metadata and controls

295 lines (221 loc) · 9.74 KB

Morepath RealWorld Example App

Morepath codebase containing real world examples (CRUD, auth, advanced patterns, etc) that adheres to the RealWorld spec and API.

This codebase was created to demonstrate a fully fledged fullstack application built with Morepath, using Pony object-relational mapper, including CRUD operations, authentication, routing, pagination, and more.

We've gone to great lengths to adhere to the Morepath community styleguides & best practices.

For more information on how to this works with other frontends/backends, head over to the RealWorld repo.

A demo conduit-morepath backend server is running at https://conduit.yacoma.it/api.

Getting started

Clone this repo and adjust the settings in the settings folder. Remember to change the master_secret.

From inside the project directory create a clean Python environment with virtualenv and activate it:

$ virtualenv -p python3 env
$ source env/bin/activate

After this you can install the package including dependencies using:

(env) $ pip install -Ue .

Once that is done you can start the server:

(env) $ gunicorn conduit.run

You can access the conduit server at http://localhost:8000/api.

You can also start the server on another host/port:

(env) $ gunicorn --bind=example.com:3000 conduit.run

Code Overview

Dependencies

Application Structure

The core application under the conduit folder contains:

  • run.py - The entry point to our application. It sets up the database and provides a WSGI factory which can be used by a WSGI HTTP Server like gunicorn to run the application.
  • app.py - Sets up the core App and merges the AuthApp, the BlogApp and the PonyApp from more.pony in by subclassing from them. It also creates a ProductionApp and a TestApp, which are used instead depending on the RUN_ENV environment variable.
  • permissions.py - Sets up the permissions and permission rules used to protect the views.
  • database.py - Just creates an instance of the PonyORM Database.
  • error_view.py - Defines the handling of the Cerberus ValidationError. For details see below.
  • utils.py - Some utility scripts. Here for transforming from datetime to ISO format and back.
  • auth/ - Folder contains the AuthApp.
  • blog/ - Folder contains the BlogApp.
  • settings/- Folder contains the default settings and the settings for production and testing in YAML format.
  • test/ - Folder contains the unit tests.

The subapplication folders auth/ and blog/ contain:

  • app.py - Defines the App.
  • model.py - Creates the models extended from PonyORM's db.Entity.
  • collection.py- Sets up the collection models.
  • path.py - Defines the paths depending on the model.
  • view.py - Creates the views depending on the model.
  • schema.yml - Contains the schemas used by Cerberus in YAML format.
  • validator.py - Contains custom validators used by Cerberus (only in auth).

Error Handling

For validating the incoming JSON data on requests we use Cerberus. The Cerberus schemas are defined in schema.yml inside the app folders (auth/ and blog/). You can also add custom validators, e.g. the EmailValidator defined in auth/validator.py.

Cerberus returns an ValidationError. How to handle the response including returning a 422 status code and formatting the view is defined in error_view.py.

Authentication

We use the Morepath identity policy provided by more.jwtauth which allows authentication of request through the JWT token in the Authorization header.

Testing

For installing the test suite and running the tests use:

(env) $ pip install -Ur requirements/develop.txt
(env) $ py.test

To check for test coverage:

(env) $ py.test --cov

The example App ships with 100% test coverage.

To check if your code is conform with PEP8:

(env) $ flake8 conduit setup.py

You can also run tox locally if you have installed Python 3.5 or/and Python 3.6:

(env) $ tox

Install pre-commit hook for Black integration

We're using Black for formatting the code and it's recommended to install the pre-commit hook for Black integration before committing:

$ pre-commit install

Black

To format the code with the Black Code Formatter run in the root directory:

$ black .

Black has also integration for the most popular editors.

Deployment

Requirements for the server

On Debian/Ubuntu you can install them as superuser with:

$ apt-get install nginx supervisor make

Overview

We use a post-receive git hook to publish the repository on the production server. He triggers on every push to the git repo on the server.

The post-receive hook uses the path defined in the prod_path variable. Make sure that this path exists on the server before pushing the first time.

The hook triggers make deploylive which is defined in Makefile. This install the dependencies and build the App.

Configuration

The deploy/conf directory contains samples for git hook and server configuration with gunicord behind a nginx reverse proxy. For monitoring and controlling gunicord we use supervisor.

  • git/hooks/post-receive - put this in the hooks directory of your bare git repository on the server and make sure it is executable.
  • web/nginx.conf - the nginx configuration.
  • web/supervisord.conf - the supervisor configuration for gunicorn.
  • web/gunicorn.sample.conf.py - Gunicorn configuration, should be moved to web/gunicorn.sample.py after configuring.

The samples have to be configured by replacing the placeholders indicated by [PLACEHOLDER].

The following placeholders are used:

  • [PATH TO APP] - absolute path to the app folder on the server
  • [IP] - IP address of the server
  • [PORT] - port on which the Gunicorn WSGI server should run (remember to open this TCP port in your firewall)
  • [SERVERNAME] - servername which is normally the base URL of the server
  • [PATH TO LOG] - absolute path to HTTP log without file extension
  • [PATH TO GUNICORN LOG] - absolute path to Gunicorn log without file extension
  • [PATH TO CERTIFICATE] - absolute path to SSL certificate file
  • [PATH TO CERTIFICATE KEY] - absolute path to SSL certificate key file
  • [PATH TO CLIENT APP] - absolute path to client app you want to serve

Serve a conduit client together with the backend

Optionally you can also serve a conduit client like the Cerebral Example App together with the Morepath backend.

  • In nginx.conf add a root location with the path to your client build. It can be in a different directory then the Morepath backend.
  • Add a post-receive git hook to your client repo similar to the one we use for the backend.
      #!/bin/bash
      #
      set -x
      app_path="[PATH TO CLIENT APP]"
    
      while read oldrev newrev ref
      do
              branch=`echo $ref | cut -d/ -f3`
              if [[ "master" == "$branch" ]]; then
                      git --work-tree=$app_path checkout -f $branch
                      cd $app_path
                      make deploylive
                      echo 'Changes pushed live.'
              fi
      done
  • Create a simple Makefile to build the client. Remember to put a tab character at the beginning of every recipe line!
      .PHONY:	deploylive
      deploylive:
      	rm -rf node_modules
      	npm install
      	npm run build

Database

PonyORM supports SQLite, PostgreSQL, MySQL/MariaDB and Oracle. In the example App we use Postgres in production and SQLite for development and testing.

When you want to use another database then SQLite you have to first create a database for conduit-morepath on the server.

Then configure conduit/settings/production.yml according to the database setup.