I'd like to split my app into multiple independent modules:
# datascience/service/ham/app.py
from sanic import Sanic
from sanic.response import json
app = Sanic()
@app.route("/")
async def test(request):
return json({"hello": "world"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
# datascience/service/app.py
from sanic import Sanic
from datascience.service.spam.app import app as spam_app
from datascience.service.ham.app import app as ham_app
app = Sanic()
app.route("/", spam_app)
app.route("/test", ham_app)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
this way /test/ -> datascience.service.ham.app.test
Why not use two blueprints, one in each module, then have one parent script that imports and runs them both?
@r0fls It's also not as elegant as app composition:
Nestable apps exist in frameworks like Express or WSGI applications
One solution could be to recursively import submodules using something similar to:
def import_all_submodules(module):
if isinstance(module, basestring):
module = importlib.import_module(module)
for _, modname, _ in pkgutil.walk_packages(
path=module.__path__,
prefix=module.__name__ + '.',
onerror=lambda x: None):
__import__(modname, fromlist=[])
@seemethere that looks like dark magic
@graingert I mean I had to sacrifice a goat to write it so it basically is 👿
And it's not really what I want. I still want to import the apps I need explicitly
Yeah judging from the usage example you provided I would say you are describing a Blueprint.
Maybe there needs to be an extension to the Blueprint's functionality in order to meet your needs?
Can you install a blueprint in a blueprint?
I mean the functionality could be there if wanted
@graingert
I only just came across this issue. If you do not want to use Blueprints, this is the perfect use-case for the Dispatcher extension (shameless plug, I am the author).
There is even an example in the readme showing how to do what you want.
You can think of the Dispatcher as a kind of pre-router that has the ability to route to other Sanic apps, or even to Flask apps. It can also do its own middleware, so it can apply request middleware before sending it to a sub-app, and it can apply response middleware after receiving the response from the sub-app.
Github page is here: https://github.com/ashleysommer/sanic-dispatcher
You could mimic a django like approach. Check out the add_routes method: https://github.com/danpozmanter/jawaf/blob/master/jawaf/server.py
You basically use a config file to specify which apps you explicitly want to include. (The way I've done it, it works with apps in the project directory, as well as any apps installed as python packages that have a routes.py and views.py defined). But you could roll it a few ways depending on what you want to build.
Hey @graingert
It seems like I've implemented something you talking about.
Sanic-router - is a simple, django-like route controller.
There are multiple solutions for this now and if blueprints are an option, nested blueprints are in the current release.
Most helpful comment
@seemethere that looks like dark magic