Skip to content

Commit f43c80b

Browse files
authored
Merge pull request #1173 from i-dot-ai/feature/move-logging-to-core-logger
Change logging to use i_dot_ai_utilities logger and formatted all files
2 parents 47c0595 + 50fd4d8 commit f43c80b

22 files changed

+276
-164
lines changed

backend/consultations/api/views/candidate_theme.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ class CandidateThemeViewSet(ModelViewSet):
1919
def get_queryset(self):
2020
consultation_uuid = self.kwargs["consultation_pk"]
2121
question_uuid = self.kwargs["question_pk"]
22-
22+
2323
queryset = models.CandidateTheme.objects.filter(
2424
question__consultation_id=consultation_uuid,
2525
question_id=question_uuid,
2626
)
27-
27+
2828
# Staff users can see all candidate themes, non-staff users only see themes for assigned consultations
2929
if not self.request.user.is_staff:
3030
queryset = queryset.filter(question__consultation__users=self.request.user)
31-
31+
3232
return queryset.order_by("-approximate_frequency")
3333

3434
def list(self, request, consultation_pk=None, question_pk=None):

backend/consultations/api/views/consultation.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import logging
21
from typing import Any
32
from uuid import UUID
43

@@ -58,11 +57,11 @@ def get_permissions(self):
5857
Override permissions for specific actions
5958
"""
6059
permission_classes = self.permission_classes
61-
62-
if self.action == 'destroy':
60+
61+
if self.action == "destroy":
6362
# Only admin users can delete consultations
6463
permission_classes = [IsAuthenticated, IsAdminUser]
65-
64+
6665
return [permission() for permission in permission_classes]
6766

6867
def perform_destroy(self, instance):
@@ -302,7 +301,7 @@ def submit_consultation_export(self, request) -> Response:
302301

303302
for id in validated["question_ids"]:
304303
try:
305-
logging.info("Exporting theme audit data - sending to queue")
304+
logger.info("Exporting theme audit data - sending to queue")
306305
export_user_theme_job.delay(question_id=UUID(id), s3_key=validated["s3_key"])
307306
except Exception:
308307
return Response(

backend/consultations/api/views/question.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ class QuestionViewSet(ModelViewSet):
2121

2222
def get_queryset(self):
2323
consultation_uuid = self.kwargs["consultation_pk"]
24-
24+
2525
queryset = models.Question.objects.filter(consultation_id=consultation_uuid)
26-
26+
2727
# Staff users can see all questions, non-staff users only see questions for assigned consultations
2828
if not self.request.user.is_staff:
2929
queryset = queryset.filter(consultation__users=self.request.user)
30-
30+
3131
return queryset.annotate(response_count=Count("response")).order_by("number")
3232

3333
@action(

backend/consultations/api/views/respondent.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ class RespondentViewSet(ModelViewSet):
1515

1616
def get_queryset(self):
1717
consultation_uuid = self.kwargs["consultation_pk"]
18-
18+
1919
queryset = models.Respondent.objects.filter(consultation_id=consultation_uuid)
20-
20+
2121
# Staff users can see all respondents, non-staff users only see respondents for assigned consultations
2222
if not self.request.user.is_staff:
2323
queryset = queryset.filter(consultation__users=self.request.user)
24-
24+
2525
return queryset.order_by("-created_at")

backend/consultations/api/views/selected_theme.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ class SelectedThemeViewSet(ModelViewSet):
2020
def get_queryset(self):
2121
consultation_uuid = self.kwargs["consultation_pk"]
2222
question_uuid = self.kwargs["question_pk"]
23-
23+
2424
queryset = models.SelectedTheme.objects.filter(
2525
question__consultation_id=consultation_uuid,
2626
question_id=question_uuid,
2727
)
28-
28+
2929
# Staff users can see all themes, non-staff users only see themes for assigned consultations
3030
if not self.request.user.is_staff:
3131
queryset = queryset.filter(question__consultation__users=self.request.user)
32-
32+
3333
return queryset
3434

3535
def perform_create(self, serializer):

backend/consultations/api/views/theme.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ class ThemeViewSet(ReadOnlyModelViewSet):
1313

1414
def get_queryset(self):
1515
consultation_uuid = self.kwargs["consultation_pk"]
16-
16+
1717
queryset = models.CrossCuttingTheme.objects.filter(consultation_id=consultation_uuid)
18-
18+
1919
# Staff users can see all themes, non-staff users only see themes for assigned consultations
2020
if not self.request.user.is_staff:
2121
queryset = queryset.filter(consultation__users=self.request.user)
22-
22+
2323
return queryset.order_by("-created_at")

backend/consultations/export_user_theme.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ def export_user_theme(question_id: uuid.UUID, s3_key: str) -> None:
9797
filename = f"{timestamp}_question_{question_number}_theme_changes.csv"
9898

9999
if not output:
100-
logger.warning(f"No responses found for question {question_number}")
100+
logger.warning(
101+
"No responses found for question {question_number}", question_number=question_number
102+
)
101103
return
102104

103105
if settings.ENVIRONMENT == "local":
@@ -127,7 +129,9 @@ def export_user_theme(question_id: uuid.UUID, s3_key: str) -> None:
127129
)
128130
csv_buffer.close()
129131
logger.info(
130-
f"Finishing export for question {question_number} for consultation {question.consultation.title}"
132+
"Finishing export for question {question_number} for consultation {consultation_title}",
133+
question_number=question_number,
134+
consultation_title=question.consultation.title,
131135
)
132136

133137

backend/data_pipeline/batch.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ def submit_job(
3636

3737
batch = boto3.client("batch")
3838

39-
logger.info(f"Submitting {job_type} job to AWS Batch for consultation: {consultation_name}")
39+
logger.info(
40+
"Submitting {job_type} job to AWS Batch for consultation: {consultation_name}",
41+
job_type=job_type,
42+
consultation_name=consultation_name,
43+
)
4044

4145
response = batch.submit_job(
4246
jobName=job_name,
@@ -47,6 +51,6 @@ def submit_job(
4751
)
4852

4953
job_id = response["jobId"]
50-
logger.info(f"Batch job submitted: {job_id}")
54+
logger.info("Batch job submitted: {job_id}", job_id=job_id)
5155

5256
return response

backend/data_pipeline/s3.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def read_jsonl(
3434
response = s3_client.get_object(Bucket=bucket_name, Key=key)
3535
except ClientError as e:
3636
if not raise_if_missing and e.response["Error"]["Code"] == "NoSuchKey":
37-
logger.info(f"File not found (skipping): {key}")
37+
logger.info("File not found (skipping): {key}", key=key)
3838
return []
3939
raise
4040

@@ -73,7 +73,7 @@ def read_json(
7373
return data
7474
except ClientError as e:
7575
if not raise_if_missing and e.response["Error"]["Code"] == "NoSuchKey":
76-
logger.info(f"File not found (skipping): {key}")
76+
logger.info("File not found (skipping): {key}", key=key)
7777
return None
7878
raise
7979

backend/data_pipeline/sync/candidate_themes.py

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import logging
21
from typing import Dict, List, Optional
32

43
from django.conf import settings
@@ -9,7 +8,7 @@
98
from backend.consultations.models import CandidateTheme, Consultation, Question
109
from backend.data_pipeline.models import CandidateThemeBatch, ThemeNodeList
1110

12-
logger = logging.getLogger(__name__)
11+
logger = settings.LOGGER
1312

1413

1514
# ============================================================================
@@ -46,21 +45,23 @@ def load_candidate_themes_from_s3(
4645
# Build S3 key for clustered_themes.json
4746
key = f"app_data/consultations/{consultation_code}/outputs/sign_off/{timestamp}/question_part_{question_number}/clustered_themes.json"
4847

49-
logger.info(f"Loading candidate themes from {key}")
48+
logger.info("Loading candidate themes from {key}", key=key)
5049

5150
# Read and parse JSON file
5251
theme_data = s3.read_json(
5352
bucket_name=bucket_name_str, key=key, s3_client=s3_client, raise_if_missing=False
5453
)
5554

5655
if theme_data is None:
57-
logger.info(f"No candidate themes file found at {key}")
56+
logger.info("No candidate themes file found at {key}", key=key)
5857
return []
5958

6059
validated_themes = ThemeNodeList.model_validate(theme_data).theme_nodes
6160

6261
logger.info(
63-
f"Loaded and validated {len(validated_themes)} candidate themes for question {question_number}"
62+
"Loaded and validated {theme_count} candidate themes for question {question_number}",
63+
theme_count=len(validated_themes),
64+
question_number=question_number,
6465
)
6566

6667
return validated_themes
@@ -106,8 +107,10 @@ def load_candidate_themes_batch(
106107
)
107108

108109
logger.info(
109-
f"Loading candidate themes for consultation '{consultation_code}' "
110-
f"(timestamp: {timestamp}) across {len(question_numbers)} questions"
110+
"Loading candidate themes for consultation '{consultation_code}' (timestamp: {timestamp}) across {question_count} questions",
111+
consultation_code=consultation_code,
112+
timestamp=timestamp,
113+
question_count=len(question_numbers),
111114
)
112115

113116
# Load themes for each question
@@ -133,7 +136,9 @@ def load_candidate_themes_batch(
133136

134137
total_themes = sum(len(themes) for themes in themes_by_question.values())
135138
logger.info(
136-
f"Loaded {total_themes} total candidate themes across {len(themes_by_question)} questions"
139+
"Loaded {total_themes} total candidate themes across {question_count} questions",
140+
total_themes=total_themes,
141+
question_count=len(themes_by_question),
137142
)
138143

139144
return batch
@@ -159,18 +164,27 @@ def _import_candidate_themes_for_question(question: Question, themes: List[Theme
159164
themes: List of validated ThemeNode objects
160165
"""
161166
if not themes:
162-
logger.info(f"No candidate themes to import for question {question.number}")
167+
logger.info(
168+
"No candidate themes to import for question {question_number}",
169+
question_number=question.number,
170+
)
163171
return
164172

165173
# Delete existing candidate themes for this question (idempotent)
166174
existing_count = CandidateTheme.objects.filter(question=question).count()
167175
if existing_count > 0:
168176
logger.info(
169-
f"Deleting {existing_count} existing candidate themes for question {question.number}"
177+
"Deleting {existing_count} existing candidate themes for question {question_number}",
178+
existing_count=existing_count,
179+
question_number=question.number,
170180
)
171181
CandidateTheme.objects.filter(question=question).delete()
172182

173-
logger.info(f"Importing {len(themes)} candidate themes for question {question.number}")
183+
logger.info(
184+
"Importing {theme_count} candidate themes for question {question_number}",
185+
theme_count=len(themes),
186+
question_number=question.number,
187+
)
174188

175189
# First pass: create all themes without parent relationships
176190
themes_to_create = [
@@ -209,15 +223,24 @@ def _import_candidate_themes_for_question(question: Question, themes: List[Theme
209223
themes_to_update.append(candidate_theme)
210224
else:
211225
logger.warning(
212-
f"Parent theme with topic_id '{parent_id}' not found for theme '{candidate_theme.name}'"
226+
"Parent theme with topic_id '{parent_id}' not found for theme '{theme_name}'",
227+
parent_id=parent_id,
228+
theme_name=candidate_theme.name,
213229
)
214230

215231
# Bulk update parent relationships
216232
if themes_to_update:
217233
CandidateTheme.objects.bulk_update(themes_to_update, ["parent"])
218-
logger.info(f"Set {len(themes_to_update)} parent relationships")
234+
logger.info(
235+
"Set {relationship_count} parent relationships",
236+
relationship_count=len(themes_to_update),
237+
)
219238

220-
logger.info(f"Created {len(created_themes)} candidate themes for question {question.number}")
239+
logger.info(
240+
"Created {theme_count} candidate themes for question {question_number}",
241+
theme_count=len(created_themes),
242+
question_number=question.number,
243+
)
221244

222245

223246
@transaction.atomic
@@ -247,12 +270,17 @@ def import_candidate_themes(batch: CandidateThemeBatch) -> None:
247270
"Base consultation data must be imported before candidate themes."
248271
)
249272

250-
logger.info(f"Starting candidate themes import for consultation '{consultation.title}'")
273+
logger.info(
274+
"Starting candidate themes import for consultation '{consultation_title}'",
275+
consultation_title=consultation.title,
276+
)
251277

252278
# Update consultation timestamp
253279
if consultation.timestamp != batch.timestamp:
254280
logger.info(
255-
f"Updating consultation timestamp from '{consultation.timestamp}' to '{batch.timestamp}'"
281+
"Updating consultation timestamp from '{old_timestamp}' to '{new_timestamp}'",
282+
old_timestamp=consultation.timestamp,
283+
new_timestamp=batch.timestamp,
256284
)
257285
consultation.timestamp = batch.timestamp
258286
consultation.save(update_fields=["timestamp"])
@@ -278,8 +306,9 @@ def import_candidate_themes(batch: CandidateThemeBatch) -> None:
278306
total_themes_created += len(themes)
279307

280308
logger.info(
281-
f"Candidate themes import complete: "
282-
f"{total_themes_created} themes across {questions_imported} questions"
309+
"Candidate themes import complete: {total_themes_created} themes across {questions_imported} questions",
310+
total_themes_created=total_themes_created,
311+
questions_imported=questions_imported,
283312
)
284313

285314

@@ -311,8 +340,9 @@ def import_candidate_themes_from_s3(
311340
ValueError: If consultation or questions don't exist
312341
"""
313342
logger.info(
314-
f"Starting candidate themes import for consultation '{consultation_code}' "
315-
f"(timestamp: {timestamp})"
343+
"Starting candidate themes import for consultation '{consultation_code}' (timestamp: {timestamp})",
344+
consultation_code=consultation_code,
345+
timestamp=timestamp,
316346
)
317347

318348
# Load from S3
@@ -325,4 +355,7 @@ def import_candidate_themes_from_s3(
325355
# Import into database
326356
import_candidate_themes(batch)
327357

328-
logger.info(f"Candidate themes import complete for consultation '{consultation_code}'")
358+
logger.info(
359+
"Candidate themes import complete for consultation '{consultation_code}'",
360+
consultation_code=consultation_code,
361+
)

0 commit comments

Comments
 (0)