Skip to content

feat(client): carry request priority on RequestContext#1205

Open
dgarros wants to merge 2 commits into
infrahub-developfrom
dga/feat-rate-limiting-api-zb38x
Open

feat(client): carry request priority on RequestContext#1205
dgarros wants to merge 2 commits into
infrahub-developfrom
dga/feat-rate-limiting-api-zb38x

Conversation

@dgarros

@dgarros dgarros commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Companion SDK changes for the priority-aware server-side API backpressure feature in Infrahub.

  • Carry request priority on RequestContext so a per-request X-Priority can be propagated by callers.
  • Rename the middle priority tier NORMALMEDIUM.

Pairs with opsmill/infrahub#9879 (priority-aware server-side API backpressure). That PR bumps the python_sdk submodule pointer to this branch's tip, so this SDK PR must merge first (or alongside it).

🤖 Generated with Claude Code


Summary by cubic

Adds RequestContext.priority to drive the X-Priority header on all client requests and renames Priority.NORMAL to Priority.MEDIUM to align with backend. Supports INFP-636 (priority-aware API backpressure).

  • New Features

    • RequestContext.priority emits X-Priority on InfrahubClient and InfrahubClientSync requests.
    • Precedence: per-call priority= > request_context.priority > Config.priority > none.
    • Priority is header-only and never included in mutation bodies.
  • Migration

    • Replace Priority.NORMAL with Priority.MEDIUM; update INFRAHUB_PRIORITY=normal to medium.

Written for commit 522c870. Summary will update on new commits.

Review in cubic

dgarros and others added 2 commits July 22, 2026 05:06
Add an optional `priority` field to RequestContext so a client-set context
drives the X-Priority header. Resolution precedence is per-call `priority=`
kwarg > request_context.priority > Config.priority default > no header. The
priority is emitted as a header only and is excluded from the mutation body
serialization (the server context input accepts only `account`).

Part of INFP-636.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Align the SDK `Priority` enum with the backend `WorkflowPriority`
(high/medium/low) so the X-Priority wire value and the enum members match.
The case-insensitive resolution is unchanged.

Part of INFP-636.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dgarros
dgarros requested a review from a team as a code owner July 22, 2026 05:18
@github-actions github-actions Bot added the type/documentation Improvements or additions to documentation label Jul 22, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying infrahub-sdk-python with  Cloudflare Pages  Cloudflare Pages

Latest commit: 522c870
Status: ✅  Deploy successful!
Preview URL: https://bc8a3c42.infrahub-sdk-python.pages.dev
Branch Preview URL: https://dga-feat-rate-limiting-api-z.infrahub-sdk-python.pages.dev

View logs

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

3 issues found across 11 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="infrahub_sdk/node/node.py">

<violation number="1" location="infrahub_sdk/node/node.py:287">
P2: A per-call `RequestContext(priority=...)` is silently ignored: excluding it here removes the value from the mutation, but the subsequent transport call does not receive that per-call context and only checks `client.request_context`. Resolving the explicit context's priority into the effective `priority` argument would preserve the documented `priority=` > `request_context.priority` > `Config.priority` behavior.</violation>
</file>

<file name="infrahub_sdk/client.py">

<violation number="1" location="infrahub_sdk/client.py:258">
P2: File downloads, artifact-generation calls, and password-authentication requests still omit `RequestContext.priority` because they bypass `_request_headers`; the companion admission layer classifies a missing header as MEDIUM at opsmill/infrahub#9879/backend/infrahub/api/admission/middleware.py:87-92, so high/low work on these paths can be admitted or shed at the wrong tier. Centralizing the context-priority merge in the low-level transports would cover all request paths.</violation>
</file>

<file name="infrahub_sdk/constants.py">

<violation number="1" location="infrahub_sdk/constants.py:20">
P2: Existing SDK callers using `Priority.NORMAL` will fail at runtime after upgrading, making this a public API compatibility break. Keeping `NORMAL` as an alias of `MEDIUM` preserves those callers while emitting the new `medium` wire value.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread infrahub_sdk/node/node.py
# priority rides the X-Priority header, not the mutation body — the server context input has no such field
if request_context:
return request_context.model_dump(exclude_none=True)
return request_context.model_dump(exclude_none=True, exclude={"priority"}) or None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: A per-call RequestContext(priority=...) is silently ignored: excluding it here removes the value from the mutation, but the subsequent transport call does not receive that per-call context and only checks client.request_context. Resolving the explicit context's priority into the effective priority argument would preserve the documented priority= > request_context.priority > Config.priority behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At infrahub_sdk/node/node.py, line 287:

<comment>A per-call `RequestContext(priority=...)` is silently ignored: excluding it here removes the value from the mutation, but the subsequent transport call does not receive that per-call context and only checks `client.request_context`. Resolving the explicit context's priority into the effective `priority` argument would preserve the documented `priority=` > `request_context.priority` > `Config.priority` behavior.</comment>

<file context>
@@ -282,14 +282,15 @@ def __setattr__(self, name: str, value: Any) -> None:
+        # priority rides the X-Priority header, not the mutation body — the server context input has no such field
         if request_context:
-            return request_context.model_dump(exclude_none=True)
+            return request_context.model_dump(exclude_none=True, exclude={"priority"}) or None
 
         client: InfrahubClient | InfrahubClientSync | None = getattr(self, "_client", None)
</file context>

Comment thread infrahub_sdk/client.py
if priority is not None:
headers["X-Priority"] = priority.value
effective_priority = priority
if effective_priority is None and self._request_context is not None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: File downloads, artifact-generation calls, and password-authentication requests still omit RequestContext.priority because they bypass _request_headers; the companion admission layer classifies a missing header as MEDIUM at opsmill/infrahub#9879/backend/infrahub/api/admission/middleware.py:87-92, so high/low work on these paths can be admitted or shed at the wrong tier. Centralizing the context-priority merge in the low-level transports would cover all request paths.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At infrahub_sdk/client.py, line 258:

<comment>File downloads, artifact-generation calls, and password-authentication requests still omit `RequestContext.priority` because they bypass `_request_headers`; the companion admission layer classifies a missing header as MEDIUM at opsmill/infrahub#9879/backend/infrahub/api/admission/middleware.py:87-92, so high/low work on these paths can be admitted or shed at the wrong tier. Centralizing the context-priority merge in the low-level transports would cover all request paths.</comment>

<file context>
@@ -254,8 +254,11 @@ def _request_headers(self, tracker: str | None = None, priority: Priority | None
-        if priority is not None:
-            headers["X-Priority"] = priority.value
+        effective_priority = priority
+        if effective_priority is None and self._request_context is not None:
+            effective_priority = self._request_context.priority
+        if effective_priority is not None:
</file context>

Comment thread infrahub_sdk/constants.py

HIGH = "high"
NORMAL = "normal"
MEDIUM = "medium"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: Existing SDK callers using Priority.NORMAL will fail at runtime after upgrading, making this a public API compatibility break. Keeping NORMAL as an alias of MEDIUM preserves those callers while emitting the new medium wire value.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At infrahub_sdk/constants.py, line 20:

<comment>Existing SDK callers using `Priority.NORMAL` will fail at runtime after upgrading, making this a public API compatibility break. Keeping `NORMAL` as an alias of `MEDIUM` preserves those callers while emitting the new `medium` wire value.</comment>

<file context>
@@ -17,7 +17,7 @@ class Priority(str, enum.Enum):
 
     HIGH = "high"
-    NORMAL = "normal"
+    MEDIUM = "medium"
     LOW = "low"
 
</file context>
Suggested change
MEDIUM = "medium"
MEDIUM = "medium"
NORMAL = MEDIUM

@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
infrahub_sdk/node/node.py 50.00% 1 Missing ⚠️
@@                 Coverage Diff                  @@
##           infrahub-develop    #1205      +/-   ##
====================================================
- Coverage             83.98%   83.26%   -0.72%     
====================================================
  Files                   139      139              
  Lines                 14390    12442    -1948     
  Branches               2381     1853     -528     
====================================================
- Hits                  12085    10360    -1725     
+ Misses                 1654     1519     -135     
+ Partials                651      563      -88     
Flag Coverage Δ
integration-tests 40.28% <10.00%> (-2.40%) ⬇️
python-3.10 57.04% <80.00%> (-1.62%) ⬇️
python-3.11 57.04% <80.00%> (-1.62%) ⬇️
python-3.12 57.04% <80.00%> (-1.60%) ⬇️
python-3.13 57.04% <80.00%> (-1.62%) ⬇️
python-3.14 57.02% <80.00%> (-1.63%) ⬇️
python-filler-3.12 22.50% <10.00%> (-0.22%) ⬇️

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

Files with missing lines Coverage Δ
infrahub_sdk/client.py 79.73% <100.00%> (-1.17%) ⬇️
infrahub_sdk/config.py 91.46% <ø> (-3.30%) ⬇️
infrahub_sdk/constants.py 93.33% <100.00%> (-1.12%) ⬇️
infrahub_sdk/context.py 100.00% <100.00%> (+100.00%) ⬆️
infrahub_sdk/node/node.py 87.75% <50.00%> (-0.92%) ⬇️

... and 11 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type/documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant