All Projects → ashleysommer → Sanic Dispatcher

ashleysommer / Sanic Dispatcher

Licence: mit
A Dispatcher extension for Sanic which also acts as a Sanic-to-WSGI adapter

Programming Languages

python
139335 projects - #7 most used programming language
python3
1442 projects

Projects that are alternatives of or similar to Sanic Dispatcher

Sanic Cors
A Sanic extension for handling Cross Origin Resource Sharing (CORS), making cross-origin AJAX possible. Based on flask-cors by Cory Dolphin.
Stars: ✭ 143 (+393.1%)
Mutual labels:  sanic, plugin
Multicorn
Multicorn is a multi-interpreter server for Python.
Stars: ✭ 27 (-6.9%)
Mutual labels:  wsgi
Sass Webpack Plugin
[Deprecated] 🌈 Get your stylesheets together
Stars: ✭ 14 (-51.72%)
Mutual labels:  plugin
Codeception Mailtrap
Codeception module to test email using Mailtrap.io
Stars: ✭ 15 (-48.28%)
Mutual labels:  plugin
Vimnavigation
Vim style keyboard navigation.
Stars: ✭ 14 (-51.72%)
Mutual labels:  plugin
Pmpro Addon Packages
Charge for access to specific pages or other post types in WordPress. Requires the Paid Memberships Pro plugin.
Stars: ✭ 20 (-31.03%)
Mutual labels:  plugin
Remember Last Position Totem Plugin
Totem video player plugin that restores position in the last played file
Stars: ✭ 13 (-55.17%)
Mutual labels:  plugin
Mpv Reload
mpv plugin for automatic reloading of slow/stuck video streams
Stars: ✭ 29 (+0%)
Mutual labels:  plugin
Vue Lazy Component
🐌 Vue.js 2.x 组件级懒加载方案-Vue.js 2.x component level lazy loading solution
Stars: ✭ 915 (+3055.17%)
Mutual labels:  plugin
Hammerspoon Alttab
Stars: ✭ 15 (-48.28%)
Mutual labels:  plugin
Craft3 Iconpicker
Craft plugin that provides a new field type that offers end users an easy way to pick an icon from a .woff or .ttf font file. You can easily use ionicons or font awesome icons or any other compatible font file.
Stars: ✭ 15 (-48.28%)
Mutual labels:  plugin
Interfacetable v3t
interfacetable_v3t (formerly check_interface_table_v3t)
Stars: ✭ 14 (-51.72%)
Mutual labels:  plugin
Transport Pipes
Buildcraft without mods!
Stars: ✭ 21 (-27.59%)
Mutual labels:  plugin
Openiterm2
Opening iTerm2 in the current directory.
Stars: ✭ 14 (-51.72%)
Mutual labels:  plugin
Eslint Plugin Security Node
ESLint security plugin for Node.js
Stars: ✭ 28 (-3.45%)
Mutual labels:  plugin
Lein Fore Prob
A leiningen plugin to make a local copy of a problem from 4clojure
Stars: ✭ 13 (-55.17%)
Mutual labels:  plugin
Hyper Match
HyperTerm extension which matches regular expressions with predefined commands
Stars: ✭ 15 (-48.28%)
Mutual labels:  plugin
Mysimbl
📦 Plugin manager for macOS
Stars: ✭ 909 (+3034.48%)
Mutual labels:  plugin
Eslint Import Resolver Jest
🃏 Jest import resolution plugin for eslint-plugin-import
Stars: ✭ 29 (+0%)
Mutual labels:  plugin
Roundcube Thunderbird labels
Thunderbird Labels Plugin for Roundcube Webmail
Stars: ✭ 28 (-3.45%)
Mutual labels:  plugin

Sanic-Dispatcher

A Dispatcher extension for Sanic that also acts as a Sanic-to-WSGI adapter

Allows you to do this: (seriously)

from sanic import Sanic, response
from sanic_dispatcher import SanicDispatcherMiddlewareController
from flask import Flask, make_response, current_app as flask_app

app = Sanic(__name__)

dispatcher = SanicDispatcherMiddlewareController(app)

child_sanic_app = Sanic("MyChildSanicApp")

child_flask_app = Flask("MyChildFlaskApp")

@app.middleware("response")
async def modify_response(request, response):
    response.body = response.body + b"\nModified by Sanic Response middleware!"
    response.headers['Content-Length'] = len(response.body)
    return response

@app.route("/")
async def index(request):
    return response.text("Hello World from {}".format(request.app.name))

@child_sanic_app.route("/")
async def index(request):
    return response.text("Hello World from {}".format(request.app.name))

@child_flask_app.route("/")
def index():
    app = flask_app
    return make_response("Hello World from {}".format(app.import_name))

dispatcher.register_sanic_application(child_sanic_app, '/sanicchild', apply_middleware=True)
dispatcher.register_wsgi_application(child_flask_app.wsgi_app, '/flaskchild', apply_middleware=True)

if __name__ == "__main__":
    app.run(port=8001, debug=True)

Installation

pip install Sanic-Dispatcher

How To Use

First make a Sanic application the way you normally do:

from sanic import Sanic

app = Sanic(__name__) # This creates a sanic app

app becomes your 'base' or 'parent' sanic app which will accommodate the Dispatcher extension

Create a Dispatcher

from sanic_dispatcher import SanicDispatcherMiddlewareController

dispatcher = SanicDispatcherMiddlewareController(app)

dispatcher is your new dispatcher controller. Note: This takes a reference to app as its first parameter, but it does not consume app, nor does it return app.

I want to dispatch another Sanic App

app = Sanic(__name__)

dispatcher = SanicDispatcherMiddlewareController(app)

otherapp = Sanic("MyChildApp")

dispatcher.register_sanic_application(otherapp, "/childprefix")

@otherapp.route('/')
async def index(request):
    return response.text("Hello World from Child App")

Browsing to url /childprefix/ will invoke the otherapp App, and call the / route which displays "Hello World from Child App"

What if the other App is a Flask App?

from flask import Flask, make_response

app = Sanic(__name__)

dispatcher = SanicDispatcherMiddlewareController(app)
flaskapp = Flask("MyFlaskApp")

# register the wsgi_app method from the flask app into the dispatcher
dispatcher.register_wsgi_application(flaskapp.wsgi_app, "/flaskprefix")

@flaskapp.route('/')
def index():
    return make_response("Hello World from Flask App")

Browsing to url /flaskprefix/ will invoke the Flask App, and call the / route which displays "Hello World from Flask App"

What if the other App is a Django App?

import my_django_app

app = Sanic(__name__)

dispatcher = SanicDispatcherMiddlewareController(app)
# register the django wsgi application into the dispatcher
dispatcher.register_wsgi_application(my_django_app.wsgi.application,
                                     "/djangoprefix")

Browsing to url /djangoprefix/ will invoke the Django App.

Can I run a default application?

The Sanic App app you create at the start is also the default app.

When you navigate to a URL that does not match a registered dispatch prefix, this Sanic app will handle the request itself as per normal.

app = Sanic(__name__)

dispatcher = SanicDispatcherMiddlewareController(app)

otherapp = Sanic("MyChildApp")

dispatcher.register_sanic_application(otherapp, "/childprefix")

@app.route('/')
async def index(request):
    return response.text("Hello World from Default App")

@otherapp.route('/')
async def index(request):
    return response.text("Hello World from Child App")

Browsing to url / will not invoke any Dispatcher applications, so app will handle the request itself, resolving the / route which displays "Hello World from Default App"

I want to apply common middleware to the registered applications!

Easy!

import my_django_app
from flask import Flask, make_response, current_app

app = Sanic(__name__)

dispatcher = SanicDispatcherMiddlewareController(app)

child_sanic_app = Sanic("MyChildSanicApp")

child_flask_app = Flask("MyChildFlaskApp")

@app.middleware("request")
async def modify_request(request):
    request.headers['Content-Type'] = "text/plain"

@app.middleware("response")
async def modify_response(request, response):
    response.body = response.body + b"\nModified by Sanic Response middleware!"
    response.headers['Content-Length'] = len(response.body)
    return response

@app.route("/")
async def index(request):
    return response.text("Hello World from {}".format(request.app.name))

@child_sanic_app.route("/")
async def index(request):
    return response.text("Hello World from {}".format(request.app.name))

@child_flask_app.route("/")
def index():
    app = current_app
    return make_response("Hello World from {}".format(app.import_name))

dispatcher.register_sanic_application(child_sanic_app,
                                      '/childprefix', apply_middleware=True)
dispatcher.register_wsgi_application(my_django_app.wsgi.application,
                                     '/djangoprefix', apply_middleware=True)
dispatcher.register_wsgi_application(child_flask_app.wsgi_app,
                                     '/flaskprefix', apply_middleware=True)

The key here is passing apply_middleware=True to the relevant register application function. By default apply_middleware is set to False for all registered dispatcher applications.

In this example the Sanic Request Middleware modify_request will be applied to ALL requests, including those handled by applications registered on the dispatcher. The request middleware will be applied to the request before it is passed to any registered applications.

In this example the Sanic Response Middleware modify_response will be applied to ALL responses, including those which were generated by applications registered on the dispatcher. The response middleware will be applied to the response after it is processed by the registered application.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].