with tutorial documentacion docs python mongodb flask pymongo

python - tutorial - Frasco: configuración de la aplicación y atributos específicos de la solicitud?



python api with mongodb (3)

Estoy escribiendo una aplicación que se conecta a una base de datos. Quiero crear esa conexión db una vez, y luego reutilizar esa conexión a lo largo de la vida de la aplicación.

También quiero autenticar a los usuarios. La autenticación de un usuario vivirá solo durante la vida de una solicitud.

¿Cómo puedo diferenciar entre los objetos almacenados durante la vida útil de una aplicación de matraz, en comparación con la solicitud? ¿Dónde los almacenaría para que todos los módulos (y los planos posteriores) tengan acceso a ellos?

Aquí está mi aplicación de muestra:

from flask import Flask, g app = Flask(__name__) @app.before_first_request def setup_database(*args, **kwargs): print ''before first request'', g.__dict__ g.database = ''DATABASE'' print ''after first request'', g.__dict__ @app.route(''/'') def index(): print ''request start'', g.__dict__ g.current_user = ''USER'' print ''request end'', g.__dict__ return ''hello'' if __name__ == ''__main__'': app.run(debug=True, port=6001)

Cuando ejecuto esto (Flask 0.10.1) y navego a http://localhost:6001/ , esto es lo que aparece en la consola:

$ python app.py * Running on http://127.0.0.1:6001/ * Restarting with reloader before first request {} after first request {''database'': ''DATABASE''} request start {''database'': ''DATABASE''} request end {''current_user'': ''USER'', ''database'': ''DATABASE''} 127.0.0.1 - - [30/Sep/2013 11:36:40] "GET / HTTP/1.1" 200 - request start {} request end {''current_user'': ''USER''} 127.0.0.1 - - [30/Sep/2013 11:36:41] "GET / HTTP/1.1" 200 -

Es decir, la primera solicitud funciona como se esperaba: flask.g mantiene mi base de datos, y cuando se inicia la solicitud, también tiene la información de mi usuario.

Sin embargo, a mi segundo pedido, ¡flask.g se borra! Mi base de datos no está en ninguna parte.

Ahora, sé que flask.g solía aplicarse solo a la solicitud. Pero ahora que está vinculado a la aplicación (a partir de 0.10), quiero saber cómo vincular las variables a toda la aplicación, en lugar de solo una solicitud.

¿Qué me estoy perdiendo?

edición: estoy especialmente interesado en MongoDB y, en mi caso, en mantener conexiones con varias bases de datos de Mongo. ¿Mi mejor apuesta es crear esas conexiones en __init__.py y reutilizar esos objetos?


"enlazado a la aplicación" no significa lo que piensas que significa. Significa que g está vinculado a la solicitud actualmente en ejecución. Quoth los documentos:

Flask le proporciona un objeto especial que garantiza que solo sea válido para la solicitud activa y que devolverá valores diferentes para cada solicitud.

Cabe señalar que los tutoriales de Flask no persisten específicamente en los objetos de la base de datos , pero que esto no es normativo para ninguna aplicación de tamaño sustancial . Si está realmente interesado en bucear en el agujero del conejo, sugiero una herramienta de agrupación de conexiones de base de datos. (como este , mencionado en la respuesta de SO ref. arriba)


Le sugiero que utilice la sesión para gestionar la información del usuario. Las sesiones le ayudan a mantener la información entre varias solicitudes y el matraz le proporciona un marco de sesión ya.

from flask import session session[''usename''] = ''xyz''

Mira la extensión Flask-Login . Está bien diseñado para manejar autenticaciones de usuario.

Para la base de datos, sugiero mirar la extensión Flask-SQLAlchemy . Esto se encarga de la inicialización, agrupación, desmontaje, etc. para que usted salga de la caja. Todo lo que necesita hacer es definir el URI de la base de datos en una configuración y vincularlo a la aplicación.

from flask.ext.sqlalchemy import SQLAlchemy app = Flask(__name__) app.config[''SQLALCHEMY_DATABASE_URI''] = ''sqlite:////tmp/test.db'' db = SQLAlchemy(app)


flask.g solo almacenará cosas durante la duración de una solicitud. La documentación mencionó que los valores se almacenan en el contexto de la aplicación en lugar de en la solicitud, pero eso es más un problema de implementación: no cambia el hecho de que los objetos en flask.g solo están disponibles en el mismo hilo, y durante el proceso. tiempo de vida de una sola solicitud.

Por ejemplo, en la sección de tutorial oficial sobre conexiones de base de datos , la conexión se realiza una vez al comienzo de la solicitud, y luego se termina al final de la solicitud.

Por supuesto, si realmente lo desea, puede crear la conexión de la base de datos una vez, almacenarla en __init__.py y hacer referencia a ella (como una variable global) según sea necesario. Sin embargo, no debe hacer esto: la conexión podría cerrarse o agotarse, y no podría usar la conexión en varios subprocesos.

Dado que no especificó CÓMO utilizará Mongo en Python, asumo que usará PyMongo , ya que eso maneja toda la agrupación de conexiones por usted.

En este caso, harías algo como esto ...

from flask import Flask from pymongo import MongoClient # This line of code does NOT create a connection client = MongoClient() app = Flask() # This can be in __init__.py, or some other file that has imported the "client" attribute @app.route(''/''): def index(): posts = client.database.posts.find()

Usted podría, si lo desea, hacer algo como esto ...

from flask import Flask, g from pymongo import MongoClient # This line of code does NOT create a connection client = MongoClient() app = Flask() @app.before_request def before_request(): g.db = client.database @app.route(''/''): def index(): posts = g.db.posts.find()

Esto realmente no es tan diferente, sin embargo, puede ser útil para la lógica que desea realizar en cada solicitud (como establecer g.db en una base de datos específica dependiendo del usuario que haya iniciado sesión).

Finalmente, puedes darte cuenta de que la mayor parte del trabajo de configuración de PyMongo con Flask se realiza en Flask-PyMongo .

Su otra pregunta se relaciona con la forma en que realiza un seguimiento de las cosas específicas del usuario que ha iniciado sesión. Bueno, en este caso, DEBE almacenar algunos datos que se quedan en la conexión. flask.g se borra al final de la consulta, por lo que no es bueno.

Lo que quieres usar es sessions . Este es un lugar donde puede almacenar valores que están (con la implementación predeterminada) almacenados en una cookie en el navegador del usuario. Dado que la cookie se enviará junto con cada solicitud que el navegador del usuario realice a su sitio web, tendrá disponibles los datos que ingrese en la sesión.

Sin embargo, tenga en cuenta que la sesión NO está almacenada en el servidor. Se convierte en una cadena que se pasa de un lado a otro al usuario. Por lo tanto, no puedes almacenar cosas como conexiones DB en él. En su lugar, almacenaría identificadores (como ID de usuario).

Asegurarse de que la autenticación del usuario funcione es MUY difícil de hacer bien. Las preocupaciones de seguridad que necesita para asegurarse son increíblemente complejas. Recomendaría encarecidamente usar algo como Flask-Login para manejar esto por usted. Aún puede usar la session para almacenar otros elementos según sea necesario, o puede dejar que Flask-Login maneje la identificación del usuario y almacene los valores que necesita en la base de datos y los recupere de la base de datos en cada solicitud.

Entonces, en resumen, hay algunas formas diferentes de hacer lo que usted quiere hacer. Cada uno tiene sus usos.

  • Los globos globales son buenos para los elementos que son seguros para subprocesos (como el MongoClient de PyMongo).
  • flask.g puede utilizarse para almacenar datos durante la vida útil de una solicitud. Con las aplicaciones de matraz basadas en SQLAlchemy, una cosa común es asegurarse de que todos los cambios se realicen a la vez, al final de una solicitud utilizando un método after_request . Usar flask.g para algo como esto es muy útil.
  • La session Flask se puede usar para almacenar datos simples (cadenas y números, no objetos de conexión) que se pueden usar en solicitudes posteriores que provienen del mismo usuario. Esto depende completamente del uso de cookies, por lo que en cualquier momento el usuario podría eliminar la cookie y todo lo que se encuentre en la "sesión" se perderá. Por lo tanto, es probable que desee almacenar gran parte de sus datos en bases de datos, con la sesión utilizada para identificar los datos que se relacionan con el usuario en la sesión.