Skip to content

fix: move stdlib json import to module level in hot-path tracer + lambda functions#1243

Merged
VaibhavUpreti merged 1 commit intoTracer-Cloud:mainfrom
cloudenochcsis:fix/1242-hot-path-imports
May 3, 2026
Merged

fix: move stdlib json import to module level in hot-path tracer + lambda functions#1243
VaibhavUpreti merged 1 commit intoTracer-Cloud:mainfrom
cloudenochcsis:fix/1242-hot-path-imports

Conversation

@cloudenochcsis
Copy link
Copy Markdown
Contributor

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

  • app/services/tracer_client/tracer_integrations.py — added `import json` at module top; removed it from inside two functions:
    • `get_all_integrations()` — the import was inside a `for` loop iterating integration records, re-running once per iteration
    • `get_grafana_credentials()` — per-call during integration resolution
  • app/services/lambda_client.py — added `import json` at module top; removed it from inside `invoke_function()` (per Lambda invocation)

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?

  • No, I wrote all the code myself
  • Yes, I used AI assistance (continue below)

If you used AI assistance:

  • I have reviewed every single line of the AI-generated code
  • I can explain the purpose and logic of each function/component I added
  • I have tested edge cases and understand how the code handles them
  • I have modified the AI output to follow this project's coding standards and conventions

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

  • I have added proper PR title and linked to the issue
  • I have performed a self-review of my code
  • I can explain the purpose of every function, class, and logic block I added
  • I understand why my changes work and have tested them thoroughly
  • I have considered potential edge cases and how my code handles them
  • If it is a core feature, I have added thorough tests (n/a — semantic-noop import hoist; existing suite covers these code paths)
  • My code follows the project's style guidelines and conventions

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
Copy link
Copy Markdown
Member

@VaibhavUpreti VaibhavUpreti left a comment

Choose a reason for hiding this comment

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

awesome @cloudenochcsis thanks a lot for fixing this! Welcome to OpenSRE community 🚀

@VaibhavUpreti VaibhavUpreti merged commit d2cf78e into Tracer-Cloud:main May 3, 2026
6 checks passed
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 3, 2026

Greptile Summary

Moves import json from inside function/loop bodies to module top in lambda_client.py and tracer_integrations.py, matching the pattern established in #1216. The change is a semantic no-op — all call sites (json.loads, json.dumps, json.JSONDecodeError) are identical before and after; only the name-binding source changes.

Confidence Score: 5/5

Safe to merge — semantic no-op import hoist with correct alphabetical placement in both files.

Both changes are purely mechanical: import json moves from an inner scope to module top with no alteration to any call site. Import ordering is alphabetically correct in both files, the full test suite (4656 tests) passes, and there are no logic, security, or type changes to evaluate.

No files require special attention.

Important Files Changed

Filename Overview
app/services/lambda_client.py Hoisted import json from inside invoke_function() body to module top (line 4), between import base64 and from contextlib import suppress — alphabetically correct, no logic change.
app/services/tracer_client/tracer_integrations.py Hoisted import json from inside a for-loop body in get_all_integrations() and from inside get_grafana_credentials() to module top (line 5), between from __future__ import annotations and import logging — alphabetically correct, no logic change.

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
Loading

Reviews (1): Last reviewed commit: "fix: move stdlib json import to module l..." | Re-trigger Greptile

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 3, 2026

🏄 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.

muddlebee pushed a commit that referenced this pull request May 4, 2026
…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
@cloudenochcsis cloudenochcsis deleted the fix/1242-hot-path-imports branch May 4, 2026 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants