Package: dynamodb-session-web
dynamodb-session-webAn implementation of a "web" session using DynamoDB as backend storage. This project has the following goals:Focus on core session handling concerns, rather than specific Python frameworks.FollowOWASP Session Managementbest practices by default. Specifically, best practices for:Session IDLength, value, and entropy: ID is a 32-byte secure random number.Strict session management: ID generation can only occur within the framework.Treat as sensitive: A "loggable session ID" is provided as a property in order to make logging the ID easier (if desired).TimeoutsAbsolute session timeout - default of 12 hoursIdle session timeout - default of 2 hoursManual session timeout - i.e. there's delete/clear supportUsageRequires a DynamoDB table namedapp_session(can be changed in settings)Create session tableawsdynamodbcreate-table\--attribute-definitions\AttributeName=id,AttributeType=S\--key-schema"AttributeName=id,KeyType=HASH"\--provisioned-throughput"ReadCapacityUnits=5,WriteCapacityUnits=5"\--table-nameapp_sessionDefault Examplefromdynamodb_session_webimportSessionManagersession=SessionManager()# Create a new session object, get the ID for later useinitial_data=session.create()session_id=initial_data.session_idinitial_data['foo']='bar'initial_data['one']=1session.save(initial_data)print(session_id)#> 'WaHnSSou4d5Rq0k11vFGafe4sjMrkwiVhNziIWLLwMc'print(initial_data.loggable_session_id)#> '517286da2682be08dc9975612dc86d65487f0990906656f631d419e64dcda6f41f5e0529c290663be315524a0b35777645e0e827d2e982a048b5e2b4bba4e02b'loaded_data=session.load(session_id)print(loaded_data['foo'])#> 'bar'print(loaded_data['one'])#> 1session.clear(session_id)Configurable Timeout and NullSession Responsefromtimeimportsleepfromdynamodb_session_webimportSessionManagersession=SessionManager()# Create a new session object, get the ID for later useinitial_data=session.create()initial_data.idle_timeout_seconds=30initial_data.absolute_timeout_seconds=30session_id=initial_data.session_idinitial_data['foo']='bar'session.save(initial_data)sleep(35)loaded_data=session.load(session_id)print(loaded_data)#> <dynamodb_session_web.NullSessionInstance object at 0x109a7da30>Custom Data Class Exampleimportjsonfromdataclassesimportasdict,dataclassfromdynamodb_session_webimportSessionInstanceBase,SessionManager@dataclassclassMySession(SessionInstanceBase):fruit:str=''color:str=''def__init__(self,**kwargs):super().__init__(**kwargs)defdeserialize(self,data):data_dict=json.loads(data)self.fruit=data_dict['fruit']self.color=data_dict['color']defserialize(self):returnjson.dumps(asdict(self))session=SessionManager(MySession)# Create a new session object, get the ID for later useinitial_data=session.create()session_id=initial_data.session_idinitial_data.fruit='apple'initial_data.color='red'session.save(initial_data)loaded_data=session.load(session_id)print(loaded_data.fruit)#> 'apple'print(loaded_data.color)#> 'red'session.clear(session_id)ConfigurationSeveral behaviors can be configured at the Session Manager level:Custom data class; must provide serialization and deserialization methods (see examples). Defaults to a dictionary.Session ID length. Defaults to 32 bytes.Table name. Defaults toapp_sessionDynamoDB URL. Defaults to None (i.e. Boto3 logic).Idle session timeout (in seconds). Defaults to 7200 seconds (2 hours).Absolute session timeout (in seconds). Defaults to 43200 seconds (12 hours).fromdynamodb_session_webimportSessionInstanceBase,SessionManagerclassMyCustomDataClass(SessionInstanceBase):defdeserialize(self,data:str):passdefserialize(self)->str:passSessionManager(MyCustomDataClass,sid_byte_length=128,table_name='my-dynamodb-table',endpoint_url='http://localhost:8000',region_name='us-east-1',idle_timeout_seconds=300,absolute_timeout_seconds=3600,)Additionally, individual session instances can have their own idle and absolute timeouts, specified in seconds:fromdynamodb_session_webimportSessionManagersession=SessionManager()instance=session.create()instance.idle_timeout_seconds=30instance.absolute_timeout_seconds=30DevelopmentPrerequisites:DockerTestsinstallpoetry, then runpoetry installto install the dependencies.To run tests, runpoetry run pytestThe integration tests will use thedocker-compose.ymlfile to create a local DynamoDB instance.Useful ThingsGet a record from local DynamoDB instanceexportsid=Jh4f1zvVp9n-YaDbkpZ0Vtru6iCXnERZv40q_ocZ7BA
awsdynamodbquery--table-nameapp_session--endpoint-urlhttp://localhost:8000\--key-condition-expression'id = :id'\--expression-attribute-values'{ ":id": {"S": "'$sid'" }}'