Source code for aws_session_recorder.lib.session
"""Main module."""
import os
import boto3 # type: ignore
import botocore.client # type: ignore
import botocore.model # type: ignore
import botocore.awsrequest # type: ignore
import sqlalchemy # type: ignore
import sqlalchemy.orm # type: ignore
import sqlalchemy.ext.declarative # type: ignore
from aws_session_recorder.lib.schema.functions import ApiCallMap
from aws_session_recorder.lib.schema.base import Base
[docs]class Session(boto3.session.Session):
db: sqlalchemy.orm.Session
Base: sqlalchemy.ext.declarative.DeclarativeMeta
def __init__(self, connection_string: str = f"sqlite:///{os.path.join(os.getcwd(), 'sqlite.db')}", *args, **kwargs):
super().__init__(*args, **kwargs)
self.setup(connection_string=connection_string)
[docs] def setup(self, connection_string: str):
engine = sqlalchemy.create_engine(connection_string, echo=False)
Base.metadata.create_all(engine)
self.db = sqlalchemy.orm.Session(engine)
[docs] def client(self, *args, **kwargs):
client: botocore.client.BaseClient = super().client(*args, **kwargs)
client.meta.events.register('provide-client-params.iam.*', self.record_request)
client.meta.events.register('after-call.iam.*', self.record_response)
return client
[docs] def record_request(
self,
params: dict,
model: botocore.model.OperationModel,
context: dict,
event_name: str,
*args, **kwargs
):
context['request_params'] = params
[docs] def record_response(self,
http_response: botocore.awsrequest.AWSResponse,
parsed: dict,
model: botocore.model.OperationModel,
context: dict,
event_name: str,
*args, **kwargs):
try:
f = ApiCallMap[model.name]
except KeyError:
print("Schema not implemented for {}".format(model.name))
return
request_params = context['request_params']
parsed_resp = parsed
row = f(request_params, parsed_resp) # type: ignore[arg-type]
if hasattr(row, '__next__'):
for r in row:
self.db.merge(r)
else:
self.db.merge(row)
self.db.commit()
self.db.flush()