-
Notifications
You must be signed in to change notification settings - Fork 32
♻️ Refactor app_module_setup into Composable Decorators to Enable Modular and Idempotent App Setups
#7982
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
♻️ Refactor app_module_setup into Composable Decorators to Enable Modular and Idempotent App Setups
#7982
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #7982 +/- ##
==========================================
- Coverage 87.88% 87.77% -0.12%
==========================================
Files 1841 1423 -418
Lines 71051 59192 -11859
Branches 1228 627 -601
==========================================
- Hits 62444 51953 -10491
+ Misses 8252 7028 -1224
+ Partials 355 211 -144
Continue to review 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.
Pull Request Overview
This PR refactors the legacy app_module_setup decorator into smaller, composable decorators to improve modularity and enforce idempotent application setup routines.
- Introduces
ensure_single_setupto guard any setup function against multiple executions per app. - Adds
_SetupTimingContextfor consistent timing and logging around setups. - Rewrites
app_module_setupto compose the new decorators and simplify internal logic.
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/service-library/tests/aiohttp/test_application_setup.py | Updated and extended tests to cover ensure_single_setup, adjusted fixtures. |
| packages/service-library/src/servicelib/aiohttp/application_setup.py | Extracted idempotency logic into ensure_single_setup, added timing context, and restructured app_module_setup. |
Comments suppressed due to low confidence (5)
packages/service-library/src/servicelib/aiohttp/application_setup.py:23
- There is an extra space before the dot in the f-string, resulting in a storage key with an unintended space. It should be
f"{__name__}.setup".
APP_SETUP_COMPLETED_KEY: Final[str] = f"{__name__ }.setup"
packages/service-library/src/servicelib/aiohttp/application_setup.py:180
- [nitpick] Use the instance logger (
self.logger) instead of the module‐level_loggerhere so that exit logs go through the same logger passed into the context.
_logger.info("%s completed [Elapsed: %3.1f secs]", self.head_msg, elapsed)
packages/service-library/src/servicelib/aiohttp/application_setup.py:206
- The decorator uses
functools.wrapsbutfunctoolsis not imported in this module, causing aNameError. Addimport functoolsat the top.
@functools.wraps(setup_func)
packages/service-library/src/servicelib/aiohttp/application_setup.py:305
- [nitpick] This assertion forces all setup functions to start with
setup_, which conflicts with fixtures or helpers named_setup_*. Consider relaxing or removing this constraint or renaming impacted functions.
assert setup_func.__name__.startswith( # nosec
packages/service-library/tests/aiohttp/test_application_setup.py:168
- [nitpick] The test hardcodes
'<Application. Avoid logging objects like this>'as the app repr, which won’t match actual output. Either mock the app’s__repr__or loosen the assertion to avoid a fragile placeholder.
"'test.module' was already initialized in <Application. Avoid logging objects like this>. Setup can only be executed once per app.",
…ance test fixtures
0bca481 to
5b9cf94
Compare
|
@mergify queue |
🛑 The pull request has been merged manuallyThe pull request has been merged manually at e7d9064 |
|



What do these changes do?
The
app_module_setupdecorator is typically used in web applications (like those built withaiohttp) to define setup functions that initialize parts of the application — e.g., routes, background tasks, signals, middleware, etc. These setup functions must be idempotent: they should only run once, even if they are called multiple times (e.g., by different parts of the app or due to reuse of shared components).✅ Purpose of
app_module_setup♻️ Why Refactor into Smaller Decorators (e.g.,
ensure_single_setup)Refactoring
app_module_setupinto smaller decorators makes it:ensure_single_setupto guard any function (not just module setup) against multiple calls.🧩 Example: Split Setup with Reusable Guarantees
Related issue/s
How to test
Dev-ops
None