J'utilise flask_restful depuis un certain temps dans mon projet car j'aime séparer mes ressources en différents fichiers pour une organisation de base. Maintenant, je voudrais ajouter flask_caching et je suis tombé sur un (simple ?) problème d'importation circulaire

Ma structure de projet est comme ça

flask_api.py
-resources
--my_resource.py
--my_other_resource.py
--so_many_more_resources.py

Les points de terminaison de my_resources.py sont ajoutés dans flask_api.py, où je crée également l'objet flask_cache Cache, comme suit :

# flask_api.py
from flask import Flask
from flask_restful import Api
from flask_caching import Cache
from resources import my_resource
app = Flask(__name__)
cache = Cache(app, config={'sample config'})
api = Api(app)
api.add_resource(my_resource.GetStuff, '/api/v2/stuff/get')
# this file also runs the app

Je suis alors (en train d'essayer) d'importer le cache dans my_resource.py - où j'utilise le décorateur @cache

# resources/my_resource.py
from flask_api import cache
class GetStuff(Resource):
    @cache.memoize(timeout=30)
    def get():
        return "Stuff"

Mais cela provoque le redoutable problème d'importation circulaire. Je pourrais prendre en sandwich toutes mes importations de ressources en dessous de la ligne cache = Cache(...), au-dessus de api.add_resource(). Cependant, cela ressemble à une odeur de code hacky et en fait un sandwich très, très charnu. Je préférerais de loin les avoir tous en haut du fichier.

Quelle est la bonne façon de résoudre ce problème ? (espérons-le, sans remanier de grandes parties de la base de code)

Tl;dr : flask_api crée un cache et importe des ressources -> les ressources ne peuvent pas importer de cache depuis flask_api

2
c8999c 3f964f64 10 févr. 2020 à 17:14

1 réponse

Meilleure réponse

D'accord, la solution simple consistait à déplacer la génération de cache dans le fichier __init__.py dans le dossier des ressources

flask_api.py
-resources
--__init__.py
--my_resource.py
--my_other_resource.py
--so_many_more_resources.py

Et en initiant le cache sans le paramètre "app", comme ça

# __init__.py
cache = Cache(config={'...'})

Flask_api.py peut alors l'importer et faire cache.init_app(app)

# flask_api.py
from resources import cache
cache.init_app(app)

Et les ressources peuvent également importer le cache de __init__.py

# my_resource.py
from . import cache
class GetStuff(Resource):
    @cache.memoize(timeout=30)
    def get():
        return "Stuff"

Cela ne provoque pas une tonne de changements structurels pour mon application flask et me permet d'importer des ressources dans flask_api sans les prendre en sandwich après la génération de l'application pour éviter les importations circulaires.

J'espère que cela aidera toute autre personne rencontrant des problèmes similaires.

1
c8999c 3f964f64 22 sept. 2020 à 11:25