Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

How Can memorystore Redis be used to store session data of flask app running on App Engine?

I have a flask application on App Engine, where I am trying to find a suitable solution to store the user session data.

I came across redis as a solution [please suggest if anything suites better], I am still figuring out on how I can use the Memeorystore Redis to store the session data.

I am trying to use the flask login manager along with memorystore to make this work.

I have my following code:

 

app = Flask(__name__)

app.secret_key = os.environ.get('SECRET_KEY')
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_USE_SIGNER'] = True
app.config['SESSION_KEY_PREFIX'] = 'tank_userSession0782328'  # Change this to a unique prefix
REDIS_HOST = os.getenv('REDIS_HOST', 'localhost')
REDIS_PORT = int(os.getenv('REDIS_PORT', 6379))
app.config['SESSION_REDIS'] = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT)

Session(app)
login_manager = LoginManager()
login_manager.login_view = "login"
login_manager.init_app(app)

@app.route('/login', methods=['POST'])
def login_authentication():
    try:
        # Get the username and password from the request
        username = request.json.get('username')
        password = request.json.get('password')

        # Validate the login credentials
        user = validate_credentials(username, password)

        if user:
            # Log the login details in the 'login_sheetName' sheet
            log_login_details(user.id, username)

            login_user(user)

            print("User ID: ", current_user.id)
            print("first name: ", current_user.firstname)

            return redirect(url_for('home'))
        else:
            # Return an error response
            print("Login credentials mismatch")
            return jsonify({'error': 'Invalid username or password'})
        
    except Exception as e:
        print("Error:", e)
        return jsonify({'error': 'An error occurred'})

 

The error occurs when I am in line number 30 "login_user(user)"

 


Error I am encountering: 

DEFAULT 2023-11-10T13:45:01.924336Z [2023-11-10 13:45:01,918] ERROR in app: Exception on /login [POST]
ERROR 2023-11-10T13:45:01.924365Z Traceback (most recent call last): File "/layers/google.python.pip/pip/lib/python3.11/site-packages/flask/app.py", line 2190, in wsgi_app response = self.full_dispatch_request()
DEFAULT 2023-11-10T13:45:01.924369Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
DEFAULT 2023-11-10T13:45:01.924376Z File "/layers/google.python.pip/pip/lib/python3.11/site-packages/flask/app.py", line 1487, in full_dispatch_request
DEFAULT 2023-11-10T13:45:01.924380Z return self.finalize_request(rv)
DEFAULT 2023-11-10T13:45:01.924384Z ^^^^^^^^^^^^^^^^^^^^^^^^^
DEFAULT 2023-11-10T13:45:01.924388Z File "/layers/google.python.pip/pip/lib/python3.11/site-packages/flask/app.py", line 1508, in finalize_request
DEFAULT 2023-11-10T13:45:01.924393Z response = self.process_response(response)
DEFAULT 2023-11-10T13:45:01.924397Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
DEFAULT 2023-11-10T13:45:01.924402Z File "/layers/google.python.pip/pip/lib/python3.11/site-packages/flask/app.py", line 2005, in process_response
DEFAULT 2023-11-10T13:45:01.924406Z self.session_interface.save_session(self, ctx.session, response)
DEFAULT 2023-11-10T13:45:01.924411Z File "/layers/google.python.pip/pip/lib/python3.11/site-packages/flask_session/sessions.py", line 161, in save_session
DEFAULT 2023-11-10T13:45:01.924415Z session_id = self._get_signer(app).sign(want_bytes(session.sid))
DEFAULT 2023-11-10T13:45:01.924419Z ^^^^^^^^^^^^^^^^^^^^^^^^^^
DEFAULT 2023-11-10T13:45:01.927387Z AttributeError: 'NoneType' object has no attribute 'sign'
DEFAULT 2023-11-10T13:45:01.927401Z [2023-11-10 13:45:01,926] ERROR in app: Request finalizing failed with an error while handling an error


Solved Solved
1 1 1,403
1 ACCEPTED SOLUTION

found the RESOLUTION as follows:
1. for flask application to use google could redis instance to store user session data, follow all the steps from this article: https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-standard

2. store the required details for your app to use during run time as environment variable in the app.yaml file.

Update the app.yaml file appropriately before deploying on google cloud

runtime: python311

env_variables:
  REDIS_HOST: "<redis_host>"
  REDIS_PORT: "6379"
  SECRET_KEY: <unique-alpha-numeric-string-without-quotes>

vpc_access_connector:
  name: projects/<g-cloud-project-id>/locations/<location>/connectors/<vpc-connector-name>

In the above code my error was trying to tell me that it was unable to create session id during run time as it was unable to access the "SECRET_KEY" variable as environment variable.

Environment variable "SECERET_KEY" was missing from the app.yaml file.

DEFAULT 2023-11-10T13:45:01.924415Z session_id = self._get_signer(app).sign(want_bytes(session.sid))
DEFAULT 2023-11-10T13:45:01.924419Z ^^^^^^^^^^^^^^^^^^^^^^^^^^
DEFAULT 2023-11-10T13:45:01.927387Z AttributeError: 'NoneType' object has no attribute 'sign'


 

View solution in original post

1 REPLY 1

found the RESOLUTION as follows:
1. for flask application to use google could redis instance to store user session data, follow all the steps from this article: https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-standard

2. store the required details for your app to use during run time as environment variable in the app.yaml file.

Update the app.yaml file appropriately before deploying on google cloud

runtime: python311

env_variables:
  REDIS_HOST: "<redis_host>"
  REDIS_PORT: "6379"
  SECRET_KEY: <unique-alpha-numeric-string-without-quotes>

vpc_access_connector:
  name: projects/<g-cloud-project-id>/locations/<location>/connectors/<vpc-connector-name>

In the above code my error was trying to tell me that it was unable to create session id during run time as it was unable to access the "SECRET_KEY" variable as environment variable.

Environment variable "SECERET_KEY" was missing from the app.yaml file.

DEFAULT 2023-11-10T13:45:01.924415Z session_id = self._get_signer(app).sign(want_bytes(session.sid))
DEFAULT 2023-11-10T13:45:01.924419Z ^^^^^^^^^^^^^^^^^^^^^^^^^^
DEFAULT 2023-11-10T13:45:01.927387Z AttributeError: 'NoneType' object has no attribute 'sign'


 

Top Labels in this Space
Top Solution Authors