Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Blueprint pre-registration #2340

Open
ahopkins opened this issue Dec 14, 2021 · 1 comment
Open

RFC: Blueprint pre-registration #2340

ahopkins opened this issue Dec 14, 2021 · 1 comment
Labels

Comments

@ahopkins
Copy link
Member

ahopkins commented Dec 14, 2021

Background

I see a lot of developers getting stuck because of import ordering. This usually happens because of a mistake in trying to import a module with reference to the application before the application has actually been created.

While I think there are some helpful patterns to avoid this (factories, late imports, etc), it might also be helpful to provide a little leeway. This PR is meant to add the ability for a Blueprint to declare its application up front.

Then, as long as that module has been imported somewhere, it will automatically be registered when the application starts up.

What it would look like

# some.other.module
bp = Blueprint("SomeBP")
bp.pre_register("SomeAppName")
# anywhere
import some.other.module

This could be simplified, and made to look similar to the Sanic.get_app pattern. In this example, we call Sanic.lazy, which will return a preregistered Blueprint object.

# some.other.module
from sanic import Sanic

app = Sanic.lazy("SomeApp")


@app.before_server_start
async def before_server_start(app: Sanic, _):
    ...


@app.get("/foo")
async def get(_):
    ...
# server
import some.other.module

app = Sanic("SomeApp")

Taking it further

We also can borrow the pattern from Sanic.get_app() and use the only application instance (if there is only one). This would allow:

lazy_app = Sanic.lazy()

If this is the case, then it would be natural--and highly likely--that someone may attempt the run the application from that lazily created Blueprint. We could allow that by simply creating a basic application instance for them at startup.

$ sanic path.to.server:lazy_app

I am myself still undecided on this last bit. It seems logical and convenient, but I have not fully thought thru the issue.

Potential PR implementation

See PR #2339

@ahopkins
Copy link
Member Author

Another thought...

When Sanic.lazy is used without a name, the implied blueprint name should use the current module's name:

name = inspect.getmodulename(inspect.stack()[1].filename)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant