Skip to content

Commit

Permalink
Switch from django-types to django-stubs
Browse files Browse the repository at this point in the history
  • Loading branch information
medihack committed Aug 28, 2024
1 parent 1e98f56 commit 86d9a8d
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 100 deletions.
3 changes: 0 additions & 3 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
- Use django-stubs instead of django-types (also ADIT)
- Use Alpine directive instead data for age range slider
- Rename all derived models from AppSettings (to be congruent with ADIT)
- Make notes.urls.py restful
- Rename patient_birth_date to patient_birthdate (sounds better, but DICOM uses Patient Birth Date)
- Check if for RAG ranking should be turned off for performance improvements (and using some fixed sort order)
- Some present provider.max_results to the user somehow, especially important if the query results (step 1) is larger
- task control panel
Expand Down Expand Up @@ -68,7 +66,6 @@

## Maybe

- Consider Manticore or Quickwit as FTS
- Look into distanceThreshold when using semantic/hybrid search
-- In normal nearestNeighbor search every document is included as all documents are neighbors
-- That is why we currently only use semantic stuff as ranking algorithm
Expand Down
110 changes: 80 additions & 30 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ authors = ["medihack <[email protected]>"]
license = "GPL-3.0-or-later"

[tool.poetry.dependencies]
adit-radis-shared = {git = "https://github.com/openradx/adit-radis-shared.git", rev = "v0.6.3"}
adit-radis-shared = { git = "https://github.com/openradx/adit-radis-shared.git", rev = "v0.6.5" }
adrf = "^0.1.4"
aiofiles = "^23.1.0"
asyncinotify = "^4.0.1"
Expand Down Expand Up @@ -50,9 +50,9 @@ django-browser-reload = "^1.11.0"
django-debug-permissions = "^1.0.0"
django-debug-toolbar = "^4.1.0"
django-fastdev = "^1.9.0"
django-stubs = "^5.0.4"
django-test-migrations = "^1.3.0"
django-types = "^0.19.1"
djangorestframework-types = "^0.8.0"
djangorestframework-stubs = "^3.15.0"
djlint = "^1.19.16"
factory-boy = "^3.1.0"
Faker = "^25.4.0"
Expand Down
8 changes: 2 additions & 6 deletions radis/chats/models.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import logging
from typing import TYPE_CHECKING, Callable
from typing import Callable

from adit_radis_shared.common.models import AppSettings
from django.conf import settings
from django.db import models

if TYPE_CHECKING:
from django.db.models.manager import RelatedManager

logger = logging.getLogger(__name__)


Expand All @@ -24,8 +21,7 @@ class Chat(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

if TYPE_CHECKING:
messages = RelatedManager["ChatMessage"]()
messages: models.QuerySet["ChatMessage"]

def __str__(self):
return f"Chat {self.pk}"
Expand Down
2 changes: 1 addition & 1 deletion radis/chats/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.contrib.auth.decorators import login_required
from django.core.exceptions import SuspiciousOperation
from django.http import HttpResponse
from django.shortcuts import aget_object_or_404, get_object_or_404, redirect, render # type: ignore
from django.shortcuts import aget_object_or_404, get_object_or_404, redirect, render
from django.urls import reverse
from django.views.decorators.http import require_GET, require_POST
from django_htmx.http import push_url
Expand Down
12 changes: 5 additions & 7 deletions radis/core/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Callable
from typing import Callable

from django.conf import settings
from django.db import models
Expand All @@ -7,9 +7,6 @@

from radis.core.utils.model_utils import reset_tasks

if TYPE_CHECKING:
from django.db.models.manager import RelatedManager


class AnalysisJob(models.Model):
class Status(models.TextChoices):
Expand All @@ -23,9 +20,6 @@ class Status(models.TextChoices):
WARNING = "WA", "Warning"
FAILURE = "FA", "Failure"

if TYPE_CHECKING:
tasks = RelatedManager["AnalysisTask"]()

default_priority: int
urgent_priority: int
continuous_job: bool
Expand All @@ -46,6 +40,8 @@ class Status(models.TextChoices):
started_at = models.DateTimeField(null=True, blank=True)
ended_at = models.DateTimeField(null=True, blank=True)

tasks: models.QuerySet["AnalysisTask"]

class Meta:
abstract = True
indexes = [models.Index(fields=["owner", "status"])]
Expand Down Expand Up @@ -221,6 +217,8 @@ class Meta:
def __str__(self) -> str:
return f"{self.__class__.__name__} [ID {self.id} (Job ID {self.job.id})]"

def get_absolute_url(self) -> str: ...

def delay(self) -> None: ...

@property
Expand Down
2 changes: 1 addition & 1 deletion radis/pgsearch/providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pyparsing as pp
from django.contrib.postgres.search import (
SearchHeadline, # type: ignore
SearchHeadline,
SearchQuery,
SearchRank,
)
Expand Down
2 changes: 1 addition & 1 deletion radis/rag/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class QuestionResultInlineFormset(forms.BaseInlineFormSet):
def add_fields(self, form: forms.Form, index: int) -> None:
super().add_fields(form, index)
rag_instance = self.instance
form.fields["question"].queryset = rag_instance.task.job.questions.all()
form.fields["question"].queryset = rag_instance.task.job.questions.all() # type: ignore


class QuestionResultInline(admin.StackedInline):
Expand Down
4 changes: 2 additions & 2 deletions radis/rag/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ def __init__(self, *args, **kwargs):
self.fields["provider"].widget = forms.Select(
choices=[(provider.name, provider.name) for provider in retrieval_providers.values()]
)
self.fields["language"].choices = [
self.fields["language"].choices = [ # type: ignore
(language.pk, LANGUAGE_LABELS[language.code])
for language in Language.objects.order_by("code")
]
self.fields["modalities"].choices = [
self.fields["modalities"].choices = [ # type: ignore
(modality.pk, modality.code)
for modality in Modality.objects.filter(filterable=True).order_by("code")
]
Expand Down
20 changes: 7 additions & 13 deletions radis/rag/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Callable
from typing import Callable

from adit_radis_shared.common.models import AppSettings
from django.conf import settings
Expand All @@ -11,9 +11,6 @@
from radis.core.models import AnalysisJob, AnalysisTask
from radis.reports.models import Language, Modality, Report

if TYPE_CHECKING:
from django.db.models.manager import RelatedManager


# TODO: Rename to RagSettings (as in ADIT)
class RagAppSettings(AppSettings):
Expand Down Expand Up @@ -45,9 +42,8 @@ class RagJob(AnalysisJob):
age_from = models.IntegerField(null=True, blank=True)
age_till = models.IntegerField(null=True, blank=True)

if TYPE_CHECKING:
tasks = RelatedManager["RagTask"]()
questions = RelatedManager["Question"]()
tasks: models.QuerySet["RagTask"]
questions: models.QuerySet["Question"]

def __str__(self) -> str:
return f"RagJob {self.id}"
Expand Down Expand Up @@ -82,11 +78,10 @@ def __str__(self) -> str:


class RagTask(AnalysisTask):
if TYPE_CHECKING:
rag_instances = RelatedManager["RagInstance"]()

job = models.ForeignKey(RagJob, on_delete=models.CASCADE, related_name="tasks")

rag_instances: models.QuerySet["RagInstance"]

def get_absolute_url(self) -> str:
return reverse("rag_task_detail", args=[self.id])

Expand All @@ -105,9 +100,6 @@ class Result(models.TextChoices):
ACCEPTED = "A", "Accepted"
REJECTED = "R", "Rejected"

if TYPE_CHECKING:
results = RelatedManager["QuestionResult"]()

id: int
text = models.TextField()
report_id: int
Expand All @@ -117,6 +109,8 @@ class Result(models.TextChoices):
get_overall_result_display: Callable[[], str]
task = models.ForeignKey(RagTask, on_delete=models.CASCADE, related_name="rag_instances")

results: models.QuerySet["QuestionResult"]

def __str__(self) -> str:
return f"RagInstance {self.id}"

Expand Down
2 changes: 1 addition & 1 deletion radis/rag/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def process_rag_job(job_id: int) -> None:
study_date_from=job.study_date_from,
study_date_till=job.study_date_till,
study_description=job.study_description,
patient_sex=job.patient_sex, # type: ignore
patient_sex=job.patient_sex,
patient_age_from=job.age_from,
patient_age_till=job.age_till,
),
Expand Down
2 changes: 1 addition & 1 deletion radis/rag/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def get_context_data(self, form, **kwargs):
context["helper"] = QuestionFormSetHelper()

data = self.get_cleaned_data_for_step(RagJobWizardView.SEARCH_STEP)
assert data
assert data and isinstance(data, dict)
context["provider"] = retrieval_providers[data["provider"]]

active_group = self.request.user.active_group
Expand Down
Loading

0 comments on commit 86d9a8d

Please sign in to comment.