fix: move stdlib json import to module level in hot-path tracer + lambda functions#1243
Conversation
Hoists `import json` from inside hot-path function bodies to module top in two services, matching the pattern from Tracer-Cloud#1216 (which fixed Tracer-Cloud#1209 for `copy` and `datetime` in app/nodes/). - app/services/tracer_client/tracer_integrations.py - get_all_integrations: import was inside a `for` loop iterating integration records, re-running the import statement once per iteration - get_grafana_credentials: import was per-call during integration resolution - app/services/lambda_client.py - invoke_function: import was per Lambda invocation Fixes Tracer-Cloud#1242
VaibhavUpreti
left a comment
There was a problem hiding this comment.
awesome @cloudenochcsis thanks a lot for fixing this! Welcome to OpenSRE community 🚀
Greptile SummaryMoves Confidence Score: 5/5Safe to merge — semantic no-op import hoist with correct alphabetical placement in both files. Both changes are purely mechanical: No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Module Load] -->|"import json (once)"| B[json in sys.modules]
subgraph "Before (per-call / per-iteration)"
C1["invoke_function() called"] --> D1["import json ← sys.modules lookup + local bind"]
E1["get_all_integrations() loop iteration"] --> F1["import json ← sys.modules lookup + local bind"]
G1["get_grafana_credentials() called"] --> H1["import json ← sys.modules lookup + local bind"]
end
subgraph "After (module top, once)"
C2["invoke_function() called"] --> D2["json already bound at module scope"]
E2["get_all_integrations() loop iteration"] --> F2["json already bound at module scope"]
G2["get_grafana_credentials() called"] --> H2["json already bound at module scope"]
end
B --> C2
B --> E2
B --> G2
Reviews (1): Last reviewed commit: "fix: move stdlib json import to module l..." | Re-trigger Greptile |
|
🏄 Some PRs rot in review for six weeks. @cloudenochcsis's said "not today" and merged like it owned the place. 🌊 👋 Join us on Discord - OpenSRE : hang out, contribute, or hunt for features and issues. Everyone's welcome. |
…ntegrations node (#1266) `_decode_org_id_from_token` in `app/nodes/resolve_integrations/node.py` imported `base64` and `json` inside the function body. The helper is called from `node_resolve_integrations`, which runs early in every investigation that uses webhook auth or `JWT_TOKEN`-based auth, so each investigation paid the per-call import overhead unnecessarily. Both modules are pure stdlib with no circular-import risk and no optional-dependency concerns. Hoisting to module level removes the per-call `sys.modules` lookup and local namespace binding while keeping behavior identical. The `import json as _json` alias and the in-function references are replaced with the standard `json` name. Same pattern as the fix in #1242 / PR #1243, applied to a graph node rather than a service module. Fixes #1265

Fixes #1242
Describe the changes you have made in this PR -
Hoists `import json` from inside hot-path function bodies to module top in two services, matching the pattern from #1216 (which fixed #1209 for `copy` and `datetime` in `app/nodes/`). Same class of issue, different sites.
Files changed
Diff summary
```
2 files changed, 2 insertions(+), 6 deletions(-)
```
Demo/Screenshot for feature changes and bug fixes -
```
Before — re-run on every call (loop case re-runs per iteration):
def get_all_integrations(self):
...
for integration in integrations:
if isinstance(creds, str):
import json # executes per integration record
integration["credentials"] = json.loads(creds)
After — imported once at module load:
import json # module top
...
def get_all_integrations(self):
...
for integration in integrations:
if isinstance(creds, str):
integration["credentials"] = json.loads(creds)
```
Local checks (clean baseline preserved):
```
$ make lint && make format-check && make typecheck && make test-cov
ruff check app/ tests/ -> All checks passed!
ruff format --check app/ tests/ -> 1057 files already formatted
mypy app/ -> Success: no issues found in 456 source files
pytest -> 4656 passed, 2 skipped, 21 warnings in ~49s
```
Code Understanding and AI Usage
Did you use AI assistance (ChatGPT, Claude, Copilot, etc.) to write any part of this code?
If you used AI assistance:
Explain your implementation approach:
The change is the same surgical pattern as #1216: `import json` is moved out of the function body and added to the module's top-level imports, sorted alphabetically alongside the existing stdlib imports. Once `json` is in `sys.modules` after first import, the inside-function `import json` statement is not "free" — the interpreter still re-runs the import statement on every call, performing a `sys.modules` lookup and binding the name into the function's local namespace. The most egregious case here is `tracer_integrations.py:68`, where the original import sat inside a `for` loop iterating integration records, so the statement re-ran once per record.
No semantic change: `json.loads` and `json.JSONDecodeError` are referenced identically before and after; the only difference is where the name binding originates. The full test suite (4656 tests) continues to pass with the same skip count and no new warnings.
I considered also touching `app/nodes/resolve_integrations/node.py` (which has `import base64` and `import json` inside `_decode_org_id_from_token`) but kept it out of scope to keep this PR small and to avoid a function that was the subject of an unrelated, contentious prior PR — happy to send a follow-up if maintainers want it covered.
Checklist before requesting a review