generated from MinBZK/python-project-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding more structure and database support
- Loading branch information
1 parent
32663ca
commit b4257ba
Showing
24 changed files
with
263 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
from fastapi import APIRouter | ||
|
||
from tad.api.routes import health, root | ||
from tad.api.routes import health, pages, root, tasks | ||
|
||
api_router = APIRouter() | ||
api_router.include_router(root.router) | ||
api_router.include_router(health.router, prefix="/health", tags=["health"]) | ||
api_router.include_router(pages.router, prefix="/pages", tags=["pages"]) | ||
api_router.include_router(tasks.router, prefix="/tasks", tags=["tasks"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from fastapi import APIRouter, Request | ||
from fastapi.responses import HTMLResponse | ||
from fastapi.templating import Jinja2Templates | ||
|
||
from tad.services.statuses import StatusesService | ||
from tad.services.tasks import TasksService | ||
|
||
tasks_service = TasksService() | ||
statuses_service = StatusesService() | ||
router = APIRouter() | ||
templates = Jinja2Templates(directory="tad/site/templates") | ||
|
||
|
||
@router.get("/", response_class=HTMLResponse) | ||
async def default_layout(request: Request): | ||
context = { | ||
"page_title": "This is the page title", | ||
"tasks_service": tasks_service, | ||
"statuses_service": statuses_service, | ||
} | ||
return templates.TemplateResponse(request=request, name="default_layout.jinja", context=context) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
from fastapi import APIRouter, Request | ||
from fastapi.responses import HTMLResponse | ||
from fastapi.templating import Jinja2Templates | ||
|
||
from tad.services.tasks import TasksService | ||
|
||
router = APIRouter() | ||
|
||
tasks_service = TasksService() | ||
templates = Jinja2Templates(directory="tad/site/templates") | ||
|
||
|
||
@router.get("/") | ||
async def test(): | ||
return [{"username": "Rick"}, {"username": "Morty"}] | ||
|
||
|
||
@router.post("/move", response_class=HTMLResponse) | ||
async def move_task(request: Request): | ||
json = await request.json() | ||
|
||
print(json) | ||
task = tasks_service.move_task( | ||
int(json["taskId"]), int(json["statusId"]), json["previousSiblingId"], json["nextSiblingId"] | ||
) | ||
return templates.TemplateResponse(request=request, name="task.jinja", context={"task": task}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from typing import ClassVar | ||
|
||
|
||
class Singleton(type): | ||
"""The Singleton metaclass can be used to mark classes as singleton. | ||
Based on https://stackoverflow.com/questions/6760685/what-is-the-best-way-of-implementing-singleton-in-python | ||
Usage: class Classname(metaclass=Singleton): | ||
""" | ||
|
||
_instances = ClassVar[{}] | ||
|
||
def __call__(cls, *args, **kwargs): | ||
if cls not in cls._instances: | ||
cls._instances[cls] = super().__call__(*args, **kwargs) | ||
return cls._instances[cls] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import logging | ||
from collections.abc import Sequence | ||
|
||
from sqlmodel import Session, select | ||
|
||
from tad.core.db import engine | ||
from tad.core.singleton import Singleton | ||
from tad.models import Status | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class StatusesRepository(metaclass=Singleton): | ||
# TODO find out how to reuse Session | ||
|
||
def __init__(self): | ||
logger.info("Hello world from statuses repo") | ||
statuses = self.find_all() | ||
if len(statuses) == 0: | ||
self.__add_test_statuses() | ||
|
||
def __add_test_statuses(self): | ||
with Session(engine) as session: | ||
session.add(Status(id=1, name="todo", sort_order=1)) | ||
session.add(Status(id=2, name="in_progress", sort_order=2)) | ||
session.add(Status(id=3, name="review", sort_order=3)) | ||
session.add(Status(id=4, name="done", sort_order=4)) | ||
session.commit() | ||
|
||
def find_all(self) -> Sequence[Status]: | ||
with Session(engine) as session: | ||
statement = select(Status) | ||
return session.exec(statement).all() | ||
|
||
def save(self, status) -> Status: | ||
with Session(engine) as session: | ||
session.add(status) | ||
session.commit() | ||
session.refresh(status) | ||
return status | ||
|
||
def find_by_id(self, status_id) -> Status: | ||
with Session(engine) as session: | ||
statement = select(Status).where(Status.id == status_id) | ||
return session.exec(statement).one() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
from collections.abc import Sequence | ||
|
||
from sqlmodel import Session, select | ||
|
||
from tad.core.db import engine | ||
from tad.core.singleton import Singleton | ||
from tad.models import Task | ||
|
||
|
||
class TasksRepository(metaclass=Singleton): | ||
def __init__(self): | ||
tasks = self.find_all() | ||
if len(tasks) == 0: | ||
self.__add_test_tasks() | ||
|
||
def __add_test_tasks(self): | ||
with Session(engine) as session: | ||
session.add( | ||
Task( | ||
status_id=1, | ||
title="IAMA", | ||
description="Impact Assessment Mensenrechten en Algoritmes", | ||
sort_order=10, | ||
) | ||
) | ||
session.add(Task(status_id=1, title="SHAP", description="SHAP", sort_order=20)) | ||
session.add(Task(status_id=1, title="This is title 3", description="This is description 3", sort_order=30)) | ||
session.commit() | ||
|
||
def find_all(self) -> Sequence[Task]: | ||
"""Returns all the tasks from the repository.""" | ||
with Session(engine) as session: | ||
statement = select(Task) | ||
return session.exec(statement).all() | ||
|
||
def find_by_status_id(self, status_id) -> Sequence[Task]: | ||
with Session(engine) as session: | ||
statement = select(Task).where(Task.status_id == status_id).order_by(Task.sort_order) | ||
return session.exec(statement).all() | ||
|
||
def save(self, task) -> Task: | ||
with Session(engine) as session: | ||
session.add(task) | ||
session.commit() | ||
session.refresh(task) | ||
return task | ||
|
||
def find_by_id(self, task_id) -> Task: | ||
with Session(engine) as session: | ||
statement = select(Task).where(Task.id == task_id) | ||
return session.exec(statement).one() |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import logging | ||
|
||
from tad.core.singleton import Singleton | ||
from tad.repositories.statuses import StatusesRepository | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class StatusesService(metaclass=Singleton): | ||
__statuses_repository = StatusesRepository() | ||
|
||
def __init__(self): | ||
# TODO find out why logging is not visible | ||
print("I am created, hello world") | ||
|
||
def get_status(self, status_id): | ||
return self.__statuses_repository.find_by_id(status_id) | ||
|
||
def get_statuses(self) -> []: | ||
return self.__statuses_repository.find_all() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import logging | ||
|
||
from tad.core.singleton import Singleton | ||
from tad.models.task import Task | ||
from tad.models.user import User | ||
from tad.repositories.tasks import TasksRepository | ||
from tad.services.statuses import StatusesService | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class TasksService(metaclass=Singleton): | ||
__tasks_repository = TasksRepository() | ||
__statuses_service = StatusesService() | ||
|
||
def __init__(self): | ||
pass | ||
|
||
def get_tasks(self, status_id): | ||
return self.__tasks_repository.find_by_status_id(status_id) | ||
|
||
def assign_task(self, task: Task, user: User): | ||
task.user_id = user.id | ||
self.__tasks_repository.save(task) | ||
|
||
def move_task(self, task_id, status_id, previous_sibling_id, next_sibling_id) -> Task: | ||
status = self.__statuses_service.get_status(status_id) | ||
task = self.__tasks_repository.find_by_id(task_id) | ||
|
||
if status.name == "done": | ||
# TODO implement logic for done | ||
logging.warning("Task is done, we need to update a system card") | ||
|
||
# assign the task to the current user | ||
if status.name == "in_progress": | ||
task.user_id = 1 | ||
|
||
# update the status for the task (this may not be needed if the status has not changed) | ||
task.status_id = status_id | ||
|
||
# update order position of the card | ||
if not previous_sibling_id and not next_sibling_id: | ||
task.sort_order = 10 | ||
elif previous_sibling_id and next_sibling_id: | ||
previous_task = self.__tasks_repository.find_by_id(int(previous_sibling_id)) | ||
next_task = self.__tasks_repository.find_by_id(int(next_sibling_id)) | ||
new_sort_order = previous_task.sort_order + ((next_task.sort_order - previous_task.sort_order) / 2) | ||
task.sort_order = new_sort_order | ||
elif previous_sibling_id and not next_sibling_id: | ||
previous_task = self.__tasks_repository.find_by_id(int(previous_sibling_id)) | ||
task.sort_order = previous_task.sort_order + 10 | ||
elif not previous_sibling_id and next_sibling_id: | ||
next_task = self.__tasks_repository.find_by_id(int(next_sibling_id)) | ||
task.sort_order = next_task.sort_order / 2 | ||
|
||
task = self.__tasks_repository.save(task) | ||
|
||
return task |
Oops, something went wrong.