#StackBounty: #python #python-3.x #mvc #url-routing Python (Sanic) Routing

Bounty: 50

I am new to Python and wanted to explore how I can associate routes with “controllers” with Sanic as a base. It works fine but “feels” a bit clunky but I can’t put my finger on why/how.

routes.py – Returning controller methods from a given route

from .index import IndexRoutes
from .clients import ClientRoutes
from Controllers.IndexController import *
from Controllers.ClientController import *


def add_routes(app):
    routes = get_routes()

    for route in routes:
        for m in route['methods']:
            controller = m['controller']
            method = m['method']

                eval(controller + '.' + method),
                route['prefix'] + m['path'],

def get_routes():
    routes = []

    for c in CLASSES:
        methods = getattr(c, 'ROUTE_METHODS')

        route = {
            'name': getattr(c, 'ROUTE_NAME'),
            'methods': [],
            'prefix': getattr(c, 'ROUTE_PREFIX')

        for method in methods:
            route['methods'].append(getattr(c, method)())


    return routes

client.py – Example of route definitions

class ClientRoutes:
    ROUTE_NAME = 'clients'
    ROUTE_METHODS = ['index', 'create', 'update', 'single', 'destroy']
    ROUTE_PREFIX = 'clients'

    def index():
        return {
            'controller': 'ClientController',
            'method': 'index',
            'path': '/',
            'request_methods': ['GET']

    def create():
        return {
            'controller': 'ClientController',
            'method': 'create',
            'path': '/',
            'request_methods': ['POST']

    def single():
        return {
            'controller': 'ClientController',
            'method': 'single',
            'path': '/<id>',
            'request_methods': ['GET']

    def update():
        return {
            'controller': 'ClientController',
            'method': 'update',
            'path': '/<id>',
            'request_methods': ['PUT']

    def destroy():
        return {
            'controller': 'ClientController',
            'method': 'destroy',
            'path': '/<id>',
            'request_methods': ['DELETE']

ClientController.py – Example of controller

from sanic import response
from Database.Model import Model
from Database.Client import Client
from Helpers.transformers import to_dict

class ClientController:

    async def index(request):
        clients = Model(Client)
        return response.json(to_dict(clients.get()))

    async def create(request):
        data = request.json
            if 'name' not in data:
                raise KeyError('Name is required')
                if len(data['name']) < 1:
                    raise ValueError('Name is required')
        except KeyError as e:
            return response.json(str(e), 400)
        except ValueError as e:
            return response.json(str(e), 400)

        client = Model(Client)
        return response.json(to_dict(client.save(data)))

        # ... Other methods below, unnecessary for this example

Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.