Skip to content

feat(sdk): add Python fluent API facade, update README, and bump to 0.2.0#161

Merged
macalbert merged 7 commits intomainfrom
docs/sdk-python-fluent-api-readme
Apr 15, 2026
Merged

feat(sdk): add Python fluent API facade, update README, and bump to 0.2.0#161
macalbert merged 7 commits intomainfrom
docs/sdk-python-fluent-api-readme

Conversation

@macalbert
Copy link
Copy Markdown
Owner

@macalbert macalbert commented Apr 15, 2026

Summary

Introduces the Envilder facade class for the Python SDK, providing one-liner
and fluent builder APIs for secret resolution. Updates the README with usage
examples, adds badges, and bumps the package version to 0.2.0.

Changes

New: Envilder facade (envilder_facade.py)

  • Envilder.load(file) — resolve + inject into os.environ in one call
  • Envilder.resolve_file(file) — resolve without injecting
  • Envilder.from_file(file).with_provider(...).with_vault_url(...).resolve() — fluent builder
  • with_provider(), with_vault_url(), with_profile() — runtime overrides for $config

README

  • Rewritten Quick Start with One-liner, Resolve, Fluent builder, and Advanced usage sections
  • Added Coverage Report, PyPI version, and MIT license badges
  • Fixed code snippets: added missing imports, context managers, parenthesized continuations

Infra / CI

  • Version bumped 0.1.00.2.0 in pyproject.toml
  • Fixed Makefile format-sdk-python to split black/isort per directory
  • Fixed Biome format + lint errors in coverage-report scripts (parseInt radix, ANSI regex suppression)
  • Fixed test file paths for CI compatibility (Path(__file__) instead of relative string)

Code quality (from review feedback)

  • Added encoding="utf-8" to open() in _parse_file
  • Merged implicit string concatenations into single literals
  • Renamed test_envilder.pytest_envilder_facade.py (mirror convention)

Tests

  • 8 unit tests for the facade (resolve, inject, overrides, validation)
  • All 42 Python SDK tests pass (unit + e2e)

Testing

  • make check-sdk-python passes (black, isort, mypy)
  • pytest — 42/42 pass
  • pnpm biome check — clean
  • All 19 review threads resolved

Related

Follows feat/sdk-python-fluent-api (merged to main).

Add Envilder facade with one-liner and fluent builder patterns:

- Envilder.load('map.json') — resolve + inject into os.environ
- Envilder.resolve_file('map.json') — resolve to dict
- Envilder.from_file('map.json').with_provider(...).resolve()
- Envilder.from_file('map.json').with_profile(...).inject()

Existing EnvilderClient/MapFileParser/SecretProviderFactory unchanged.
8 new tests covering resolve, inject, overrides, and validation.
Copilot AI review requested due to automatic review settings April 15, 2026 15:14
gemini-code-assist[bot]

This comment was marked as resolved.

@macalbert macalbert self-assigned this Apr 15, 2026
@macalbert macalbert added the enhancement New feature or request label Apr 15, 2026
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 15, 2026

Walkthrough

Introduces a new Envilder facade class that simplifies the Python SDK API through a fluent builder pattern, wrapping existing components (MapFileParser, SecretProviderFactory, EnvilderClient). Provides static methods for direct usage (load(), resolve_file(), from_file()) and chainable instance methods for configuration. Version bumped to 0.2.0 with documentation and test updates.

Changes

Cohort / File(s) Summary
Core Facade Implementation
envilder/application/envilder_facade.py, envilder/__init__.py
New Envilder facade class with fluent API providing load(), resolve_file(), from_file() static methods and builder methods (with_provider(), with_vault_url(), with_profile()); exported from main module.
Test Coverage
tests/sdks/python/application/test_envilder_facade.py
Comprehensive test suite for Envilder facade covering resolution, injection, builder chaining, configuration overrides, and validation error handling.
Bug Fixes & Maintenance
infrastructure/secret_provider_factory.py, containers/localstack_container.py
Minor string formatting fixes in error messages for Azure Key Vault and LocalStack token resolution.
Documentation & Version
README.md, pyproject.toml
Updated README with badges and reworked Quick Start examples demonstrating simplified Envilder usage patterns; version bumped to 0.2.0.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Envilder
    participant MapFileParser
    participant SecretProviderFactory
    participant EnvilderClient
    participant Environment

    Client->>Envilder: load('secrets-map.json')
    Envilder->>MapFileParser: parse JSON file
    MapFileParser-->>Envilder: map_file dict
    Envilder->>SecretProviderFactory: create(options)
    SecretProviderFactory-->>Envilder: secret_provider
    Envilder->>EnvilderClient: resolve_secrets(map_file)
    EnvilderClient-->>Envilder: secrets dict
    Envilder->>EnvilderClient: inject_into_environment(secrets)
    EnvilderClient->>Environment: os.environ.update()
    Envilder-->>Client: secrets dict
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Suggested labels

sdk-python

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description covers key changes (Envilder facade, README updates, version bump) but lacks required template sections like Related issues, Type of change checkbox selection, and Checklist completion. Complete the PR description template by selecting the Type of change (Feature), checking applicable Checklist items (Tests added/updated, Docs updated, Lint/format pass), and noting any related issues.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the three main changes: addition of a Python fluent API facade, README updates, and version bump to 0.2.0.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/sdk-python-fluent-api-readme

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@macalbert macalbert force-pushed the docs/sdk-python-fluent-api-readme branch from 1f91838 to d2aff13 Compare April 15, 2026 15:16

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings April 15, 2026 15:23
devin-ai-integration[bot]

This comment was marked as resolved.

This comment was marked as resolved.

@macalbert macalbert force-pushed the docs/sdk-python-fluent-api-readme branch from b3da938 to 9900374 Compare April 15, 2026 15:30
Copilot AI review requested due to automatic review settings April 15, 2026 15:33
@macalbert macalbert force-pushed the docs/sdk-python-fluent-api-readme branch from 9900374 to 4f5389b Compare April 15, 2026 15:33

This comment was marked as resolved.

@macalbert macalbert force-pushed the docs/sdk-python-fluent-api-readme branch from 4f5389b to f48dfed Compare April 15, 2026 15:51
- Use Path(__file__) for MAP_FILE in test_envilder.py so tests
  pass regardless of working directory (fixes CI cd+pytest)
- Auto-format coverage-report scripts with Biome (single quotes,
  trailing newline)
Copilot AI review requested due to automatic review settings April 15, 2026 16:23
- Add radix parameter (10) to parseInt calls
- Suppress noControlCharactersInRegex for intentional ANSI stripping
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 10 changed files in this pull request and generated no new comments.

coderabbitai[bot]

This comment was marked as resolved.

- Add encoding='utf-8' to open() in envilder_facade._parse_file
- Replace backslash line continuations with parentheses in README
- Add missing import in 'Resolve without injecting' README snippet
- Use context manager in 'Advanced usage' README snippet
- Merge implicit string concatenations into single strings
- Rename test_envilder.py to test_envilder_facade.py (mirror convention)
@macalbert macalbert changed the title docs(sdk): update Python README with fluent API and bump to 0.2.0 feat(sdk): add Python fluent API facade, update README, and bump to 0.2.0 Apr 15, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
tests/sdks/python/application/test_envilder_facade.py (1)

143-157: ⚠️ Potential issue | 🟡 Minor

Remove lambda assignments in validation tests (E731).

Line 143 and Line 153 assign lambdas to action; this is a Ruff E731 violation and can fail lint checks. Call the functions directly inside pytest.raises().

♻️ Suggested fix
-        # Act
-        action = lambda: Envilder.load("non-existent.json")
-
-        # Assert
-        with pytest.raises(FileNotFoundError):
-            action()
+        # Act / Assert
+        with pytest.raises(FileNotFoundError):
+            Envilder.load("non-existent.json")
@@
-        # Act
-        action = lambda: Envilder.from_file("")
-
-        # Assert
-        with pytest.raises(ValueError, match="file_path"):
-            action()
+        # Act / Assert
+        with pytest.raises(ValueError, match="file_path"):
+            Envilder.from_file("")
#!/bin/bash
# Verify lambda assignments used for pytest "action" wrappers in this module.
rg -nP --type=py '^\s*action\s*=\s*lambda\b' tests/sdks/python/application/test_envilder_facade.py -C2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/sdks/python/application/test_envilder_facade.py` around lines 143 -
157, The tests assign lambdas to `action` (Ruff E731) before using
`pytest.raises`; replace those lambda assignments by calling the target
functions directly inside the context manager — e.g., change `action = lambda:
Envilder.load("non-existent.json"); with pytest.raises(FileNotFoundError):
action()` to `with pytest.raises(FileNotFoundError):
Envilder.load("non-existent.json")`, and similarly replace `action = lambda:
Envilder.from_file("")`/`with pytest.raises(ValueError, match="file_path"):
action()` with `with pytest.raises(ValueError, match="file_path"):
Envilder.from_file("")` so `Envilder.load` and `Envilder.from_file` are invoked
directly in the `pytest.raises` block.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/sdks/python/application/test_envilder_facade.py`:
- Around line 143-157: The tests assign lambdas to `action` (Ruff E731) before
using `pytest.raises`; replace those lambda assignments by calling the target
functions directly inside the context manager — e.g., change `action = lambda:
Envilder.load("non-existent.json"); with pytest.raises(FileNotFoundError):
action()` to `with pytest.raises(FileNotFoundError):
Envilder.load("non-existent.json")`, and similarly replace `action = lambda:
Envilder.from_file("")`/`with pytest.raises(ValueError, match="file_path"):
action()` with `with pytest.raises(ValueError, match="file_path"):
Envilder.from_file("")` so `Envilder.load` and `Envilder.from_file` are invoked
directly in the `pytest.raises` block.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6d250bfe-b41c-42cf-b3bf-fdc1c76b0e24

📥 Commits

Reviewing files that changed from the base of the PR and between b7bbc1c and 8dbf74c.

⛔ Files ignored due to path filters (2)
  • .github/workflows/coverage-report/extract-test-stats.mjs is excluded by none and included by none
  • .github/workflows/coverage-report/generate-coverage-dashboard.mjs is excluded by none and included by none
📒 Files selected for processing (5)
  • src/sdks/python/README.md
  • src/sdks/python/envilder/application/envilder_facade.py
  • src/sdks/python/envilder/infrastructure/secret_provider_factory.py
  • tests/sdks/python/application/test_envilder_facade.py
  • tests/sdks/python/containers/localstack_container.py
✅ Files skipped from review due to trivial changes (3)
  • tests/sdks/python/containers/localstack_container.py
  • src/sdks/python/envilder/infrastructure/secret_provider_factory.py
  • src/sdks/python/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/sdks/python/envilder/application/envilder_facade.py

@macalbert macalbert merged commit 5e52633 into main Apr 15, 2026
16 checks passed
@macalbert macalbert deleted the docs/sdk-python-fluent-api-readme branch April 15, 2026 17:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants