Skip to content

Commit 015cb57

Browse files
committed
Merge branch 'main' of github.com:RolnickLab/antenna into 706-support-for-reprocessing-detections-and-skipping-detector
2 parents 0a80074 + ac4f705 commit 015cb57

File tree

65 files changed

+2015
-285
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2015
-285
lines changed

.envs/.ci/.django

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ MINIO_DEFAULT_BUCKET=ami-ci
1616
MINIO_STORAGE_USE_HTTPS=False
1717
MINIO_TEST_BUCKET=ami-test-ci
1818
MINIO_BROWSER_REDIRECT_URL=http://minio:9001
19+
20+
DEFAULT_PROCESSING_SERVICE_NAME=Test Processing Service
21+
DEFAULT_PROCESSING_SERVICE_ENDPOINT=http://ml_backend:2000

.envs/.local/.django

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,8 @@ MINIO_DEFAULT_BUCKET=ami
3737
MINIO_STORAGE_USE_HTTPS=False
3838
MINIO_TEST_BUCKET=ami-test
3939
MINIO_BROWSER_REDIRECT_URL=http://minio:9001
40+
41+
# Default processing service (local)
42+
DEFAULT_PROCESSING_SERVICE_NAME=Local Processing Service
43+
DEFAULT_PROCESSING_SERVICE_ENDPOINT=http://ml_backend:2000
44+
# DEFAULT_PIPELINES_ENABLED=random,constant # When set to None, all pipelines will be enabled.

.envs/.production/.django-example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,8 @@ DJANGO_ACCOUNT_ALLOW_REGISTRATION=True
5353
# Gunicorn
5454
# ------------------------------------------------------------------------------
5555
WEB_CONCURRENCY=4
56+
57+
# Default processing service
58+
DEFAULT_PROCESSING_SERVICE_NAME="AMI Data Companion"
59+
DEFAULT_PROCESSING_SERVICE_ENDPOINT=https://ml.antenna.insectai.org/
60+
DEFAULT_PIPELINES_ENABLED=global_moths_2024,quebec_vermont_moths_2023,panama_moths_2023,uk_denmark_moths_2023

ami/base/views.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,23 @@ class ProjectMixin:
2222
def get_active_project(self) -> Project:
2323
from ami.base.serializers import SingleParamSerializer
2424

25+
param = "project_id"
26+
2527
project_id = None
2628
# Extract from URL `/projects/` is in the url path
2729
if "/projects/" in self.request.path:
2830
project_id = self.kwargs.get("pk")
2931

3032
# If not in URL, try query parameters
3133
if not project_id:
32-
if self.require_project:
33-
project_id = SingleParamSerializer[int].clean(
34-
param_name="project_id",
35-
field=serializers.IntegerField(required=True, min_value=0),
36-
data=self.request.query_params,
37-
)
38-
else:
39-
project_id = self.request.query_params.get("project_id") # No validation
34+
# Look for project_id in GET query parameters or POST data
35+
# POST data returns a list of ints, but QueryDict.get() returns a single value
36+
project_id = self.request.query_params.get(param) or self.request.data.get(param)
37+
38+
project_id = SingleParamSerializer[int].clean(
39+
param_name=param,
40+
field=serializers.IntegerField(required=self.require_project, min_value=0),
41+
data={param: project_id} if project_id else {},
42+
)
4043

4144
return get_object_or_404(Project, id=project_id) if project_id else None

ami/main/admin.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
Site,
2727
SourceImage,
2828
SourceImageCollection,
29+
Tag,
2930
TaxaList,
3031
Taxon,
3132
)
@@ -75,9 +76,33 @@ def save_related(self, request, form, formsets, change):
7576
filter_horizontal = ("members",)
7677

7778
inlines = [ProjectPipelineConfigInline]
79+
autocomplete_fields = ("default_filters_include_taxa", "default_filters_exclude_taxa")
7880

7981
fieldsets = (
80-
(None, {"fields": ("name", "description", "priority", "active")}),
82+
(
83+
None,
84+
{
85+
"fields": (
86+
"name",
87+
"description",
88+
"priority",
89+
"active",
90+
"feature_flags",
91+
)
92+
},
93+
),
94+
(
95+
"Settings",
96+
{
97+
"fields": (
98+
"default_processing_pipeline",
99+
"session_time_gap_seconds",
100+
"default_filters_score_threshold",
101+
"default_filters_include_taxa",
102+
"default_filters_exclude_taxa",
103+
),
104+
},
105+
),
81106
(
82107
"Ownership & Access",
83108
{
@@ -455,6 +480,7 @@ class TaxonAdmin(admin.ModelAdmin[Taxon]):
455480
"rank",
456481
"parent",
457482
"parent_names",
483+
"tag_list",
458484
"list_names",
459485
"created_at",
460486
"updated_at",
@@ -475,10 +501,10 @@ def get_queryset(self, request):
475501

476502
return qs.annotate(occurrence_count=models.Count("occurrences")).order_by("-occurrence_count")
477503

478-
@admin.display(
479-
description="Occurrences",
480-
ordering="occurrence_count",
481-
)
504+
@admin.display(description="Tags")
505+
def tag_list(self, obj) -> str:
506+
return ", ".join([tag.name for tag in obj.tags.all()])
507+
482508
def occurrence_count(self, obj) -> int:
483509
return obj.occurrence_count
484510

@@ -596,3 +622,10 @@ def populate_collection_async(self, request: HttpRequest, queryset: QuerySet[Sou
596622

597623
# Hide images many-to-many field from form. This would list all source images in the database.
598624
exclude = ("images",)
625+
626+
627+
@admin.register(Tag)
628+
class TagAdmin(admin.ModelAdmin):
629+
list_display = ("id", "name", "project")
630+
list_filter = ("project",)
631+
search_fields = ("name",)

0 commit comments

Comments
 (0)