Skip to content

refactor: no functions or classes inside functions in app/ - #387

Merged
HardMax71 merged 1 commit into
mainfrom
refactor/no-nested-functions-app
Oct 13, 2026
Merged

HardMax71 merged 1 commit into
mainfrom
refactor/no-nested-functions-app

Conversation

@HardMax71

@HardMax71 HardMax71 commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

app/ defined 33 functions inside other functions. This moves every one of them out, so an AST scan of app/ finds no def or class inside a function body.

The Kafka handlers in app/events/handlers.py are module-level functions now, each factory registers them with router.subscriber(...)(handler), and the names say what they do (start_saga, store_completed_result, notify_failed). FastStream wraps each registration separately and Dishka injects through the broker's call decorators, so the same function is safe to register on several routers. The exception handlers moved out of configure_exception_handlers the same way.

The ASGI wrappers in the cache, metrics, rate limit, security headers and request size middlewares are small classes holding one request's send or receive. The metrics one keeps the status and headers its response starts with. The memory and CPU gauge callbacks are module-level functions, and the process gauge is a class that keeps its psutil.Process, since cpu_percent measures from its last call.

The notification and replay retry loggers are methods. They read the notification or the replay config from RetryCallState.args, the arguments of the retried call, so nothing closes over them, and the replay dispatch is a method too. System notifications go out 20 users at a time with itertools.batched and gather instead of a semaphore in a closure. The user overview counts statuses with a generator, and the rate limit filters compare three precomputed sets instead of three lambdas. Three sort-key lambdas are left, since the issue covers def and class.

AGENTS.md now states the rule and shows the module-level handler, and the topic architecture doc shows the same pattern.

ruff, mypy, grimp, 569 unit tests and the Grafana contract tests pass, and the docs build in strict mode. The backend e2e suite gave 488 passed, 1 skipped on a fresh local stack with k3s and the worker running this branch, the same count as main.

Closes #383


Summary by cubic

Moves every def and class defined inside a function out to module level in app/, so an AST scan of app/ finds no nested functions or classes.

  • Kafka handlers, exception handlers, and retry loggers are now module-level functions or methods, registered with the subscriber or exception-handler decorators directly.
  • ASGI send/receive wrappers in the cache, metrics, rate limit, security headers, and request size middlewares became small classes that hold one request's state.
  • System notifications now batch 20 users at a time with itertools.batched and gather instead of a semaphore in a closure.
  • AGENTS.md and the Kafka topic architecture doc now document the rule and show the pattern.

Closes #383.

Written for commit b5b64c3. Summary will update on new commits.

View guided diff Turn on auto-fix

The Kafka handlers are module-level functions that each router factory registers by calling the subscriber decorator, and the exception handlers are module-level functions registered the same way. The ASGI send and receive wrappers in the cache, metrics, rate limit, security headers and request size middlewares are small classes that hold one request's state. The memory and CPU gauges are module-level callbacks, and the process gauge is a class that keeps its psutil.Process, since cpu_percent measures from the last call.

The notification and replay retry loggers are methods that read the notification or the replay config from the retried call's arguments, and the replay dispatch is a method. System notifications go out 20 users at a time through itertools.batched instead of a semaphore inside a closure. The user overview counts statuses with a generator, and the rate limit filters compare precomputed sets instead of lambdas.

AGENTS.md states the rule and shows the handler pattern.
@HardMax71
HardMax71 enabled auto-merge (squash) October 13, 2026 23:45
@github-actions github-actions Bot added documentation Improvements or additions to documentation area: api FastAPI routes, auth, rate limiting, settings area: events Kafka consumers and middlewares, producer, idempotency, DLQ, replay area: realtime SSE streams and notifications area: observability Metrics, dashboards, alerts, logs, traces, OTel collector labels Oct 13, 2026
@coderabbitai

coderabbitai Bot commented Oct 13, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6c9b09ae-a075-4841-ba1a-802913f22ceb
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 67.23164% with 58 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
backend/app/events/handlers.py 57.14% 24 Missing ⚠️
backend/app/core/middlewares/cache.py 25.00% 9 Missing ⚠️
backend/app/core/middlewares/metrics.py 73.33% 8 Missing ⚠️
...ackend/app/services/event_replay/replay_service.py 50.00% 8 Missing ⚠️
backend/app/core/middlewares/security_headers.py 44.44% 5 Missing ⚠️
backend/app/services/notification_service.py 62.50% 3 Missing ⚠️
backend/app/services/admin/admin_user_service.py 80.00% 1 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Flag Coverage Δ
backend-unit 72.44% <67.23%> (+0.22%) ⬆️

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

Files with missing lines Coverage Δ
backend/app/core/exceptions/handlers.py 100.00% <100.00%> (ø)
backend/app/core/middlewares/rate_limit.py 96.66% <100.00%> (+0.23%) ⬆️
backend/app/core/middlewares/request_size_limit.py 94.11% <100.00%> (+1.01%) ⬆️
backend/app/services/admin/admin_user_service.py 99.15% <80.00%> (-0.85%) ⬇️
backend/app/services/notification_service.py 64.11% <62.50%> (-1.21%) ⬇️
backend/app/core/middlewares/security_headers.py 61.11% <44.44%> (-27.13%) ⬇️
backend/app/core/middlewares/metrics.py 77.65% <73.33%> (+5.13%) ⬆️
...ackend/app/services/event_replay/replay_service.py 80.55% <50.00%> (-1.39%) ⬇️
backend/app/core/middlewares/cache.py 71.05% <25.00%> (-23.40%) ⬇️
backend/app/events/handlers.py 71.76% <57.14%> (-11.77%) ⬇️
Components Coverage Δ
Backend 91.15% <67.23%> (-0.32%) ⬇️
Frontend 92.60% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sonarqubecloud

Copy link
Copy Markdown

@HardMax71
HardMax71 merged commit b6300af into main Oct 13, 2026
20 checks passed
@HardMax71
HardMax71 deleted the refactor/no-nested-functions-app branch October 13, 2026 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: api FastAPI routes, auth, rate limiting, settings area: events Kafka consumers and middlewares, producer, idempotency, DLQ, replay area: observability Metrics, dashboards, alerts, logs, traces, OTel collector area: realtime SSE streams and notifications documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor: no functions defined inside functions in app/

2 participants