Manejo de la configuración¶
Las aplicaciones necesitan algún tipo de configuración. Hay diferentes configuraciones que puedes querer cambiar dependiendo del entorno de la aplicación, como activar el modo de depuración, establecer la clave secreta, y otras cosas específicas del entorno.
La forma en que Flask está diseñado normalmente requiere que la configuración esté disponible cuando la aplicación se inicia. Puedes codificar la configuración en el código, lo que para muchas aplicaciones pequeñas no es realmente tan malo, pero hay mejores maneras.
Independientemente de cómo se cargue la configuración, hay un objeto config disponible que contiene los valores de configuración cargados: El atributo config del objeto Flask. Este es el lugar donde Flask mismo pone ciertos valores de configuración y también donde las extensiones pueden poner sus valores de configuración. Pero también es donde puedes tener tu propia configuración.
Conceptos básicos de configuración¶
El config es en realidad una subclase de un diccionario y puede ser modificado como cualquier diccionario:
app = Flask(__name__)
app.config['TESTING'] = True
Ciertos valores de configuración también se envían al objeto Flask para que puedas leerlos y escribirlos desde allí:
app.testing = True
Para actualizar varias claves a la vez se puede utilizar el método dict.update():
app.config.update(
TESTING=True,
SECRET_KEY='192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
)
Debug Mode¶
El valor de configuración DEBUG es especial porque puede comportarse de forma inconsistente si se cambia después de que la aplicación haya comenzado a configurarse. Para establecer el modo de depuración de forma fiable, utiliza la opción --debug en el comando flask o flask run. flask run utilizará el depurador interactivo y el recargador por defecto en modo depuración.
$ flask --app hello run --debug
Se recomienda utilizar esta opción. Aunque es posible establecer DEBUG en su configuración o código, esto se desaconseja totalmente. El comando flask run no puede leerlo antes, y algunos sistemas o extensiones pueden haberse configurado ya basándose en un valor anterior.
Valores de configuración incorporados¶
Los siguientes valores de configuración son utilizados internamente por Flask:
- DEBUG¶
Si el modo de depuración está habilitado. Cuando se usa
flask runpara iniciar el servidor de desarrollo, se mostrará un depurador interactivo para las excepciones no manejadas, y el servidor se recargará cuando cambie el código. El atributodebugse asigna a esta clave de configuración. Se establece con la variable de entornoFLASK_DEBUG. Puede no comportarse como se espera si se establece en el código.No active el modo de depuración cuando se despliegue en producción.
Por defecto:
False
- TESTING¶
Activar el modo de prueba. Las excepciones se propagan en lugar de ser manejadas por los manejadores de errores de la aplicación. Las extensiones también pueden cambiar su comportamiento para facilitar las pruebas. Deberías habilitar esto en tus propias pruebas.
Por defecto:
False
- PROPAGATE_EXCEPTIONS¶
Las excepciones se vuelven a lanzar en lugar de ser manejadas por los manejadores de errores de la aplicación. Si no se establece, esto es implícitamente cierto si
TESTINGoDEBUGestá activado.Por defecto:
None
- TRAP_HTTP_EXCEPTIONS¶
Si no hay un manejador para una excepción de tipo
HTTPException, vuelve a lanzarla para que sea manejada por el depurador interactivo en lugar de devolverla como una simple respuesta de error.Por defecto:
False
- TRAP_BAD_REQUEST_ERRORS¶
Intentar acceder a una clave que no existe desde los dicts de petición como
argsyformdevolverá una página de error 400 Bad Request. Habilita esto para tratar el error como una excepción no manejada en su lugar para que obtengas el depurador interactivo. Esta es una versión más específica deTRAP_HTTP_EXCEPTIONS. Si no se activa, se habilita en modo de depuración.Por defecto:
None
- SECRET_KEY¶
Una clave secreta que se utilizará para firmar de forma segura la cookie de sesión y puede ser utilizada para cualquier otra necesidad relacionada con la seguridad por las extensiones o su aplicación. Debe ser un
bytesostrlargo y aleatorio. Por ejemplo, copie la salida de esto a su config:$ python -c 'import secrets; print(secrets.token_hex())' '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
No reveles la clave secreta al publicar las preguntas o comprometer el código.
Por defecto:
None
- SECRET_KEY_FALLBACKS¶
Una lista de claves secretas antiguas que aún pueden utilizarse para desfirmar, la más reciente primero. Esto permite a un proyecto implementar la rotación de claves sin invalidar sesiones activas u otros secretos firmados recientemente.
Las claves deben eliminarse tras un periodo de tiempo adecuado, ya que comprobar cada clave adicional añade cierta sobrecarga.
La sesión de cookie segura incorporada de Flask soporta esto. Las extensiones que usan
SECRET_KEYpueden no soportarlo todavía.Por defecto:
NoneAdded in version 3.1.
- SESSION_COOKIE_NAME¶
El nombre de la cookie de sesión. Se puede cambiar en caso de que ya tenga una cookie con el mismo nombre.
Por defecto:
'session'
- SESSION_COOKIE_DOMAIN¶
The value of the
Domainparameter on the session cookie. If not set, browsers will only send the cookie to the exact domain it was set from. Otherwise, they will send it to any subdomain of the given value as well.No fijar este valor es más restringido y seguro que fijarlo.
Por defecto:
NoneAdvertencia
Si esto se cambia después de que el navegador haya creado una cookie con una configuración, puede resultar en la creación de otra. Los navegadores pueden enviar ambas en un orden indefinido. En ese caso, es posible que desee cambiar
SESSION_COOKIE_NAMEtambién o invalidar de otro modo las sesiones antiguas.Changelog
Distinto en la versión 2.3: Not set by default, does not fall back to
SERVER_NAME.
- SESSION_COOKIE_PATH¶
La ruta para la que será válida la cookie de sesión. Si no se establece, la cookie será válida bajo
APPLICATION_ROOTo/si no se establece.Por defecto:
None
- SESSION_COOKIE_HTTPONLY¶
Los navegadores no permiten el acceso de JavaScript a las cookies marcadas como «sólo HTTP» por seguridad.
Por defecto:
True
- SESSION_COOKIE_SECURE¶
Los navegadores sólo enviarán las cookies con solicitudes a través de HTTPS si la cookie está marcada como «segura». La aplicación debe ser servida a través de HTTPS para que esto tenga sentido.
Por defecto:
False
- SESSION_COOKIE_PARTITIONED¶
Los navegadores enviarán las cookies basándose en el dominio del documento de nivel superior, en lugar de basarse únicamente en el dominio del documento que establece la cookie. Esto evita que las cookies de terceros establecidas en iframes se «filtren» entre sitios distintos.
Los navegadores están empezando a desautorizar las cookies de terceros no particionadas, por lo que deberá marcar sus cookies como particionadas si espera que funcionen en dichas situaciones de incrustación.
Habilitar esto implícitamente habilita
SESSION_COOKIE_SECUREtambién, ya que sólo es válido cuando se sirve a través de HTTPS.Por defecto:
FalseAdded in version 3.1.
- SESSION_COOKIE_SAMESITE¶
Restringe cómo se envían las cookies con las solicitudes de sitios externos. Puede establecerse como
'Lax'(recomendado) o'Strict'. Ver Opciones de configuración de cookies.Por defecto:
NoneChangelog
Added in version 1.0.
- PERMANENT_SESSION_LIFETIME¶
Si
session.permanentes verdadero, la expiración de la cookie se establecerá este número de segundos en el futuro. Puede ser undatetime.timedeltao unint.La implementación de cookies por defecto de Flask valida que la firma criptográfica no sea más antigua que este valor.
Por defecto:
timedelta(days=31)(2678400seconds)
- SESSION_REFRESH_EACH_REQUEST¶
Controla si la cookie se envía con cada respuesta cuando
session.permanentes verdadero. Enviar la cookie cada vez (el valor por defecto) puede evitar que la sesión expire de forma más fiable, pero utiliza más ancho de banda. Las sesiones no permanentes no se ven afectadas.Por defecto:
True
- USE_X_SENDFILE¶
Cuando sirvas archivos, establece la cabecera
X-Sendfileen lugar de servir los datos con Flask. Algunos servidores web, como Apache, reconocen esto y sirven los datos de manera más eficiente. Esto sólo tiene sentido cuando se utiliza un servidor de este tipo.Por defecto:
False
- SEND_FILE_MAX_AGE_DEFAULT¶
Cuando se sirven archivos, establece la edad máxima del control de la caché a este número de segundos. Puede ser un
datetime.timedeltao unint. Anula este valor en base a cada archivo usandoget_send_file_max_age()en la aplicación o blueprint.Si es
None,send_fileindica al navegador que se utilizarán peticiones condicionales en lugar de una caché temporizada, lo que suele ser preferible.Por defecto:
None
- TRUSTED_HOSTS¶
Validar
Request.hosty otros atributos que lo utilizan contra estos valores de confianza. Lanza unSecurityErrorsi el host no es válido, lo que resulta en un error 400. Si esNone, todos los hosts son válidos. Cada valor es una coincidencia exacta, o puede empezar con un punto.para coincidir con cualquier subdominio.La validación se realiza durante el enrutamiento contra este valor. Las llamadas de retorno
before_requestyafter_requestse seguirán realizando.Por defecto:
NoneAdded in version 3.1.
- SERVER_NAME¶
Informa a la aplicación a qué host y puerto está vinculada.
Debe establecerse si
subdomain_matchingestá activado, para poder extraer el subdominio de la petición.Debe establecerse para
url_forpara generar URLs externas fuera de un contexto de petición.Por defecto:
NoneDistinto en la versión 3.1: No restringe las peticiones sólo a este dominio, tanto para
subdomain_matchingcomo parahost_matching.Changelog
Distinto en la versión 2.3: No afecta a
SESSION_COOKIE_DOMAIN.Distinto en la versión 1.0: No habilita implícitamente
subdomain_matching.
- APPLICATION_ROOT¶
Informa a la aplicación bajo qué ruta está montada por la aplicación / servidor web. Esto se utiliza para generar URLs fuera del contexto de una solicitud (dentro de una solicitud, el despachador es responsable de establecer
SCRIPT_NAMEen su lugar; ver Despacho de aplicaciones para ejemplos de configuración de despacho).Se utilizará para la ruta de la cookie de sesión si
SESSION_COOKIE_PATHno se establece.Por defecto:
'/'
- PREFERRED_URL_SCHEME¶
Utilice este esquema para generar URLs externas cuando no esté en un contexto de solicitud.
Por defecto:
'http'
- MAX_CONTENT_LENGTH¶
The maximum number of bytes that will be read during this request. If this limit is exceeded, a 413
RequestEntityTooLargeerror is raised. If it is set toNone, no limit is enforced at the Flask application level. However, if it isNoneand the request has noContent-Lengthheader and the WSGI server does not indicate that it terminates the stream, then no data is read to avoid an infinite stream.Cada solicitud tiene por defecto esta configuración. Puede establecerse en un
Request.max_content_lengthespecífico para aplicar el límite a esa vista concreta. Esto debe establecerse adecuadamente en función de las necesidades específicas de una aplicación o vista.Por defecto:
NoneChangelog
Added in version 0.6.
- MAX_FORM_MEMORY_SIZE¶
The maximum size in bytes any non-file form field may be in a
multipart/form-databody. If this limit is exceeded, a 413RequestEntityTooLargeerror is raised. If it is set toNone, no limit is enforced at the Flask application level.Cada solicitud tiene por defecto esta configuración. Puede establecerse en un
Request.max_form_memory_partsespecífico para aplicar el límite a esa vista concreta. Esto debe establecerse adecuadamente en función de las necesidades específicas de una aplicación o vista.Por defecto:
500_000Added in version 3.1.
- MAX_FORM_PARTS¶
The maximum number of fields that may be present in a
multipart/form-databody. If this limit is exceeded, a 413RequestEntityTooLargeerror is raised. If it is set toNone, no limit is enforced at the Flask application level.Cada solicitud tiene por defecto esta configuración. Puede establecerse en un
Request.max_form_partsespecífico para aplicar el límite a esa vista concreta. Esto debe establecerse adecuadamente en función de las necesidades específicas de una aplicación o vista.Por defecto:
1_000Added in version 3.1.
- TEMPLATES_AUTO_RELOAD¶
Recarga las plantillas cuando se modifican. Si no se establece, se habilitará en modo de depuración.
Por defecto:
None
- EXPLAIN_TEMPLATE_LOADING¶
Registra la información de depuración que rastrea cómo se cargó un archivo de plantilla. Esto puede ser útil para averiguar por qué no se ha cargado una plantilla o parece que se ha cargado un archivo incorrecto.
Por defecto:
False
- MAX_COOKIE_SIZE¶
Avisa si las cabeceras de las cookies son mayores que esta cantidad de bytes. Por defectos a
4093. Las cookies más grandes pueden ser ignoradas silenciosamente por los navegadores. Establezca0para desactivar la advertencia.
- PROVIDE_AUTOMATIC_OPTIONS¶
Establece
Falsepara deshabilitar la adición automática de respuestas OPTIONS. Se puede anular por ruta modificando el atributoprovide_automatic_options.
Added in version 3.10: Añadido PROVIDE_AUTOMATIC_OPTIONS para controlar la adición por defecto de respuestas OPTIONS autogeneradas.
Changelog
Distinto en la versión 2.3: Se han eliminado los atributos JSON_AS_ASCII, JSON_SORT_KEYS, JSONIFY_MIMETYPE y JSONIFY_PRETTYPRINT_REGULAR. El proveedor por defecto app.json tiene atributos equivalentes.
Distinto en la versión 2.3: Se ha eliminado ENV.
Distinto en la versión 2.2: Se ha eliminado PRESERVE_CONTEXT_ON_EXCEPTION.
Distinto en la versión 1.0: Se han eliminado LOGGER_NAME y LOGGER_HANDLER_POLICY. Consulte Registro de eventos para obtener información sobre la configuración.
Se ha añadido ENV para reflejar la variable de entorno FLASK_ENV.
Añadido SESSION_COOKIE_SAMESITE para controlar la opción SameSite de la cookie de sesión.
Añadido MAX_COOKIE_SIZE para controlar un aviso de Werkzeug.
Added in version 0.11: SESSION_REFRESH_EACH_REQUEST, TEMPLATES_AUTO_RELOAD,
LOGGER_HANDLER_POLICY, EXPLAIN_TEMPLATE_LOADING
Added in version 0.10: JSON_AS_ASCII, JSON_SORT_KEYS, JSONIFY_PRETTYPRINT_REGULAR
Added in version 0.9: PREFERRED_URL_SCHEME
Added in version 0.8: TRAP_BAD_REQUEST_ERRORS, TRAP_HTTP_EXCEPTIONS,
APPLICATION_ROOT, SESSION_COOKIE_DOMAIN,
SESSION_COOKIE_PATH, SESSION_COOKIE_HTTPONLY,
SESSION_COOKIE_SECURE
Added in version 0.7: PROPAGATE_EXCEPTIONS, PRESERVE_CONTEXT_ON_EXCEPTION
Added in version 0.6: MAX_CONTENT_LENGTH
Added in version 0.5: SERVER_NAME
Added in version 0.4: LOGGER_NAME
Configuración desde archivos Python¶
La configuración resulta más útil si puede almacenarla en un archivo independiente, idealmente ubicado fuera del paquete de la aplicación real. Puedes desplegar tu aplicación y luego configurarla por separado para el despliegue específico.
Un patrón común es el siguiente:
app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
Primero se carga la configuración del módulo tuaplicacion.default_settings y luego se sustituyen los valores por el contenido del archivo al que apunta la variable de entorno TUAPLICACION_SETTINGS. Esta variable de entorno se puede establecer en el shell antes de iniciar el servidor:
$ export YOURAPPLICATION_SETTINGS=/path/to/settings.cfg
$ flask run
* Running on http://127.0.0.1:5000/
$ set -x YOURAPPLICATION_SETTINGS /path/to/settings.cfg
$ flask run
* Running on http://127.0.0.1:5000/
> set YOURAPPLICATION_SETTINGS=\path\to\settings.cfg
> flask run
* Running on http://127.0.0.1:5000/
> $env:YOURAPPLICATION_SETTINGS = "\path\to\settings.cfg"
> flask run
* Running on http://127.0.0.1:5000/
Los propios archivos de configuración son archivos reales de Python. Sólo los valores en mayúsculas se almacenan en el objeto config más tarde. Así que asegúrese de usar letras mayúsculas para sus claves de configuración.
Aquí hay un ejemplo de un archivo de configuración:
# Example configuration
SECRET_KEY = '192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'
Asegúrese de cargar la configuración muy pronto, para que las extensiones tengan la capacidad de acceder a la configuración cuando se inicie. También hay otros métodos en el objeto config para cargar desde archivos individuales. Para una referencia completa, lea la documentación del objeto Config.
Configuración a partir de archivos de datos¶
También es posible cargar la configuración desde un archivo en un formato de su elección utilizando from_file(). Por ejemplo, para cargar desde un archivo TOML:
import tomllib
app.config.from_file("config.toml", load=tomllib.load, text=False)
O desde un archivo JSON:
import json
app.config.from_file("config.json", load=json.load)
Configuración desde las variables de entorno¶
Además de apuntar a los archivos de configuración utilizando variables de entorno, puede resultar útil (o necesario) controlar sus valores de configuración directamente desde el entorno. Se puede instruir a Flask para que cargue todas las variables de entorno que comiencen con un prefijo específico en la configuración utilizando from_prefixed_env().
Las variables de entorno pueden establecerse en el shell antes de iniciar el servidor:
$ export FLASK_SECRET_KEY="5f352379324c22463451387a0aec5d2f"
$ export FLASK_MAIL_ENABLED=false
$ flask run
* Running on http://127.0.0.1:5000/
$ set -x FLASK_SECRET_KEY "5f352379324c22463451387a0aec5d2f"
$ set -x FLASK_MAIL_ENABLED false
$ flask run
* Running on http://127.0.0.1:5000/
> set FLASK_SECRET_KEY="5f352379324c22463451387a0aec5d2f"
> set FLASK_MAIL_ENABLED=false
> flask run
* Running on http://127.0.0.1:5000/
> $env:FLASK_SECRET_KEY = "5f352379324c22463451387a0aec5d2f"
> $env:FLASK_MAIL_ENABLED = "false"
> flask run
* Running on http://127.0.0.1:5000/
Las variables se pueden cargar y acceder a través de la configuración con una clave igual al nombre de la variable de entorno sin el prefijo, es decir.
app.config.from_prefixed_env()
app.config["SECRET_KEY"] # Is "5f352379324c22463451387a0aec5d2f"
El prefijo es FLASK_ por defecto. Esto es configurable mediante el argumento prefix de from_prefixed_env().
Los valores serán analizados para intentar convertirlos a un tipo más específico que las cadenas. Por defecto se utiliza json.loads(), por lo que cualquier valor JSON válido es posible, incluyendo listas y dicts. Esto es configurable mediante el argumento loads de from_prefixed_env().
Cuando se añade un valor booleano con el análisis JSON por defecto, sólo «true» y «false», en minúsculas, son valores válidos. Ten en cuenta que cualquier cadena no vacía es considerada True por Python.
Es posible establecer claves en diccionarios anidados separando las claves con doble guión bajo (__). Las claves intermedias que no existan en el dictado padre se inicializarán con un dict vacío.
$ export FLASK_MYAPI__credentials__username=user123
app.config["MYAPI"]["credentials"]["username"] # Is "user123"
En Windows, las claves de las variables de entorno son siempre mayúsculas, por lo que el ejemplo anterior terminaría como MYAPI__CREDENTIALS__USERNAME.
Para obtener aún más características de carga de configuraciones, incluyendo la fusión y el soporte de Windows insensible a las mayúsculas y minúsculas, pruebe una biblioteca dedicada como Dynaconf, que incluye la integración con Flask.
Mejores prácticas de configuración¶
El inconveniente del planteamiento antes mencionado es que dificulta un poco las pruebas. No existe una solución única al 100% para este problema en general, pero hay un par de cosas que puedes tener en cuenta para mejorar esa experiencia:
Cree su aplicación en una función y registre los blueprints en ella. De esta manera puedes crear múltiples instancias de tu aplicación con diferentes configuraciones adjuntas lo que hace que las pruebas unitarias sean mucho más fáciles. Puedes usar esto para pasar la configuración según sea necesario.
No escriba código que necesite la configuración en el momento de la importación. Si te limitas a los accesos de sólo petición a la configuración, puedes reconfigurar el objeto más tarde según sea necesario.
Asegúrate de cargar la configuración muy pronto, para que las extensiones puedan acceder a la configuración cuando llamen a
init_app.
Desarrollo / Producción¶
La mayoría de las aplicaciones necesitan más de una configuración. Debería haber al menos configuraciones separadas para el servidor de producción y el utilizado durante el desarrollo. La forma más fácil de manejar esto es utilizar una configuración por defecto que siempre se carga y forma parte del control de versiones, y una configuración separada que anula los valores según sea necesario como se menciona en el ejemplo anterior:
app = Flask(__name__)
app.config.from_object('yourapplication.default_settings')
app.config.from_envvar('YOURAPPLICATION_SETTINGS')
Entonces sólo tienes que añadir un archivo config.py separado y exportar TUAPLICACION_SETTINGS=/ruta/al/config.py y ya está. Sin embargo, también hay formas alternativas. Por ejemplo, puedes usar importaciones o subclases.
Lo que es muy popular en el mundo de Django es hacer la importación explícita en el archivo de configuración añadiendo from yourapplication.default_settings import * al principio del archivo y luego anulando los cambios a mano. También puedes inspeccionar una variable de entorno como YOURAPPLICATION_MODE y establecerla como producción, desarrollo, etc. e importar diferentes archivos codificados en base a eso.
Un patrón interesante es también utilizar clases y herencia para la configuración:
class Config(object):
TESTING = False
class ProductionConfig(Config):
DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config):
DATABASE_URI = "sqlite:////tmp/foo.db"
class TestingConfig(Config):
DATABASE_URI = 'sqlite:///:memory:'
TESTING = True
Para habilitar una configuración de este tipo sólo tienes que llamar a from_object():
app.config.from_object('configmodule.ProductionConfig')
Tenga en cuenta que from_object() no instanciará el objeto de la clase. Si necesita instanciar la clase, por ejemplo para acceder a una propiedad, debe hacerlo antes de llamar a from_object():
from configmodule import ProductionConfig
app.config.from_object(ProductionConfig())
# Alternatively, import via string:
from werkzeug.utils import import_string
cfg = import_string('configmodule.ProductionConfig')()
app.config.from_object(cfg)
La instanciación del objeto de configuración le permite utilizar @property en sus clases de configuración:
class Config(object):
"""Base config, uses staging database server."""
TESTING = False
DB_SERVER = '192.168.1.56'
@property
def DATABASE_URI(self): # Note: all caps
return f"mysql://user@{self.DB_SERVER}/foo"
class ProductionConfig(Config):
"""Uses production database server."""
DB_SERVER = '192.168.19.32'
class DevelopmentConfig(Config):
DB_SERVER = 'localhost'
class TestingConfig(Config):
DB_SERVER = 'localhost'
DATABASE_URI = 'sqlite:///:memory:'
Hay muchas maneras diferentes y depende de ti cómo quieres gestionar tus archivos de configuración. Sin embargo aquí una lista de buenas recomendaciones:
Mantenga una configuración por defecto en el control de versiones. Rellene la configuración con esta configuración por defecto o impórtela en sus propios archivos de configuración antes de anular los valores.
Utilice una variable de entorno para cambiar entre las configuraciones. Esto se puede hacer desde fuera del intérprete de Python y hace que el desarrollo y el despliegue sean mucho más fáciles porque puedes cambiar rápida y fácilmente entre diferentes configuraciones sin tener que tocar el código en absoluto. Si trabajas a menudo en diferentes proyectos puedes incluso crear tu propio script para el sourcing que active un virtualenv y exporte la configuración de desarrollo por ti.
Utilice una herramienta como fabric para enviar el código y la configuración por separado a los servidores de producción.
Carpetas de instancias¶
Changelog
Added in version 0.8.
Flask 0.8 introduce las carpetas de instancia. Durante mucho tiempo Flask hizo posible referirse a rutas relativas a la carpeta de la aplicación directamente (a través de Flask.root_path). Así era también como muchos desarrolladores cargaban las configuraciones almacenadas junto a la aplicación. Sin embargo, lamentablemente esto sólo funciona bien si las aplicaciones no son paquetes, en cuyo caso la ruta raíz se refiere al contenido del paquete.
Con Flask 0.8 se introdujo un nuevo atributo: Flask.instance_path. Hace referencia a un nuevo concepto llamado “carpeta de instancia”. La carpeta de instancia está diseñada para no estar bajo control de versiones y ser específica para el despliegue. Es el lugar perfecto para dejar cosas que cambian en tiempo de ejecución o archivos de configuración.
Puedes proporcionar explícitamente la ruta de la carpeta de instancia cuando creas la aplicación Flask o puedes dejar que Flask autodetecte la carpeta de instancia. Para la configuración explícita utilice el parámetro instance_path:
app = Flask(__name__, instance_path='/path/to/instance/folder')
Por favor, tenga en cuenta que esta ruta debe ser absoluta cuando se proporciona.
Si no se proporciona el parámetro instance_path se utilizan las siguientes ubicaciones por defecto:
Módulo desinstalado:
/myapp.py /instance
Paquete desinstalado:
/myapp /__init__.py /instance
Módulo o paquete instalado:
$PREFIX/lib/pythonX.Y/site-packages/myapp $PREFIX/var/myapp-instance
$PREFIXes el prefijo de tu instalación de Python. Puede ser/usro la ruta de tu virtualenv. Puedes imprimir el valor desys.prefixpara ver cuál es el prefijo establecido.
Dado que el objeto config proporcionaba la carga de archivos de configuración a partir de nombres de archivo relativos, hemos hecho posible cambiar la carga a través de los nombres de archivo para que sea relativa a la ruta de la instancia si se desea. El comportamiento de las rutas relativas en los archivos de configuración puede cambiarse entre «relativo a la raíz de la aplicación» (por defecto) y «relativo a la carpeta de la instancia» a través del interruptor instance_relative_config del constructor de la aplicación:
app = Flask(__name__, instance_relative_config=True)
Aquí hay un ejemplo completo de cómo configurar Flask para precargar la configuración de un módulo y luego anular la configuración de un archivo en la carpeta de instancia si existe:
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('yourapplication.default_settings')
app.config.from_pyfile('application.cfg', silent=True)
La ruta de acceso a la carpeta de instancias se puede encontrar a través de Flask.instance_path. Flask también proporciona un acceso directo para abrir un archivo de la carpeta de instancia con Flask.open_instance_resource().
Ejemplo de uso de ambos:
filename = os.path.join(app.instance_path, 'application.cfg')
with open(filename) as f:
config = f.read()
# or via open_instance_resource:
with app.open_instance_resource('application.cfg') as f:
config = f.read()