Mon API est en cours de construction pour permettre aux développeurs d'étendre ses fonctionnalités. Mon plan est de le faire en fournissant un répertoire "extensions" où ils peuvent déposer des Blueprints et ils seront chargés dynamiquement. Ceci est le code que j'utilise pour importer (modifié à partir de cela tutoriel )
from flask import Flask
import pkgutil
import sys
app = Flask(__name__)
EXTENSIONS_DIR = "extensions"
modules = pkgutil.iter_modules(path=[EXTENSIONS_DIR])
for loader, mod_name, ispkg in modules:
if mod_name not in sys.modules:
# It imports fine
loaded_mod = __import__(EXTENSIONS_DIR+"."+mod_name+"."+mod_name, fromlist=[mod_name])
# It does not register
app.register_blueprint(loaded_mod)
Ceci est la disposition du répertoire de mon projet. Le répertoire extensions
est l'endroit où les développeurs ajoutent leurs fonctionnalités étendues.
/root
/extensions
/extension1
__init__.py
extension1.py
/extension2
__init__.py
extension2.py
simple_example.py
Le problème est que j'obtiens cette erreur et je ne suis pas sûr de ce qu'elle me dit.
>python simple_example.py
Traceback (most recent call last):
File "simple_example.py", line 14, in <module>
app.register_blueprint(loaded_mod)
File "C:\Python27\lib\site-packages\flask\app.py", line 62, in wrapper_func
return f(self, *args, **kwargs)
File "C:\Python27\lib\site-packages\flask\app.py", line 880, in register_blueprint
if blueprint.name in self.blueprints:
AttributeError: 'module' object has no attribute 'name'
Une simple extension ressemble à ceci
from flask import Blueprint
extension1 = Blueprint('extension1', __name__)
@extension1.route("/my_route")
def treasure_list():
return "list of objects"
Comment résoudre le AttributeError
d'une manière qui permet à mon app.register_blueprint
appel à réussir?
Vous essayez d'enregistrer module et non l'objet Blueprint
contenu.
Vous devrez introspecter le module pour trouver des instances de Blueprint
à la place:
if mod_name not in sys.modules:
loaded_mod = __import__(EXTENSIONS_DIR+"."+mod_name+"."+mod_name, fromlist=[mod_name])
for obj in vars(loaded_mod).values():
if isinstance(obj, Blueprint):
app.register_blueprint(obj)
Quand j'ai eu cette erreur, mon code ressemblait à ceci:
from blueprints import api
...
app.register_blueprint(api)
J'ai corrigé cela en faisant ceci:
app.register_blueprint(api.blueprint)
J'ai également connu le même effet dans un projet. L'origine du problème était une importation incorrecte du fichier de plan.
Assurez-vous que l'instruction import importe le plan réel et non le module sur lequel il est défini.
En d'autres termes, vous faites peut-être
from .blueprint import blueprint
pendant que tu voulais dire
from .blueprint.blueprint import blueprint
En guise de recommandation secondaire, nommez le module sur lequel le plan directeur est défini avec un nom différent du plan directeur lui-même, afin de clarifier l'importation. Un exemple:
from .blueprint.views import blueprint
J'importais directement le plan directeur from flask import Flask
. J'ai résolu cette erreur en installant flask à nouveau en utilisant pip3 install flask
. Parfois, si la version flask est supérieure ou égale à 0,12,3, vous pourriez face à ce problème.