Skip to content

Conversation

@gmazoyer
Copy link
Contributor

@gmazoyer gmazoyer commented Dec 30, 2025

This Jinja2 filter aims to convert a value into a name when it is part of an enum. This is useful when the name of an enum member has more meaning, e.g. in a string which is exposed to users.

An optional enum_path parameter can be specified. When using a valid import string for an enum class, that class will be imported to look for the value within the enum members. This mean that this filter can be used with any enum classes, including the ones found in the Infrahub server code.

Note: I'd like to use this filter to move our current display_labels for permission nodes into Jinja2 based display_label.

Summary by CodeRabbit

  • New Features

    • Exposed a new INFRAHUB filter set for templates, including a value-to-enum-name filter, and added these filters to the catalog of available template filters.
  • Tests

    • Added comprehensive tests covering filter behavior, template integration, ordering of filter definitions, and numerous edge/error cases.

✏️ Tip: You can customize this high-level summary in your review settings.

This Jinja2 filter aims to convert a value into a name when it is part
of an enum. This is useful when the name of an enum member has more
meaning, e.g. in a string which is exposed to users.

An optional `enum_path` parameter can be specified. When using a
valid import string for an enum class, that class will be imported to
look for the value within the enum members. This mean that this filter
can be used with any enum classes, including the ones found in the
Infrahub server code.
@coderabbitai
Copy link

coderabbitai bot commented Dec 30, 2025

Walkthrough

A new filter function value_to_enum_name was added to convert values to enum member names, with optional dynamic enum-class resolution. It and its definitions were added as INFRAHUB_FILTERS / INFRAHUB_FILTER_DEFINITIONS in infrahub_sdk/template/filters.py, and appended to AVAILABLE_FILTERS. INFRAHUB_FILTERS is exported from infrahub_sdk/template/__init__.py. Unit tests were added to validate sorting of filter definitions and multiple behaviors of value_to_enum_name including valid imports, direct enum inputs, missing or invalid enum paths, and edge cases.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add value_to_enum_name filter' accurately and concisely describes the main change: introducing a new Jinja2 filter. It is specific, clear, and directly reflects the primary purpose of the changeset.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 30, 2025

Deploying infrahub-sdk-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 5ebde43
Status: ✅  Deploy successful!
Preview URL: https://156b19cc.infrahub-sdk-python.pages.dev
Branch Preview URL: https://gma-20251230-jinja2-enum-fil.infrahub-sdk-python.pages.dev

View logs

@codecov
Copy link

codecov bot commented Dec 30, 2025

Codecov Report

❌ Patch coverage is 89.65517% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
infrahub_sdk/template/filters.py 88.88% 1 Missing and 2 partials ⚠️
@@                 Coverage Diff                  @@
##           infrahub-develop     #727      +/-   ##
====================================================
+ Coverage             76.29%   76.35%   +0.05%     
====================================================
  Files                   114      114              
  Lines                  9831     9858      +27     
  Branches               1509     1513       +4     
====================================================
+ Hits                   7501     7527      +26     
  Misses                 1834     1834              
- Partials                496      497       +1     
Flag Coverage Δ
integration-tests 34.36% <0.00%> (-0.10%) ⬇️
python-3.10 50.22% <62.06%> (+0.06%) ⬆️
python-3.11 50.20% <62.06%> (+0.04%) ⬆️
python-3.12 50.20% <62.06%> (+0.06%) ⬆️
python-3.13 50.20% <62.06%> (+0.06%) ⬆️
python-3.14 51.83% <62.06%> (+0.04%) ⬆️
python-filler-3.12 24.02% <31.03%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
infrahub_sdk/template/__init__.py 95.38% <100.00%> (+0.03%) ⬆️
infrahub_sdk/template/filters.py 91.42% <88.88%> (-8.58%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gmazoyer gmazoyer requested a review from a team December 30, 2025 12:36
Comment on lines +51 to +53
INFRAHUB_FILTER_DEFINITIONS = [
FilterDefinition(name=name, trusted=True, source="infrahub-sdk-python") for name in sorted(INFRAHUB_FILTERS.keys())
]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote it like that so that we can easily add filters in the future.

@gmazoyer gmazoyer marked this pull request as ready for review December 30, 2025 12:58
Copy link

@coderabbitai coderabbitai bot left a 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)
infrahub_sdk/template/filters.py (1)

40-45: Minor: Redundant None check for enum member name.

The name attribute of an enum member is always a non-None string, so the if enum_member.name is not None: check on line 42 is unnecessary and can be simplified.

🔎 Suggested simplification
     try:
         enum_member = enum_type(value)
-        if enum_member.name is not None:
-            return enum_member.name
+        return enum_member.name
     except (ValueError, TypeError):
         pass
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 854412b and a59f7ec.

📒 Files selected for processing (3)
  • infrahub_sdk/template/__init__.py
  • infrahub_sdk/template/filters.py
  • tests/unit/sdk/test_template.py
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Use type hints on all function signatures
Never mix async/sync inappropriately
Never bypass type checking without justification

Files:

  • infrahub_sdk/template/filters.py
  • tests/unit/sdk/test_template.py
  • infrahub_sdk/template/__init__.py
infrahub_sdk/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Follow async/sync dual pattern for new features in the Python SDK

Files:

  • infrahub_sdk/template/filters.py
  • infrahub_sdk/template/__init__.py
tests/**/*.py

📄 CodeRabbit inference engine (tests/AGENTS.md)

tests/**/*.py: Use httpx_mock fixture for HTTP mocking in tests instead of making real HTTP requests
Do not add @pytest.mark.asyncio decorator to async test functions (async auto-mode is globally enabled)

Files:

  • tests/unit/sdk/test_template.py
tests/unit/**/*.py

📄 CodeRabbit inference engine (tests/AGENTS.md)

Unit tests must be fast, mocked, and have no external dependencies

Files:

  • tests/unit/sdk/test_template.py
🧬 Code graph analysis (2)
infrahub_sdk/template/filters.py (1)
infrahub_sdk/_importer.py (1)
  • import_module (16-63)
tests/unit/sdk/test_template.py (2)
infrahub_sdk/template/filters.py (2)
  • FilterDefinition (8-11)
  • value_to_enum_name (14-47)
infrahub_sdk/template/__init__.py (2)
  • Jinja2Template (28-182)
  • get_variables (78-87)
⏰ 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: Cloudflare Pages
🔇 Additional comments (6)
infrahub_sdk/template/filters.py (2)

50-53: Verify that trusted=True is appropriate for this filter.

The filter is marked as trusted=True, meaning it can be used in restricted template contexts. Since it dynamically imports modules based on user-provided paths, please confirm this trust level is intentional. The dynamic import allows access to any importable module, though the filter only extracts enum member names.

If this is the intended security posture (given the stated use case for Infrahub server enums), the implementation looks correct.


14-47: LGTM - Well-structured filter implementation.

The function handles multiple edge cases gracefully:

  • Direct enum input returns name immediately
  • Missing enum_path falls back to string conversion
  • Import/attribute errors are caught and handled
  • Non-enum classes are rejected
  • Invalid values for the enum fall back safely

Good defensive programming with comprehensive error handling.

infrahub_sdk/template/__init__.py (1)

158-161: LGTM - Clean integration following established patterns.

The INFRAHUB_FILTERS integration mirrors the existing netutils_filters pattern exactly, with proper gating via _available_filters check.

tests/unit/sdk/test_template.py (3)

318-325: LGTM - Good test enum and path setup.

The SampleIntEnum provides a clean test fixture with representative values, and TEST_ENUM_PATH correctly references the test module path for dynamic import testing.


334-370: LGTM - Comprehensive unit test coverage.

The tests cover all critical paths:

  • Valid enum resolution with full import path
  • Direct enum instance input
  • Missing enum_path fallback
  • Invalid module, class, and value handling
  • Edge cases (zero value, malformed path)

Good defensive testing for the filter's error handling behavior.


373-421: LGTM - Thorough template integration tests.

The test cases validate real-world template usage patterns including:

  • Simple enum value conversion
  • Chained filters (| lower)
  • Complex template strings with multiple variables
  • Invalid path fallback behavior

The async test correctly omits @pytest.mark.asyncio as per the coding guidelines (async auto-mode is globally enabled).

Copy link

@coderabbitai coderabbitai bot left a 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)
infrahub_sdk/template/filters.py (1)

44-45: Simplify the conditional check.

The check if enum_member.name is not None: is unnecessary since enum members always have a name attribute that is a string, never None.

🔎 Proposed simplification
     try:
         enum_member = enum_type(raw_value)
-        if enum_member.name is not None:
-            return enum_member.name
+        return enum_member.name
     except (ValueError, TypeError):
         pass
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a59f7ec and 5ebde43.

📒 Files selected for processing (1)
  • infrahub_sdk/template/filters.py
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Use type hints on all function signatures
Never mix async/sync inappropriately
Never bypass type checking without justification

Files:

  • infrahub_sdk/template/filters.py
infrahub_sdk/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Follow async/sync dual pattern for new features in the Python SDK

Files:

  • infrahub_sdk/template/filters.py
🧬 Code graph analysis (1)
infrahub_sdk/template/filters.py (2)
infrahub_sdk/protocols_base.py (1)
  • Enum (110-111)
infrahub_sdk/_importer.py (1)
  • import_module (16-63)
⏰ 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). (6)
  • GitHub Check: unit-tests (3.12)
  • GitHub Check: unit-tests (3.11)
  • GitHub Check: unit-tests (3.14)
  • GitHub Check: unit-tests (3.10)
  • GitHub Check: unit-tests (3.13)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (4)
infrahub_sdk/template/filters.py (4)

2-4: LGTM!

The imports are appropriate for the new filter functionality. Using the standard library import_module is correct here since it handles string-based module paths (e.g., "infrahub.core.constants"), whereas the custom import_module in _importer.py is designed for file-based imports.


14-49: Well-designed filter with robust error handling.

The implementation correctly handles multiple scenarios:

  • Values already as Enum instances
  • Dynamic enum class import and validation
  • Extracting raw values from different enum types (per commit message)
  • Graceful fallback to string representation

Type hints follow coding guidelines properly.


52-55: LGTM!

The filter registration structure is well-designed for future extensibility. Using sorted() ensures consistent ordering of filter definitions, and marking the filter as trusted=True is appropriate for SDK-provided functionality.


198-198: LGTM!

The integration of INFRAHUB_FILTER_DEFINITIONS into AVAILABLE_FILTERS is correct and maintains the existing pattern.

Comment on lines +31 to +34
try:
module_path, class_name = enum_path.rsplit(".", 1)
module = import_module(module_path)
enum_type = getattr(module, class_name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is allowing the user to import any Python module inside of the SDK a security concern?
I guess the user can already do this b/c they are using the SDK in their own code, but we also use the SDK within Infrahub and I wonder if there is a way for the user to force the Infrahub server to import something malicious

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants