-
Notifications
You must be signed in to change notification settings - Fork 536
Bug in Interpretation evaluator and minor improvements #3347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughA valueset caching mechanism is introduced to the interpretation evaluation system. The InterpretationEvaluator now accepts an optional Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
care/utils/evaluators/interpretation_evaluator.py (1)
24-33: Consider adding error handling for the database query.The caching logic is well-implemented, but
ValueSet.objects.get(slug=valueset_slug)on line 26 could raiseDoesNotExistorMultipleObjectsReturnedexceptions if the slug is missing or duplicated in the database. Perhaps it would be wise to handle these cases gracefully to prevent the entire interpretation evaluation from failing unexpectedly.Consider wrapping the query in a try-except block:
def check_valueset(self, valueset_slug, code, interpretation): if valueset_slug not in self.valueset_cache: - self.valueset_cache[valueset_slug] = ValueSet.objects.get( - slug=valueset_slug - ) + try: + self.valueset_cache[valueset_slug] = ValueSet.objects.get( + slug=valueset_slug + ) + except ValueSet.DoesNotExist: + return None valueset = self.valueset_cache[valueset_slug] lookup = valueset.lookup(code) if lookup: return interpretation return None
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
care/emr/utils/compute_observation_interpretation.py(4 hunks)care/utils/evaluators/interpretation_evaluator.py(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (.cursorrules)
**/*.py: Prioritize readability and maintainability; follow Django's coding style guide (PEP 8 compliance).
Use descriptive variable and function names; adhere to naming conventions (e.g., lowercase with underscores for functions and variables).
Files:
care/emr/utils/compute_observation_interpretation.pycare/utils/evaluators/interpretation_evaluator.py
🧬 Code graph analysis (2)
care/emr/utils/compute_observation_interpretation.py (1)
care/utils/evaluators/interpretation_evaluator.py (1)
InterpretationEvaluator(12-145)
care/utils/evaluators/interpretation_evaluator.py (1)
care/emr/registries/care_valueset/care_valueset.py (1)
valueset(45-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test / Test
🔇 Additional comments (8)
care/emr/utils/compute_observation_interpretation.py (4)
10-10: Cache initialization looks good.The valueset_cache is properly initialized, mirroring the metrics_cache pattern.
12-16: Cache propagation to main evaluator is correct.The valueset_cache is properly passed to the InterpretationEvaluator constructor, enabling caching for the main observation interpretation.
24-25: Cache synchronization is properly implemented.The valueset_cache is correctly updated from the evaluator after evaluation, ensuring the cache is maintained for subsequent component evaluations.
40-44: Component evaluation caching is consistent.The valueset_cache is properly threaded through component evaluations, maintaining cache consistency across all component interpretations.
Also applies to: 52-53
care/utils/evaluators/interpretation_evaluator.py (4)
13-22: Cache initialization follows established pattern.The valueset_cache parameter and initialization mirror the existing metric_cache approach, maintaining consistency in the codebase.
35-54: Improved return semantics for edge cases.The changes from
(False, False)to(None, [])on lines 48 and 54 are semantically clearer.Noneunambiguously indicates "no interpretation found" rather than a boolean value, and the empty list for ranges maintains consistency with successful returns.
96-105: Typo fix corrects the valueset interpretation logic.The correction from "valuset" to "valueset" on lines 97 and 100 fixes a bug that would have prevented the valueset_interpretation logic from working correctly. Nice catch.
107-107: Consistent return value at function end.The change to
(None, [])maintains consistency with the other return statements and clearly indicates "no interpretation found" as the final fallback.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #3347 +/- ##
===========================================
- Coverage 73.82% 73.78% -0.04%
===========================================
Files 435 435
Lines 19811 19819 +8
Branches 2152 2154 +2
===========================================
- Hits 14626 14624 -2
- Misses 4737 4746 +9
- Partials 448 449 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
care/emr/utils/compute_observation_interpretation.py(4 hunks)care/utils/evaluators/interpretation_evaluator.py(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- care/emr/utils/compute_observation_interpretation.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (.cursorrules)
**/*.py: Prioritize readability and maintainability; follow Django's coding style guide (PEP 8 compliance).
Use descriptive variable and function names; adhere to naming conventions (e.g., lowercase with underscores for functions and variables).
Files:
care/utils/evaluators/interpretation_evaluator.py
🧬 Code graph analysis (1)
care/utils/evaluators/interpretation_evaluator.py (1)
care/emr/registries/care_valueset/care_valueset.py (1)
valueset(45-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Test / Test
🔇 Additional comments (4)
care/utils/evaluators/interpretation_evaluator.py (4)
13-13: LGTM! Caching pattern is consistent.The valueset_cache initialization follows the same pattern as the existing metric_cache, which maintains consistency in the codebase.
Also applies to: 19-22
48-48: Good improvement to return semantics.Returning
(None, [])instead of(False, False)is more semantically appropriate for indicating "no interpretation found" and maintains consistency with other return paths.Also applies to: 54-54
97-97: Critical typo fix.Nice catch! The typo "valuset" instead of "valueset" would have prevented the valueset_interpretation logic from functioning correctly.
Also applies to: 100-100
107-107: Consistent return value.The final fallback return is now consistent with other early returns in the method.
| def check_valueset(self, valueset_slug, code, interpretation): | ||
| if valueset_slug not in self.valueset_cache: | ||
| self.valueset_cache[valueset_slug] = ValueSet.objects.get( | ||
| slug=valueset_slug | ||
| ) | ||
| valueset = self.valueset_cache[valueset_slug] | ||
| lookup = valueset.lookup(code) | ||
| if lookup: | ||
| return interpretation | ||
| return False | ||
| return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for missing ValueSet slugs.
The ValueSet.objects.get(slug=valueset_slug) call will raise a DoesNotExist exception if the slug is not found in the database, which would crash the evaluation. It would be unfortunate if that happened.
Apply this diff to handle missing valuesets gracefully:
def check_valueset(self, valueset_slug, code, interpretation):
if valueset_slug not in self.valueset_cache:
- self.valueset_cache[valueset_slug] = ValueSet.objects.get(
- slug=valueset_slug
- )
+ try:
+ self.valueset_cache[valueset_slug] = ValueSet.objects.get(
+ slug=valueset_slug
+ )
+ except ValueSet.DoesNotExist:
+ return None
valueset = self.valueset_cache[valueset_slug]
lookup = valueset.lookup(code)
if lookup:
return interpretation
return None🤖 Prompt for AI Agents
In care/utils/evaluators/interpretation_evaluator.py around lines 24 to 33, the
call to ValueSet.objects.get(slug=valueset_slug) can raise ValueSet.DoesNotExist
and crash evaluation; wrap the get call in a try/except catching
ValueSet.DoesNotExist, store a sentinel (e.g., None) in self.valueset_cache for
that slug, and proceed so the function returns None when the valueset is
missing; ensure subsequent code checks for a None cached value before calling
lookup to avoid AttributeError and log or silently handle the missing valueset
per project convention.
@ohcnetwork/care-backend-maintainers @ohcnetwork/care-backend-admins
Summary by CodeRabbit
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.