Pluckerpluck
Pluckerpluck

Reputation: 731

Running Flask from an imported module

I'm trying to run Flask from an imported module (creating a wrapper using decorators).

Basically I have:

app.py:

import mywrapper

@mywrapper.entrypoint
def test():
    print("HEYO!")

mywrapper.py

from flask import Flask

ENTRYPOINT = None

app = Flask(__name__)

@app.route("/")
def listen():
    """Start the model API service"""
    ENTRYPOINT()


def entrypoint(f):
    global ENTRYPOINT
    ENTRYPOINT = f
    return f

FLASK_APP=app

Running python -m flask, however, results in:

flask.cli.NoAppException: Failed to find Flask application or factory in module "app". Use "FLASK_APP=app:name to specify one.


Is there any trick to getting Flask to run like this? Or is it just not possible? The purpose of this is to abstract Flask away in this situation.

In my head flask should try to import mywrapper.py, which imports app.py which should generate the app and route, yet this doesn't seem to be what occurs.

Any help would be appreciated.

Upvotes: 0

Views: 797

Answers (1)

Pluckerpluck
Pluckerpluck

Reputation: 731

So I've since learnt that Flask searches only in the chosen module's namespace for a variable containing a Flask object.

There may be a smart way to avoid this limitation, but I instead decided that it was more sensible to instead just wrap the Flask class itself. If people want direct Flask functionality, I don't really care in this situation, so the only real limitation I have from this is some function names are off limits.

Basically:

wrapper.py:

class Wrapper(Flask):
    def __init__(self, name):
        super().__init__(name)
        self.entrypoint_func = None

        @self.route("/")
        def listen():
            return self.entrypoint_func()

    def entrypoint(self, f):
        assert self.entrypoint_func is None, "Entrypoint can only be set once"

        self.entrypoint_func = f
        return f

and app.py:

from mywrapper import Wrapper

app = Wrapper(__name__)

@app.entrypoint
def test():
    print("HEYO!")
    return "SUCCESS"

This is still abstracted enough that I am happy with the results.

Upvotes: 1

Related Questions