Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a716890
improved code api performance: less requests + caching
bigabig Feb 6, 2025
393ee48
improved tag api performance: less requests + caching
bigabig Feb 6, 2025
667a269
removed unnecessary search stats
bigabig Feb 6, 2025
ad3a299
reworked source document tag fetching to do fewer requests
bigabig Feb 6, 2025
7ff773b
improve statistics performance: caching & improved rendering
bigabig Feb 6, 2025
98d3635
DocumentInformation rendering improvements: fetch info on tab switch
bigabig Feb 6, 2025
088628c
removed unused query key: PROJECT_SDOCS
bigabig Feb 6, 2025
6b4beac
removed unnecessary useGetURL hook
bigabig Feb 6, 2025
8ade6d0
fixed bug in span annotator
bigabig Feb 6, 2025
126dec0
improved project & user handling: less requests + caching
bigabig Feb 7, 2025
f8aeccc
hook restructuring
bigabig Feb 7, 2025
b67cc2b
reworked memo endpoints
bigabig Feb 7, 2025
d06a403
updated api
bigabig Feb 7, 2025
5252e08
Memo Rework: Less endpoints & unified access
bigabig Feb 7, 2025
c2fd068
bbox annotation api rework to have less requests
bigabig Feb 8, 2025
65ae8de
fixed undefined
bigabig Feb 8, 2025
a58847b
annotation rework: removed *ReadResolved
bigabig Feb 9, 2025
47ecf83
improved SpanAnnotationHooks
bigabig Feb 9, 2025
8527dbe
reworked sentence annotation hooks
bigabig Feb 10, 2025
deaa6e9
fixed bug: cannot remove span annotations
bigabig Feb 10, 2025
a203216
updated api
bigabig Feb 10, 2025
ade9488
improved whiteboard hooks: less requests
bigabig Feb 10, 2025
1a17ae4
improved timeline analysis hooks: less requests
bigabig Feb 10, 2025
7566a98
rename to CodeFrequencyHooks
bigabig Feb 10, 2025
0027c0a
improved cota hooks: less requests, less query keys
bigabig Feb 10, 2025
37e5c88
documented possible background job rework
bigabig Feb 10, 2025
68baea6
merge Sdoc and Project Metadata Hooks
bigabig Feb 10, 2025
3343c4c
metadata rework: No more SdocMetadataReadResolved, less queries
bigabig Feb 10, 2025
fd5970e
rename to SearchStatisticsHooks
bigabig Feb 10, 2025
8991c37
added comments about TABLE_INFO
bigabig Feb 10, 2025
5dda4cf
moved queryKeys to QueryKey.ts
bigabig Feb 11, 2025
85ff22e
fixed tests, had to change memo endpoint slightly
bigabig Feb 11, 2025
2690661
updated api
bigabig Feb 11, 2025
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
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ repos:
- id: pyright
name: "Pyright"
types: [python]
entry: bash -c 'ENV_NAME=dats source backend/_activate_current_env.sh && pyright $@'
language: system
entry: ./bin/run-pyright.sh
language: script
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v9.11.0
hooks:
Expand Down
12 changes: 0 additions & 12 deletions backend/src/api/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,6 @@ async def skip_limit_params(
return result


async def resolve_code_param(
resolve: bool = Query(
title="Resolve Code",
description="If true, the code_id of the"
" SpanAnnotation gets resolved and replaced"
" by the respective Code entity",
default=True,
),
) -> bool:
return resolve


async def get_db_session() -> AsyncGenerator[Session, None]:
session = SQLService().session_maker()
try:
Expand Down
79 changes: 12 additions & 67 deletions backend/src/api/endpoints/bbox_annotation.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
from typing import List, Union
from typing import List

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

from api.dependencies import (
get_current_user,
get_db_session,
resolve_code_param,
)
from api.util import get_object_memo_for_user, get_object_memos
from app.core.authorization.authz_user import AuthzUser
from app.core.data.crud import Crud
from app.core.data.crud.bbox_annotation import crud_bbox_anno
from app.core.data.dto.bbox_annotation import (
BBoxAnnotationCreate,
BBoxAnnotationRead,
BBoxAnnotationReadResolved,
BBoxAnnotationUpdate,
)
from app.core.data.dto.code import CodeRead
from app.core.data.dto.memo import (
MemoRead,
)

router = APIRouter(
prefix="/bbox", dependencies=[Depends(get_current_user)], tags=["bboxAnnotation"]
Expand All @@ -30,81 +24,69 @@

@router.put(
"",
response_model=Union[BBoxAnnotationRead, BBoxAnnotationReadResolved],
response_model=BBoxAnnotationRead,
summary="Creates a BBoxAnnotation",
)
def add_bbox_annotation(
*,
db: Session = Depends(get_db_session),
bbox: BBoxAnnotationCreate,
resolve_code: bool = Depends(resolve_code_param),
authz_user: AuthzUser = Depends(),
) -> Union[BBoxAnnotationRead, BBoxAnnotationReadResolved]:
) -> BBoxAnnotationRead:
authz_user.assert_in_same_project_as(Crud.SOURCE_DOCUMENT, bbox.sdoc_id)
authz_user.assert_in_same_project_as(Crud.CODE, bbox.code_id)

db_obj = crud_bbox_anno.create(db=db, user_id=authz_user.user.id, create_dto=bbox)
if resolve_code:
return BBoxAnnotationReadResolved.model_validate(db_obj)
else:
return BBoxAnnotationRead.model_validate(db_obj)
return BBoxAnnotationRead.model_validate(db_obj)


@router.get(
"/{bbox_id}",
response_model=Union[BBoxAnnotationRead, BBoxAnnotationReadResolved],
response_model=BBoxAnnotationRead,
summary="Returns the BBoxAnnotation with the given ID.",
)
def get_by_id(
*,
db: Session = Depends(get_db_session),
bbox_id: int,
resolve_code: bool = Depends(resolve_code_param),
authz_user: AuthzUser = Depends(),
) -> Union[BBoxAnnotationRead, BBoxAnnotationReadResolved]:
) -> BBoxAnnotationRead:
authz_user.assert_in_same_project_as(Crud.BBOX_ANNOTATION, bbox_id)

db_obj = crud_bbox_anno.read(db=db, id=bbox_id)
if resolve_code:
return BBoxAnnotationReadResolved.model_validate(db_obj)
else:
return BBoxAnnotationRead.model_validate(db_obj)
return BBoxAnnotationRead.model_validate(db_obj)


@router.patch(
"/{bbox_id}",
response_model=Union[BBoxAnnotationRead, BBoxAnnotationReadResolved],
response_model=BBoxAnnotationRead,
summary="Updates the BBoxAnnotation with the given ID.",
)
def update_by_id(
*,
db: Session = Depends(get_db_session),
bbox_id: int,
bbox_anno: BBoxAnnotationUpdate,
resolve_code: bool = Depends(resolve_code_param),
authz_user: AuthzUser = Depends(),
) -> Union[BBoxAnnotationRead, BBoxAnnotationReadResolved]:
) -> BBoxAnnotationRead:
authz_user.assert_in_same_project_as(Crud.BBOX_ANNOTATION, bbox_id)
authz_user.assert_in_same_project_as(Crud.CODE, bbox_anno.code_id)

db_obj = crud_bbox_anno.update(db=db, id=bbox_id, update_dto=bbox_anno)
if resolve_code:
return BBoxAnnotationReadResolved.model_validate(db_obj)
else:
return BBoxAnnotationRead.model_validate(db_obj)
return BBoxAnnotationRead.model_validate(db_obj)


@router.delete(
"/{bbox_id}",
response_model=Union[BBoxAnnotationRead, BBoxAnnotationReadResolved],
response_model=BBoxAnnotationRead,
summary="Deletes the BBoxAnnotation with the given ID.",
)
def delete_by_id(
*,
db: Session = Depends(get_db_session),
bbox_id: int,
authz_user: AuthzUser = Depends(),
) -> Union[BBoxAnnotationRead, BBoxAnnotationReadResolved]:
) -> BBoxAnnotationRead:
authz_user.assert_in_same_project_as(Crud.BBOX_ANNOTATION, bbox_id)

db_obj = crud_bbox_anno.remove(db=db, id=bbox_id)
Expand All @@ -128,43 +110,6 @@ def get_code(
return CodeRead.model_validate(bbox_db_obj.code)


@router.get(
"/{bbox_id}/memo",
response_model=List[MemoRead],
summary="Returns the Memos attached to the BBoxAnnotation with the given ID if it exists.",
)
def get_memos(
*,
db: Session = Depends(get_db_session),
bbox_id: int,
authz_user: AuthzUser = Depends(),
) -> List[MemoRead]:
authz_user.assert_in_same_project_as(Crud.BBOX_ANNOTATION, bbox_id)

db_obj = crud_bbox_anno.read(db=db, id=bbox_id)
# TODO how to authorize memo access here?
return get_object_memos(db_obj=db_obj)


@router.get(
"/{bbox_id}/memo/user",
response_model=MemoRead,
summary=(
"Returns the Memo attached to the BBoxAnnotation with the given ID of the logged-in User if it exists."
),
)
def get_user_memo(
*,
db: Session = Depends(get_db_session),
bbox_id: int,
authz_user: AuthzUser = Depends(),
) -> MemoRead:
authz_user.assert_in_same_project_as(Crud.BBOX_ANNOTATION, bbox_id)

db_obj = crud_bbox_anno.read(db=db, id=bbox_id)
return get_object_memo_for_user(db_obj=db_obj, user_id=authz_user.user.id)


@router.get(
"/code/{code_id}/user",
response_model=List[BBoxAnnotationRead],
Expand Down
42 changes: 0 additions & 42 deletions backend/src/api/endpoints/code.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
from typing import List

from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

from api.dependencies import get_current_user, get_db_session
from api.util import get_object_memo_for_user, get_object_memos
from app.core.authorization.authz_user import AuthzUser
from app.core.data.crud import Crud
from app.core.data.crud.code import crud_code
from app.core.data.dto.code import CodeCreate, CodeRead, CodeUpdate
from app.core.data.dto.memo import (
MemoRead,
)

router = APIRouter(
prefix="/code", dependencies=[Depends(get_current_user)], tags=["code"]
Expand Down Expand Up @@ -87,39 +81,3 @@ def delete_by_id(

db_obj = crud_code.remove(db=db, id=code_id)
return CodeRead.model_validate(db_obj)


@router.get(
"/{code_id}/memo",
response_model=List[MemoRead],
summary="Returns the Memo attached to the Code with the given ID if it exists.",
)
def get_memos(
*,
db: Session = Depends(get_db_session),
code_id: int,
authz_user: AuthzUser = Depends(),
) -> List[MemoRead]:
authz_user.assert_in_same_project_as(Crud.CODE, code_id)

db_obj = crud_code.read(db=db, id=code_id)
return get_object_memos(db_obj=db_obj)


@router.get(
"/{code_id}/memo/user",
response_model=MemoRead,
summary=(
"Returns the Memo attached to the Code with the given ID of the logged-in User if it exists."
),
)
def get_user_memo(
*,
db: Session = Depends(get_db_session),
code_id: int,
authz_user: AuthzUser = Depends(),
) -> MemoRead:
authz_user.assert_in_same_project_as(Crud.CODE, code_id)

db_obj = crud_code.read(db=db, id=code_id)
return get_object_memo_for_user(db_obj=db_obj, user_id=authz_user.user.id)
40 changes: 0 additions & 40 deletions backend/src/api/endpoints/document_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from sqlalchemy.orm import Session

from api.dependencies import get_current_user, get_db_session
from api.util import get_object_memo_for_user, get_object_memos
from api.validation import Validate
from app.core.authorization.authz_user import AuthzUser
from app.core.data.crud import Crud
Expand All @@ -16,9 +15,6 @@
SourceDocumentDocumentTagLinks,
SourceDocumentDocumentTagMultiLink,
)
from app.core.data.dto.memo import (
MemoRead,
)

router = APIRouter(
prefix="/doctag", dependencies=[Depends(get_current_user)], tags=["documentTag"]
Expand Down Expand Up @@ -228,42 +224,6 @@ def delete_by_id(
return DocumentTagRead.model_validate(db_obj)


@router.get(
"/{tag_id}/memo",
response_model=List[MemoRead],
summary="Returns the Memos attached to the DocumentTag with the given ID if it exists.",
)
def get_memos(
*,
db: Session = Depends(get_db_session),
tag_id: int,
authz_user: AuthzUser = Depends(),
) -> List[MemoRead]:
authz_user.assert_in_same_project_as(Crud.DOCUMENT_TAG, tag_id)

db_obj = crud_document_tag.read(db=db, id=tag_id)
return get_object_memos(db_obj=db_obj)


@router.get(
"/{tag_id}/memo/user",
response_model=MemoRead,
summary=(
"Returns the Memo attached to the document tag with the given ID of the logged-in User if it exists."
),
)
def get_user_memo(
*,
db: Session = Depends(get_db_session),
tag_id: int,
authz_user: AuthzUser = Depends(),
) -> MemoRead:
authz_user.assert_in_same_project_as(Crud.DOCUMENT_TAG, tag_id)

db_obj = crud_document_tag.read(db=db, id=tag_id)
return get_object_memo_for_user(db_obj=db_obj, user_id=authz_user.user.id)


@router.get(
"/{tag_id}/sdocs",
response_model=List[int],
Expand Down
Loading
Loading