Skip to content

feat(python): read idempotency-key generation config from the IR#17014

Open
devin-ai-integration[bot] wants to merge 5 commits into
mainfrom
devin/1783700357-python-idempotency-key
Open

feat(python): read idempotency-key generation config from the IR#17014
devin-ai-integration[bot] wants to merge 5 commits into
mainfrom
devin/1783700357-python-idempotency-key

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Description

Linear ticket: Refs #17018

Switches the Python SDK generator from its own auto_generate_idempotency_key config flag to the centralized ir.sdkConfig.idempotencyKeyGeneration block published in IR SDK 67.11.0.

Runtime behavior is unchanged: eligible requests receive a UUIDv4 idempotency-key header, and a caller-supplied value takes precedence. Enablement, header name, and eligible HTTP methods now come from the IR rather than generator-specific config and hardcoded POST/PUT checks.

idempotency_key_generation = self._context.ir.sdk_config.idempotency_key_generation
enabled = idempotency_key_generation is not None and endpoint.method in idempotency_key_generation.methods

Changes Made

  • Read the idempotency header name and eligible method set from sdkConfig.idempotencyKeyGeneration while preserving the existing UUIDv4 injection and caller-wins fallback.
  • Removed the old per-generator config plumbing by rebuilding on current main; the CLI-only auto-generate-idempotency-key key now reaches the generator through the IR.
  • Bumped the Python v1 and v2 IR SDK dependencies to 67.11.0 and reconciled both lockfiles.
  • Brought in the seed-harness fallback for synthetic invocations that populate resolved config without raw.config, with unit coverage.
  • Regenerated the idempotency-headers and exhaustive feature-on fixtures using the kebab-case CLI key, with canonical seed metadata.
  • Added an unreleased feat changelog entry.
  • Updated README.md generator (if applicable) — N/A

Testing

  • Unit tests added/updated — Python v1 pytest + mypy, Python v2 Vitest, and @fern-api/api-workspace-commons Vitest pass.
  • Manual testing completed — pnpm seed test --generator python-sdk --fixture idempotency-headers exhaustive:auto-generate-idempotency-key --local --skip-scripts passes 3/3.
  • Generated SDK verification — mypy passes for all three outputs; each output's pytest suite passes 72 tests with 4 skipped.
  • Formatting/linting — Biome, Prettier, Ruff, and Python pre-commit hooks pass.

The feature-on generated client contains:

"Idempotency-Key": str(idempotency_key) if idempotency_key is not None else str(uuid.uuid4()),

The no-config fixture contains no UUID injection. Held for external sign-off; do not merge yet.

Link to Devin session: https://app.devin.ai/sessions/e429bcae88c74ab28101b488416486f2
Requested by: @cadesark

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

SDK Generation Benchmark Results

Comparing PR branch against median of 5 nightly run(s) on main (latest: 2026-07-13T05:08:13Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
python-sdk square 135s (n=5) 241s (n=5) 135s +0s (+0.0%)

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-07-13T05:08:13Z). Trigger benchmark-baseline to refresh.
Last updated: 2026-07-13 23:37 UTC

@devin-ai-integration devin-ai-integration Bot force-pushed the devin/1783700357-python-idempotency-key branch from a0b5f89 to f474c7b Compare July 10, 2026 21:28
@devin-ai-integration devin-ai-integration Bot changed the title feat(python): auto-generate idempotency key for POST/PUT feat(python): read idempotency-key generation config from the IR Jul 10, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Runtime-tested the generated Python SDKs locally through httpx.MockTransport.

  • Passed — caller-supplied Idempotency-Key: caller-123 wins.
  • Passed — default DELETE request has no idempotency header.
  • Passed — custom IR { headerName: "X-Custom-Idem", methods: [PATCH] } injects a valid UUIDv4 on PATCH only; POST/PUT receive no idempotency header.
  • Passed — feature-off fixture has zero uuid.uuid4() calls.
  • Passed — temporary custom SDK passes mypy across 142 source files; worktree restored clean.
Runtime evidence

Caller wins and DELETE is excluded

Custom IR header and PATCH-only method gating

Key generated source
# committed feature-on fixture
"Idempotency-Key": str(idempotency_key) if idempotency_key is not None else str(uuid.uuid4()),

# adversarial temporary config: header-name=X-Custom-Idem, methods=[PATCH]
"X-Custom-Idem": str(uuid.uuid4())

Test session: https://app.devin.ai/sessions/e429bcae88c74ab28101b488416486f2

cade and others added 2 commits July 13, 2026 13:46
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration devin-ai-integration Bot force-pushed the devin/1783700357-python-idempotency-key branch from f474c7b to e15a433 Compare July 13, 2026 13:50
devin-ai-integration Bot and others added 2 commits July 13, 2026 17:37
…ve idempotency resolver conflict in favor of main (global api.settings support)

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

4 similar comments
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Devin is archived and cannot be woken up. Please unarchive Devin if you want to continue using it.

…n in a core helper

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants