108 lines
3.9 KiB
Python
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
|
||
|
}
|