Skip to content

Commit

Permalink
Merge branch 'feat/course-chat/interaction-suggestion'
Browse files Browse the repository at this point in the history
  • Loading branch information
bassner committed Jun 21, 2024
2 parents d28a3c7 + 9fc4605 commit abe54bc
Show file tree
Hide file tree
Showing 32 changed files with 733 additions and 150 deletions.
1 change: 1 addition & 0 deletions app/common/message_converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def convert_iris_message_to_langchain_message(
case _:
raise ValueError(f"Unknown message role: {iris_message.sender}")


def convert_langchain_message_to_iris_message(
base_message: BaseMessage,
) -> PyrisMessage:
Expand Down
1 change: 0 additions & 1 deletion app/domain/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from .error_response_dto import IrisErrorResponseDTO
from .pipeline_execution_dto import PipelineExecutionDTO
from .pyris_message import PyrisMessage
from .pipeline_execution_settings_dto import PipelineExecutionSettingsDTO
from .chat.chat_pipeline_execution_dto import ChatPipelineExecutionDTO
from .chat.chat_pipeline_execution_base_data_dto import ChatPipelineExecutionBaseDataDTO
Expand Down
5 changes: 3 additions & 2 deletions app/domain/chat/chat_pipeline_execution_base_data_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from pydantic import Field, BaseModel

from app.domain import PyrisMessage, PipelineExecutionSettingsDTO
from app.domain import PipelineExecutionSettingsDTO
from app.domain.pyris_message import PyrisMessage
from app.domain.data.user_dto import UserDTO
from app.domain.status.stage_dto import StageDTO

Expand All @@ -13,4 +14,4 @@ class ChatPipelineExecutionBaseDataDTO(BaseModel):
settings: Optional[PipelineExecutionSettingsDTO]
initial_stages: Optional[List[StageDTO]] = Field(
default=None, alias="initialStages"
)
)
3 changes: 2 additions & 1 deletion app/domain/chat/chat_pipeline_execution_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from pydantic import Field

from app.domain import PipelineExecutionDTO, PyrisMessage, PipelineExecutionSettingsDTO
from app.domain import PipelineExecutionDTO, PipelineExecutionSettingsDTO
from app.domain.pyris_message import PyrisMessage
from app.domain.data.user_dto import UserDTO
from app.domain.status.stage_dto import StageDTO

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from pydantic import Field

from ..chat_pipeline_execution_base_data_dto import ChatPipelineExecutionBaseDataDTO
from ..chat_pipeline_execution_dto import ChatPipelineExecutionDTO
from ...data.extended_course_dto import ExtendedCourseDTO
from ...data.metrics.competency_jol_dto import CompetencyJolDTO
Expand Down
3 changes: 2 additions & 1 deletion app/domain/chat/course_chat/course_chat_status_update_dto.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Optional
from typing import Optional, List

from app.domain.status.status_update_dto import StatusUpdateDTO


class CourseChatStatusUpdateDTO(StatusUpdateDTO):
result: Optional[str] = None
suggestions: List[str] = []
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from typing import Optional
from typing import Optional, List

from app.domain.status.status_update_dto import StatusUpdateDTO


class ExerciseChatStatusUpdateDTO(StatusUpdateDTO):
result: Optional[str] = None
suggestions: List[str] = []
10 changes: 10 additions & 0 deletions app/domain/chat/interaction_suggestion_dto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from typing import Optional, List

from pydantic import Field, BaseModel

from app.domain import PyrisMessage


class InteractionSuggestionPipelineExecutionDTO(BaseModel):
chat_history: List[PyrisMessage] = Field(alias="chatHistory", default=[])
last_message: Optional[str] = Field(alias="lastMessage", default=None)
6 changes: 2 additions & 4 deletions app/domain/data/competency_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,5 @@ class CompetencyDTO(BaseModel):
title: Optional[str] = None
description: Optional[str] = None
taxonomy: Optional[CompetencyTaxonomy] = None
soft_due_date: Optional[datetime] = Field(
default=None, alias="softDueDate"
)
optional: Optional[bool] = None
soft_due_date: Optional[datetime] = Field(default=None, alias="softDueDate")
optional: Optional[bool] = None
12 changes: 9 additions & 3 deletions app/domain/data/exam_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ class ExamDTO(BaseModel):
is_text_exam: bool = Field(alias="isTextExam", default=False)
start_date: Optional[datetime] = Field(alias="startDate", default=None)
end_date: Optional[datetime] = Field(alias="endDate", default=None)
publish_results_date: Optional[datetime] = Field(alias="publishResultsDate", default=None)
exam_student_review_start: Optional[datetime] = Field(alias="examStudentReviewStart", default=None)
exam_student_review_end: Optional[datetime] = Field(alias="examStudentReviewEnd", default=None)
publish_results_date: Optional[datetime] = Field(
alias="publishResultsDate", default=None
)
exam_student_review_start: Optional[datetime] = Field(
alias="examStudentReviewStart", default=None
)
exam_student_review_end: Optional[datetime] = Field(
alias="examStudentReviewEnd", default=None
)
12 changes: 9 additions & 3 deletions app/domain/data/exercise_with_submissions_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,17 @@ class ExerciseWithSubmissionsDTO(BaseModel):
mode: ExerciseMode = Field(alias="mode")
max_points: Optional[float] = Field(alias="maxPoints", default=None)
bonus_points: Optional[float] = Field(alias="bonusPoints", default=None)
difficulty_level: Optional[DifficultyLevel] = Field(alias="difficultyLevel", default=None)
difficulty_level: Optional[DifficultyLevel] = Field(
alias="difficultyLevel", default=None
)
release_date: Optional[datetime] = Field(alias="releaseDate", default=None)
due_date: Optional[datetime] = Field(alias="dueDate", default=None)
inclusion_mode: Optional[IncludedInOverallScore] = Field(alias="inclusionMode", default=None)
presentation_score_enabled: Optional[bool] = Field(alias="presentationScoreEnabled", default=None)
inclusion_mode: Optional[IncludedInOverallScore] = Field(
alias="inclusionMode", default=None
)
presentation_score_enabled: Optional[bool] = Field(
alias="presentationScoreEnabled", default=None
)
submissions: List[SimpleSubmissionDTO] = Field(default=[])

class Config:
Expand Down
12 changes: 9 additions & 3 deletions app/domain/data/extended_course_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ class ExtendedCourseDTO(BaseModel):
description: Optional[str] = Field(alias="description", default=None)
start_time: Optional[datetime] = Field(alias="startTime", default=None)
end_time: Optional[datetime] = Field(alias="endTime", default=None)
default_programming_language: Optional[ProgrammingLanguage] = Field(alias="defaultProgrammingLanguage", default=None)
default_programming_language: Optional[ProgrammingLanguage] = Field(
alias="defaultProgrammingLanguage", default=None
)
max_complaints: Optional[int] = Field(alias="maxComplaints", default=None)
max_team_complaints: Optional[int] = Field(alias="maxTeamComplaints", default=None)
max_complaint_time_days: Optional[int] = Field(alias="maxComplaintTimeDays", default=None)
max_request_more_feedback_time_days: Optional[int] = Field(alias="maxRequestMoreFeedbackTimeDays", default=None)
max_complaint_time_days: Optional[int] = Field(
alias="maxComplaintTimeDays", default=None
)
max_request_more_feedback_time_days: Optional[int] = Field(
alias="maxRequestMoreFeedbackTimeDays", default=None
)
max_points: Optional[int] = Field(alias="maxPoints", default=None)
presentation_score: Optional[int] = Field(alias="presentationScore", default=None)
exercises: List[ExerciseWithSubmissionsDTO] = Field(alias="exercises", default=[])
Expand Down
1 change: 1 addition & 0 deletions app/domain/data/lecture_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from app.domain.data.lecture_unit_dto import LectureUnitDTO


class PyrisLectureDTO(BaseModel):
id: int = Field(alias="id")
title: Optional[str] = Field(alias="title", default=None)
Expand Down
2 changes: 1 addition & 1 deletion app/domain/data/metrics/competency_information_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ class CompetencyInformationDTO(BaseModel):
mastery_threshold: Optional[int] = Field(None, alias="masteryThreshold")

class Config:
populate_by_name = True
populate_by_name = True
6 changes: 4 additions & 2 deletions app/domain/data/metrics/competency_student_metrics_dto.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from typing import Dict, Set, Optional
from typing import Dict, Set
from pydantic import BaseModel, Field
from app.domain.data.metrics.competency_information_dto import CompetencyInformationDTO
from app.domain.data.metrics.competency_jol_dto import CompetencyJolDTO


class CompetencyStudentMetricsDTO(BaseModel):
competency_information: Dict[int, CompetencyInformationDTO] = Field({}, alias="competencyInformation")
competency_information: Dict[int, CompetencyInformationDTO] = Field(
{}, alias="competencyInformation"
)
exercises: Dict[int, Set[int]] = Field({})
lecture_units: Dict[int, Set[int]] = Field({}, alias="lectureUnits")
progress: Dict[int, float] = Field({})
Expand Down
6 changes: 4 additions & 2 deletions app/domain/data/metrics/exercise_student_metrics_dto.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from typing import Optional, Dict, Set
from typing import Dict, Set
from pydantic import BaseModel, Field


class ExerciseStudentMetricsDTO(BaseModel):
average_score: Dict[int, float] = Field({}, alias="averageScore")
score: Dict[int, float] = Field({})
average_latest_submission: Dict[int, float] = Field({}, alias="averageLatestSubmission")
average_latest_submission: Dict[int, float] = Field(
{}, alias="averageLatestSubmission"
)
latest_submission: Dict[int, float] = Field({}, alias="latestSubmission")
completed: Set[int] = Field({})
3 changes: 2 additions & 1 deletion app/domain/data/metrics/lecture_unit_information_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
from pydantic import BaseModel, Field
from datetime import datetime


class LectureUnitInformationDTO(BaseModel):
id: Optional[int] = None
name: Optional[str] = None
release_date: Optional[datetime] = Field(None, alias="releaseDate")
type: Optional[str] = None

class Config:
populate_by_name = True
populate_by_name = True
8 changes: 6 additions & 2 deletions app/domain/data/metrics/lecture_unit_student_metrics_dto.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from typing import Dict, Set, Optional
from pydantic import BaseModel, Field
from app.domain.data.metrics.lecture_unit_information_dto import LectureUnitInformationDTO
from app.domain.data.metrics.lecture_unit_information_dto import (
LectureUnitInformationDTO,
)


class LectureUnitStudentMetricsDTO(BaseModel):
lecture_unit_information: Dict[int, LectureUnitInformationDTO] = Field({}, alias="lectureUnitInformation")
lecture_unit_information: Dict[int, LectureUnitInformationDTO] = Field(
{}, alias="lectureUnitInformation"
)
completed: Optional[Set[int]] = None

class Config:
Expand Down
25 changes: 18 additions & 7 deletions app/domain/data/metrics/student_metrics_dto.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
from typing import Optional
from pydantic import Field, BaseModel
from app.domain.data.metrics.competency_student_metrics_dto import CompetencyStudentMetricsDTO
from app.domain.data.metrics.exercise_student_metrics_dto import ExerciseStudentMetricsDTO
from app.domain.data.metrics.lecture_unit_student_metrics_dto import LectureUnitStudentMetricsDTO
from app.domain.data.metrics.competency_student_metrics_dto import (
CompetencyStudentMetricsDTO,
)
from app.domain.data.metrics.exercise_student_metrics_dto import (
ExerciseStudentMetricsDTO,
)
from app.domain.data.metrics.lecture_unit_student_metrics_dto import (
LectureUnitStudentMetricsDTO,
)


class StudentMetricsDTO(BaseModel):
exercise_metrics: Optional[ExerciseStudentMetricsDTO] = Field(None, alias="exerciseMetrics")
lecture_unit_student_metrics_dto: Optional[LectureUnitStudentMetricsDTO] = Field(None,
alias="lectureUnitStudentMetricsDTO")
competency_metrics: Optional[CompetencyStudentMetricsDTO] = Field(None, alias="competencyMetrics")
exercise_metrics: Optional[ExerciseStudentMetricsDTO] = Field(
None, alias="exerciseMetrics"
)
lecture_unit_student_metrics_dto: Optional[LectureUnitStudentMetricsDTO] = Field(
None, alias="lectureUnitStudentMetricsDTO"
)
competency_metrics: Optional[CompetencyStudentMetricsDTO] = Field(
None, alias="competencyMetrics"
)

class Config:
populate_by_name = True
4 changes: 3 additions & 1 deletion app/domain/data/programming_exercise_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ class ProgrammingLanguage(str, Enum):
class ProgrammingExerciseDTO(BaseModel):
id: int
name: str
programming_language: Optional[str] = Field(alias="programmingLanguage", default=None)
programming_language: Optional[str] = Field(
alias="programmingLanguage", default=None
)
template_repository: Dict[str, str] = Field(alias="templateRepository", default={})
solution_repository: Dict[str, str] = Field(alias="solutionRepository", default={})
test_repository: Dict[str, str] = Field(alias="testRepository", default={})
Expand Down
7 changes: 1 addition & 6 deletions app/domain/pipeline_execution_dto.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
from typing import List, Optional

from pydantic import BaseModel, Field

from app.domain.pipeline_execution_settings_dto import PipelineExecutionSettingsDTO
from app.domain.status.stage_dto import StageDTO
from pydantic import BaseModel


class PipelineExecutionDTO(BaseModel):
Expand Down
4 changes: 3 additions & 1 deletion app/domain/pipeline_execution_settings_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@

class PipelineExecutionSettingsDTO(BaseModel):
authentication_token: str = Field(alias="authenticationToken")
allowed_model_identifiers: Optional[List[str]] = Field(alias="allowedModelIdentifiers", default=[])
allowed_model_identifiers: Optional[List[str]] = Field(
alias="allowedModelIdentifiers", default=[]
)
artemis_base_url: str = Field(alias="artemisBaseUrl")
28 changes: 18 additions & 10 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from fastapi.exceptions import RequestValidationError
from fastapi.responses import ORJSONResponse
from fastapi import FastAPI
from starlette.background import BackgroundTask
from starlette.responses import Response

Expand All @@ -18,29 +16,39 @@

app = FastAPI(default_response_class=ORJSONResponse)


@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
exc_str = f'{exc}'.replace('\n', ' ').replace(' ', ' ')
exc_str = f"{exc}".replace("\n", " ").replace(" ", " ")
logging.error(f"{request}: {exc_str}")
content = {'status_code': 10422, 'message': exc_str, 'data': None}
return JSONResponse(content=content, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)
content = {"status_code": 10422, "message": exc_str, "data": None}
return JSONResponse(
content=content, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY
)


def log_info(req_body, res_body):
logging.info(req_body)
logging.info(res_body)
@app.middleware('http')


@app.middleware("http")
async def some_middleware(request: Request, call_next):
req_body = await request.body()
response = await call_next(request)

res_body = b''
res_body = b""
async for chunk in response.body_iterator:
res_body += chunk

task = BackgroundTask(log_info, req_body, res_body)
return Response(content=res_body, status_code=response.status_code,
headers=dict(response.headers), media_type=response.media_type, background=task)

return Response(
content=res_body,
status_code=response.status_code,
headers=dict(response.headers),
media_type=response.media_type,
background=task,
)


app.include_router(health_router)
Expand Down
Loading

0 comments on commit abe54bc

Please sign in to comment.