Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Pyproject toml refactor #24

Merged
merged 17 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ jobs:
run: pip install -r backend/requirements.txt
- name: Lint code
run: ruff check backend
- name: Run Pyright
run: pyright
2 changes: 1 addition & 1 deletion backend/db/errors/database_errors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class ItemNotFoundError(Exception):

def __init__(self, message: str):
def __init__(self, message: str) -> None:
super().__init__(message)
11 changes: 6 additions & 5 deletions backend/db/implementation/SqlLesgeverDAO.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@


class SqlTeacherDAO(TeacherDAO):
def get_teacher(self, ident: int):
teacher: Teacher = Teacher.query.get(ident=ident)
def get_teacher(self, ident: int) -> TeacherDataclass:
teacher: Teacher | None = Teacher.query.get(ident=ident)

if not teacher:
raise ItemNotFoundError("TeacherDataclass with given id not found.")
msg = f"Teacher with id {ident} not found"
raise ItemNotFoundError(msg)

return teacher.to_domain_model()

def get_all_teachers(self) -> list[TeacherDataclass]:
teachers: list[Teacher] = Teacher.query.all()
return [lesgever.to_domain_model() for lesgever in teachers]

def create_teacher(self, teacher: TeacherDataclass):
new_teacher = Teacher(name=teacher.name)
def create_teacher(self, teacher: TeacherDataclass) -> None:
new_teacher = Teacher(name=teacher.name, email=teacher.email)

db.session.add(new_teacher)
db.session.commit()
Expand Down
20 changes: 9 additions & 11 deletions backend/db/implementation/SqlVakDAO.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,29 @@


class SqlSubjectDAO(SubjectDAO):
def create_subject(self, subject: SubjectDataclass, teacher_id: int):
teacher = Teacher.query.get(teacher_id)
def create_subject(self, subject: SubjectDataclass) -> None:

if not teacher:
raise ItemNotFoundError(f"De teacher met id {teacher_id} kon niet in de databank gevonden worden")

new_subject = Subject(name=subject.name, teacher=teacher)
new_subject = Subject(name=subject.name)

db.session.add(new_subject)
db.session.commit()

subject.id = new_subject.id

def get_subject(self, teacher_id: int):
subject = Subject.query.get(teacher_id)
def get_subject(self, subject_id: int) -> SubjectDataclass:
subject = Subject.query.get(subject_id)
if not subject:
raise ItemNotFoundError(f"De lesgever met id {teacher_id} kon niet in de databank gevonden worden")
msg = f"Het vak met id {subject_id} kon niet in de databank gevonden worden"
raise ItemNotFoundError(msg)

return subject.to_domain_model()

def get_subjects(self, teacher_id: int) -> list[SubjectDataclass]:
teacher: Teacher = Teacher.query.get(ident=teacher_id)
teacher: Teacher | None = Teacher.query.get(ident=teacher_id)

if not teacher:
raise ItemNotFoundError(f"De teacher met id {teacher_id} kon niet in de databank gevonden worden")
msg = f"De teacher met id {teacher_id} kon niet in de databank gevonden worden"
raise ItemNotFoundError(msg)

subjects: list[Subject] = teacher.subjects
return [vak.to_domain_model() for vak in subjects]
12 changes: 6 additions & 6 deletions backend/db/interface/SubjectDAO.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@

class SubjectDAO(ABC):
@abstractmethod
def create_subject(self, subject: SubjectDataclass, teacher_id: int):
def create_subject(self, subject: SubjectDataclass) -> None:
"""
Creëert een nieuw SubjectDataclass in de database en associeert het met een TeacherDataclass.

:param subject: De SubjectDataclass domeinmodel-instantie die aan de database moet worden toegevoegd.
:param teacher_id: De identificatie van de TeacherDataclass waarmee het SubjectDataclass geassocieerd wordt.
:raises: ItemNotFoundException: Als er geen TeacherDataclass met de opgegeven `teacher_id` in de database is.
"""
raise NotImplementedError()
raise NotImplementedError

@abstractmethod
def get_subject(self, teacher_id: int):
def get_subject(self, subject_id: int) -> SubjectDataclass:
"""
Haalt een SubjectDataclass op aan de hand van zijn identificatie.

:param teacher_id: De identificatie van het op te halen SubjectDataclass.
:param subject_id: De identificatie van het op te halen SubjectDataclass.
:raises ItemNotFoundException: Als er geen SubjectDataclass met de opgegeven `ident` in de database bestaat.
:returns: De domeinmodel-instantie van het opgehaalde SubjectDataclass.
"""
raise NotImplementedError()
raise NotImplementedError

@abstractmethod
def get_subjects(self, teacher_id: int) -> list[SubjectDataclass]:
Expand All @@ -34,4 +34,4 @@ def get_subjects(self, teacher_id: int) -> list[SubjectDataclass]:
:param teacher_id: De teacher waarvan de subjects opgehaald moeten worden.
:return: Een lijst van subjects die door de gegeven teacher worden gegeven.
"""
raise NotImplementedError()
raise NotImplementedError
8 changes: 4 additions & 4 deletions backend/db/interface/TeacherDAO.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def get_teacher(self, ident: int) -> TeacherDataclass:
:return: De teacher die overeenkomt met de gegeven id.
:raises ItemNotFoundException: Als geen teacher met het gegeven id gevonden werd.
"""
raise NotImplementedError()
raise NotImplementedError

@abstractmethod
def get_all_teachers(self) -> list[TeacherDataclass]:
Expand All @@ -22,13 +22,13 @@ def get_all_teachers(self) -> list[TeacherDataclass]:

:return: Een lijst van alle lesgevers.
"""
raise NotImplementedError()
raise NotImplementedError

@abstractmethod
def create_teacher(self, teacher: TeacherDataclass):
def create_teacher(self, teacher: TeacherDataclass) -> None:
"""
Maakt een nieuwe teacher aan.

:param teacher: De teacher die aangemaakt moet worden.
"""
raise NotImplementedError()
raise NotImplementedError
21 changes: 15 additions & 6 deletions backend/db/models/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from dataclasses import dataclass
from datetime import datetime

from sqlalchemy import Column, ForeignKey, Table
Expand All @@ -14,15 +15,17 @@
from domain.models.UserDataclass import UserDataclass


@dataclass()
class User(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
name: Mapped[str]
email: Mapped[str]
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)

def to_domain_model(self) -> UserDataclass:
return UserDataclass(id=self.id, name=self.name, email=self.email)


@dataclass()
class Admin(User):
id: Mapped[int] = mapped_column(ForeignKey(User.id), primary_key=True)

Expand Down Expand Up @@ -50,6 +53,7 @@ def to_domain_model(self) -> AdminDataclass:
)


@dataclass()
class Teacher(User):
id: Mapped[int] = mapped_column(ForeignKey(User.id), primary_key=True)
subjects: Mapped[list["Subject"]] = relationship(secondary=teachers_subjects, back_populates="teachers")
Expand All @@ -58,6 +62,7 @@ def to_domain_model(self) -> TeacherDataclass:
return TeacherDataclass(id=self.id, name=self.name, email=self.email)


@dataclass()
class Student(User):
id: Mapped[int] = mapped_column(ForeignKey(User.id), primary_key=True)
subjects: Mapped[list["Subject"]] = relationship(secondary=students_subjects, back_populates="students")
Expand All @@ -68,9 +73,10 @@ def to_domain_model(self) -> StudentDataclass:
return StudentDataclass(id=self.id, name=self.name, email=self.email)


@dataclass()
class Subject(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
name: Mapped[str]
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
teachers: Mapped[list[Teacher]] = relationship(secondary=teachers_subjects, back_populates="subjects")
students: Mapped[list[Student]] = relationship(secondary=students_subjects, back_populates="subjects")
projects: Mapped[list["Project"]] = relationship(back_populates="subject")
Expand All @@ -79,14 +85,15 @@ def to_domain_model(self) -> SubjectDataclass:
return SubjectDataclass(id=self.id, name=self.name)


@dataclass()
class Project(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
name: Mapped[str]
deadline: Mapped[datetime]
archived: Mapped[bool]
requirements: Mapped[str]
visible: Mapped[bool]
max_students: Mapped[int]
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
subject_id: Mapped[int] = mapped_column(ForeignKey(Subject.id))
subject: Mapped[Subject] = relationship(back_populates="projects")
groups: Mapped[list["Group"]] = relationship(back_populates="project")
Expand All @@ -104,6 +111,7 @@ def to_domain_model(self) -> ProjectDataclass:
)


@dataclass()
class Group(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
project_id: Mapped[int] = mapped_column(ForeignKey(Project.id))
Expand All @@ -115,15 +123,16 @@ def to_domain_model(self) -> GroupDataclass:
return GroupDataclass(id=self.id, project_id=self.project_id)


@dataclass()
class Submission(db.Model):
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
date_time: Mapped[datetime]
state: Mapped[SubmissionState]
message: Mapped[str]
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
group_id: Mapped[int] = mapped_column(ForeignKey(Group.id))
group: Mapped[Group] = relationship(back_populates="submissions")
student_id: Mapped[int] = mapped_column(ForeignKey(Student.id))
student: Mapped[Student] = relationship(back_populates="submissions")
state: Mapped[SubmissionState]
message: Mapped[str]

def to_domain_model(self) -> SubmissionDataclass:
return SubmissionDataclass(
Expand Down
3 changes: 1 addition & 2 deletions backend/domain/models/base_model.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import dataclasses
from abc import ABC
from dataclasses import dataclass


@dataclass()
class JsonRepresentable(ABC):
class JsonRepresentable:
def to_dict(self) -> dict:
return dataclasses.asdict(self)
15 changes: 9 additions & 6 deletions backend/domain/validation/SubjectValidator.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
from domain.validation.ValidationResult import ValidationResult
from domain.validation.ValidationResult import ValidationError, ValidationResult, ValidationSuccess


class SubjectValidator:
@staticmethod
def validate(json_data: dict):
result = ValidationResult()
def validate(json_data: dict) -> ValidationResult:

name = json_data.get("name")
teacher_id = json_data.get("teacher_id")

errors: list[str] = []
if not name:
result.add_error("Veld 'name' ontbreekt.")
errors.append("Veld 'name' ontbreekt.")

if not teacher_id:
result.add_error("Veld 'teacher_id' ontbreekt.")
errors.append("Veld 'teacher_id' ontbreekt.")

return result
if len(errors) > 0:
return ValidationError(errors)

return ValidationSuccess()
13 changes: 8 additions & 5 deletions backend/domain/validation/TeacherValidator.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
from domain.validation.ValidationResult import ValidationResult
from domain.validation.ValidationResult import ValidationError, ValidationResult, ValidationSuccess


class TeacherValidator:
@staticmethod
def validate(json_data: dict):
result = ValidationResult()
def validate(json_data: dict) -> ValidationResult:

name = json_data.get("name")

errors: list[str] = []
if not name:
result.add_error("Veld 'name' ontbreekt.")
errors.append("Veld 'name' ontbreekt.")

return result
if len(errors) > 0:
return ValidationError(errors)

return ValidationSuccess()
31 changes: 22 additions & 9 deletions backend/domain/validation/ValidationResult.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
class ValidationResult:
def __init__(self, is_ok: bool = True, errors: list[str] | None = None):
self.is_ok = is_ok
self.errors = errors if errors is not None else []
from abc import ABC, abstractmethod

def add_error(self, error: str):
self.is_ok = False
self.errors.append(error)

def __bool__(self):
return self.is_ok
class ValidationResult(ABC):

errors: list[str]

@abstractmethod
def __bool__(self) -> bool:
raise NotImplementedError


class ValidationSuccess(ValidationResult):

def __bool__(self) -> bool:
return True


class ValidationError(ValidationResult):
def __init__(self, errors: list[str]) -> None:
self.errors = errors

def __bool__(self) -> bool:
return False
Loading