feat(http): add canonical request lifecycle - #2210
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
07e412a to
1743c83
Compare
1743c83 to
6fad585
Compare
6fad585 to
95c2003
Compare
Greptile SummaryThis PR adds the canonical
|
| Filename | Overview |
|---|---|
| nemoguardrails/http/request.py | New file implementing managed request lifecycle: _resolve_http_client context manager handles client ownership (injected vs owned), and http_call wraps request execution with deterministic cleanup and optional status-error raising. Logic is sound. |
| nemoguardrails/http/runtime.py | New file providing create_http_client factory that composes HttpxHTTPClient and RetryingHTTPClient. Delegation of validation to the transport layer is intentional; duplicated timeout constant is flagged. |
| nemoguardrails/http/errors.py | HTTPStatusError now extracts retry_count from response.extensions, overriding the base-class default of 0. Type guard on the extracted value is correct. |
| tests/http/test_request.py | Good coverage of ownership semantics, status-error raising, credential sanitization, and error propagation. All assertions are specific and deterministic. |
| tests/http/test_runtime.py | Covers factory composition (with and without retry), option forwarding, and close delegation. Test assertions are correct against the implementation. |
| nemoguardrails/http/init.py | Exports create_http_client and http_call; public surface is minimal and consistent with the rest of the module. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["http_call(client, method, url, ...)"] --> B{client provided?}
B -- Yes --> C["_resolve_http_client yields injected client\n(no ownership taken)"]
B -- No --> D["factory() → owned ClosableHTTPClient"]
D --> E{isinstance ClosableHTTPClient?}
E -- No --> F["raise TypeError"]
E -- Yes --> G["_resolve_http_client yields owned client\n(finally: await owned.close())"]
C --> H["resolved.request(method, url, ...)"]
G --> H
H -- raises --> I["Exception propagates\n(owned client still closed via finally)"]
H -- success --> J["response captured outside context manager"]
J --> K{raise_for_status\nand status >= 400?}
K -- No --> L["return response"]
K -- Yes --> M["response.raise_for_status(HTTPRequest(...))\n-> HTTPStatusError with sanitized URL\n and retry_count from extensions"]
Reviews (6): Last reviewed commit: "perf(http): skip success request context" | Re-trigger Greptile
eb9066c to
9138450
Compare
9138450 to
623ba26
Compare
tgasser-nv
left a comment
There was a problem hiding this comment.
Looks good!
nit: Could you add add docstrings to the new files to match the existing files like client.py, types.py, etc in this directory?
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
623ba26 to
4d67108
Compare
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (16)
📝 WalkthroughWalkthroughIntroduces a transport-neutral asynchronous HTTP package with request/response types, client protocols, HTTPX transport, retry handling, lifecycle management, URL sanitization, runtime composition, test doubles, and comprehensive tests. ChangesHTTP foundation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant http_call
participant create_http_client
participant RetryingHTTPClient
participant HttpxHTTPClient
Caller->>http_call: submit HTTP request
http_call->>create_http_client: create client
create_http_client->>RetryingHTTPClient: optionally configure retries
RetryingHTTPClient->>HttpxHTTPClient: send request
HttpxHTTPClient-->>RetryingHTTPClient: response or transport error
RetryingHTTPClient-->>http_call: final response
http_call-->>Caller: return response or raise error
Possibly related PRs
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (5 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
⚔️ Resolve merge conflicts 💡
🧪 Generate unit tests (beta)
Comment |
Signed-off-by: Pouyanpi <13303554+Pouyanpi@users.noreply.github.com>
Description
Adds the canonical
http_callrequest helper and managed HTTP clientcomposition on top of the Stack 9 contract.
Design principle: lifecycle ownership is explicit. Injected clients remain
caller-owned; only fallback clients created by
http_callare closed by thehelper. Request execution therefore stays transport-neutral and can be reused by
IORails or library integrations without duplicating cleanup logic.
Instrumentation is intentionally separate in sibling Stack 10. It decorates the
same client contract without becoming a dependency of the request lifecycle or
later migrations.
developRelated Issue(s)
Verification
make test TEST="tests/http"— 65 passed.AI Assistance
Codex assisted with implementation, validation, and stack restructuring. Check
the disclosure box after human review.
Checklist
Summary by CodeRabbit
Retry-Aftersupport.