项目作者: ashleysommer

项目描述 :
A Dispatcher extension for Sanic which also acts as a Sanic-to-WSGI adapter
高级语言: Python
项目地址: git://github.com/ashleysommer/sanic-dispatcher.git
创建时间: 2017-03-13T03:43:01Z
项目社区:https://github.com/ashleysommer/sanic-dispatcher

开源协议:MIT License

下载


Sanic-Dispatcher

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

Allows you to do this: (seriously)

  1. from sanic import Sanic, response
  2. from sanic_dispatcher import SanicDispatcherMiddlewareController
  3. from flask import Flask, make_response, current_app as flask_app
  4. app = Sanic(__name__)
  5. dispatcher = SanicDispatcherMiddlewareController(app)
  6. child_sanic_app = Sanic("MyChildSanicApp")
  7. child_flask_app = Flask("MyChildFlaskApp")
  8. @app.middleware("response")
  9. async def modify_response(request, response):
  10. response.body = response.body + b"\nModified by Sanic Response middleware!"
  11. response.headers['Content-Length'] = len(response.body)
  12. return response
  13. @app.route("/")
  14. async def index(request):
  15. return response.text("Hello World from {}".format(request.app.name))
  16. @child_sanic_app.route("/")
  17. async def index(request):
  18. return response.text("Hello World from {}".format(request.app.name))
  19. @child_flask_app.route("/")
  20. def index():
  21. app = flask_app
  22. return make_response("Hello World from {}".format(app.import_name))
  23. dispatcher.register_sanic_application(child_sanic_app, '/sanicchild', apply_middleware=True)
  24. dispatcher.register_wsgi_application(child_flask_app.wsgi_app, '/flaskchild', apply_middleware=True)
  25. if __name__ == "__main__":
  26. app.run(port=8001, debug=True)

Installation

  1. pip install Sanic-Dispatcher

How To Use

First make a Sanic application the way you normally do:

  1. from sanic import Sanic
  2. 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

  1. from sanic_dispatcher import SanicDispatcherMiddlewareController
  2. 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

  1. app = Sanic(__name__)
  2. dispatcher = SanicDispatcherMiddlewareController(app)
  3. otherapp = Sanic("MyChildApp")
  4. dispatcher.register_sanic_application(otherapp, "/childprefix")
  5. @otherapp.route('/')
  6. async def index(request):
  7. 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?

  1. from flask import Flask, make_response
  2. app = Sanic(__name__)
  3. dispatcher = SanicDispatcherMiddlewareController(app)
  4. flaskapp = Flask("MyFlaskApp")
  5. # register the wsgi_app method from the flask app into the dispatcher
  6. dispatcher.register_wsgi_application(flaskapp.wsgi_app, "/flaskprefix")
  7. @flaskapp.route('/')
  8. def index():
  9. 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?

  1. import my_django_app
  2. app = Sanic(__name__)
  3. dispatcher = SanicDispatcherMiddlewareController(app)
  4. # register the django wsgi application into the dispatcher
  5. dispatcher.register_wsgi_application(my_django_app.wsgi.application,
  6. "/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.

  1. app = Sanic(__name__)
  2. dispatcher = SanicDispatcherMiddlewareController(app)
  3. otherapp = Sanic("MyChildApp")
  4. dispatcher.register_sanic_application(otherapp, "/childprefix")
  5. @app.route('/')
  6. async def index(request):
  7. return response.text("Hello World from Default App")
  8. @otherapp.route('/')
  9. async def index(request):
  10. 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!

  1. import my_django_app
  2. from flask import Flask, make_response, current_app
  3. app = Sanic(__name__)
  4. dispatcher = SanicDispatcherMiddlewareController(app)
  5. child_sanic_app = Sanic("MyChildSanicApp")
  6. child_flask_app = Flask("MyChildFlaskApp")
  7. @app.middleware("request")
  8. async def modify_request(request):
  9. request.headers['Content-Type'] = "text/plain"
  10. @app.middleware("response")
  11. async def modify_response(request, response):
  12. response.body = response.body + b"\nModified by Sanic Response middleware!"
  13. response.headers['Content-Length'] = len(response.body)
  14. return response
  15. @app.route("/")
  16. async def index(request):
  17. return response.text("Hello World from {}".format(request.app.name))
  18. @child_sanic_app.route("/")
  19. async def index(request):
  20. return response.text("Hello World from {}".format(request.app.name))
  21. @child_flask_app.route("/")
  22. def index():
  23. app = current_app
  24. return make_response("Hello World from {}".format(app.import_name))
  25. dispatcher.register_sanic_application(child_sanic_app,
  26. '/childprefix', apply_middleware=True)
  27. dispatcher.register_wsgi_application(my_django_app.wsgi.application,
  28. '/djangoprefix', apply_middleware=True)
  29. dispatcher.register_wsgi_application(child_flask_app.wsgi_app,
  30. '/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.