diff --git a/alembic/versions/0a8cb28dc397_create_response_table.py b/alembic/versions/0a8cb28dc397_create_response_table.py new file mode 100644 index 0000000..44d4246 --- /dev/null +++ b/alembic/versions/0a8cb28dc397_create_response_table.py @@ -0,0 +1,41 @@ +"""Creating response table + +Revision ID: 0a8cb28dc397 +Revises: b5c8e1cfcb42 +Create Date: 2023-11-22 12:27:50.848006 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = "0a8cb28dc397" +down_revision: Union[str, None] = "b5c8e1cfcb42" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + op.create_table("response") + op.add_column( + "response", + sa.Column("interaction_id", sa.String(), primary_key=True, nullable=False), + ) + op.add_column("response", sa.Column("response_id", sa.String(), nullable=False)) + op.add_column("response", sa.Column("survey_id", sa.String(), nullable=False)) + op.add_column("response", sa.Column("session_id", sa.String(), nullable=False)) + op.add_column("response", sa.Column("dist", sa.String(), nullable=False)) + # Add foreign key to interaction + + +def downgrade() -> None: + # Drop foreign key from interaction + op.drop_column("response", "interaction_id") + op.drop_column("response", "response_id") + op.drop_column("response", "survey_id") + op.drop_column("response", "session_id") + op.drop_column("response", "dist") + op.drop_table("response") diff --git a/gdrive/database/crud.py b/gdrive/database/crud.py index 8a40772..e833043 100644 --- a/gdrive/database/crud.py +++ b/gdrive/database/crud.py @@ -11,3 +11,12 @@ def create_participant(db_item: models.ParticipantModel): session.refresh(db_item) session.close() return db_item + + +def create_response(db_item: models.ResponseModel): + session = database.SessionLocal() + session.add(db_item) + session.commit() + session.refresh(db_item) + session.close() + return db_item diff --git a/gdrive/database/database_api.py b/gdrive/database/database_api.py new file mode 100644 index 0000000..da5623d --- /dev/null +++ b/gdrive/database/database_api.py @@ -0,0 +1,61 @@ +import logging + +import fastapi +from fastapi import responses +from pydantic import BaseModel +from sqlalchemy.exc import SQLAlchemyError + +from gdrive.database import database, models, crud + +log = logging.getLogger(__name__) +router = fastapi.APIRouter() + + +class CreateResponseRequest(BaseModel): + interactionId: str + responseId: str + sessionId: str + surveyId: str + dist: str + + +@router.post("/database") +async def database_info(): + if database.SessionLocal(): + log.info(database.engine) + return responses.JSONResponse( + status_code=202, content="Database connected as %s" % (database.engine.name) + ) + + return responses.JSONResponse(status_code=404, content="No database session found.") + + +@router.post("/database/response") +async def process_response_header(req: CreateResponseRequest): + try: + # Create new response record + if database.SessionLocal(): + record = create_response(req) + log.info("New response (interaction_id: %s)" % (record.interaction_id)) + return responses.JSONResponse( + status_code=202, content="Successfully created new response record" + ) + except SQLAlchemyError as sql_err: + log.error(sql_err) + return responses.JSONResponse( + status_code=500, content="Error trying to complete response create" + ) + + return responses.JSONResponse(status_code=404, content="No database session found.") + + +def create_response(resp_req: CreateResponseRequest): + return crud.create_response( + models.ResponseModel( + interaction_id=resp_req.interactionId, + response_id=resp_req.responseId, + session_id=resp_req.sessionId, + survey_id=resp_req.surveyId, + dist=resp_req.dist, + ) + ) diff --git a/gdrive/database/models.py b/gdrive/database/models.py index d7a0f35..2ea399d 100644 --- a/gdrive/database/models.py +++ b/gdrive/database/models.py @@ -6,6 +6,26 @@ Base = declarative.declarative_base() +class ResponseModel(Base): + __tablename__ = "response" + + interaction_id = sqla.Column(sqla.String, primary_key=True) + response_id = sqla.Column(sqla.String) + survey_id = sqla.Column(sqla.String) + session_id = sqla.Column(sqla.String) + dist = sqla.Column(sqla.String) + + def as_list(self, index: str) -> list: + return [ + index, + self.interaction_id, + self.response_id, + self.survey_id, + self.session_id, + self.dist, + ] + + class ParticipantModel(Base): __tablename__ = "participant" diff --git a/gdrive/main.py b/gdrive/main.py index 0a438c7..e345302 100644 --- a/gdrive/main.py +++ b/gdrive/main.py @@ -4,7 +4,8 @@ import fastapi import starlette_prometheus -from . import api, export_api, analytics_api, settings +from gdrive import api, export_api, analytics_api, settings +from gdrive.database import database_api app = fastapi.FastAPI() @@ -14,3 +15,4 @@ app.include_router(api.router) app.include_router(export_api.router) app.include_router(analytics_api.router) +app.include_router(database_api.router)