cic-stack/apps/cic-ussd/cic_ussd/session/ussd_session.py

108 lines
3.9 KiB
Python

# standard imports
import logging
from typing import Optional
import json
# third party imports
from redis import Redis
logg = logging.getLogger()
class UssdSession:
"""
This class defines the USSD session object that is called whenever a user interacts with the system.
:cvar redis_cache: The in-memory redis cache.
:type redis_cache: Redis
"""
redis_cache: Redis = None
def __init__(self,
external_session_id: str,
service_code: str,
msisdn: str,
user_input: str,
state: str,
session_data: Optional[dict] = None):
"""
This function is called whenever a USSD session object is created and saves the instance to a JSON DB.
:param external_session_id: The Africa's Talking session ID.
:type external_session_id: str.
:param service_code: The USSD service code from which the user used to gain access to the system.
:type service_code: str.
:param msisdn: The user's phone number.
:type msisdn: str.
:param user_input: The data or choice the user has made while interacting with the system.
:type user_input: str.
:param state: The name of the USSD menu that the user was interacting with.
:type state: str.
:param session_data: Any additional data that was persisted during the user's interaction with the system.
:type session_data: dict.
"""
self.external_session_id = external_session_id
self.service_code = service_code
self.msisdn = msisdn
self.user_input = user_input
self.state = state
self.session_data = session_data
session = self.redis_cache.get(external_session_id)
if session:
session = json.loads(session)
self.version = session.get('version') + 1
else:
self.version = 1
self.session = {
'external_session_id': self.external_session_id,
'service_code': self.service_code,
'msisdn': self.msisdn,
'user_input': self.user_input,
'state': self.state,
'session_data': self.session_data,
'version': self.version
}
self.redis_cache.set(self.external_session_id, json.dumps(self.session))
self.redis_cache.persist(self.external_session_id)
def set_data(self, key: str, value: str) -> None:
"""
This function adds or updates data to the session data.
:param key: The name used to identify the data.
:type key: str.
:param value: The actual data to be stored in the session data.
:type value: str.
"""
if self.session_data is None:
self.session_data = {}
self.session_data[key] = value
self.redis_cache.set(self.external_session_id, json.dumps(self.session))
def get_data(self, key: str) -> Optional[str]:
"""
This function attempts to fetch data from the session data using the identifier for the specific data.
:param key: The name used as the identifier for the specific data.
:type key: str.
:return: This function returns the queried data if found, else it doesn't return any value.
:rtype: str.
"""
if self.session_data is not None:
return self.session_data.get(key)
else:
return None
def to_json(self):
""" This function serializes the in memory ussd session object to a JSON object
:return: A JSON object of a ussd session in memory
:rtype: dict
"""
return {
"external_session_id": self.external_session_id,
"service_code": self.service_code,
"msisdn": self.msisdn,
"user_input": self.user_input,
"state": self.state,
"session_data": self.session_data,
"version": self.version
}