Add SDK source, config, CI, and documentation#2
Merged
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copies vendored source (providers, budget, circuit breaker, client, config, tokenizer, stream, reporter) and full test suite (303 tests). Fixes mypy strict-mode issues not caught by monorepo config: list[Any] type arg, cast() for __exit__ returns, tiktoken optional-import ignore, and an unused type: ignore[override] on the Pydantic model_validator. Adds mypy overrides for tiktoken (optional dependency, no stubs). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move all tests into tests/unit/ subdirectory following the testing strategy docs. Add tests/integration/ with credential-bootstrapping fixtures that auto-create a user/project via the API. - Reorganize tests into tests/unit/ and tests/integration/ - Register all 5 pytest markers (unit, integration, chaos, perf, stress) - Add @pytest.mark.unit to 6 unmarked test files - Add @pytest.mark.unit + @pytest.mark.asyncio (proper order) to async methods - Standardize anyio -> asyncio markers - Fix import discipline in conftest (httpx to module top) - Fix SDK_SRC paths for new directory depth - Make BudgetCheckResponse.denied_by_period required (no silent default) - Align all deny-scenario mocks with real API contract - CI workflows now filter with -m unit; integration job is opt-in Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover the three critical async gaps identified in the coverage audit: - AsyncBudgetEnforcer: check_budget (allow, deny-hard, deny-alert, fail-open), confirm_cost (success, error swallowing), close - AsyncMetadataReporter: start/close lifecycle, batch sending, flush correctness, context manager protocol - AsyncSolwyn: non-streaming call passthrough with confirm_cost Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create three CLAUDE.md files for Claude Code context: - Root: project overview, commands, architecture, rules - tests/: marker conventions, integration test setup, mocking patterns - src/solwyn/: module map, provider notes, thread safety Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
v6 of these actions does not exist as a published release, causing checkout path errors in the GitHub Actions runner. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This reverts commit 706f45e.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mirror core repo's pre-commit setup: scripts/pre-commit runs `make check` (lint + format check + typecheck) before each commit. Also fixes ruff format issues in 4 test files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove stale `# sdks/python/...` path comments from 4 files left over from the monorepo extraction. Add uv.lock for reproducible installs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ents - Normalize SolwynConfig.model_config to use ConfigDict() (was plain dict) - Remove monorepo provenance comments from docstrings - Fix stale test path in _privacy.py (tests/unit/ prefix) - Remove ../core reference from CLAUDE.md architecture diagram - Move src/solwyn/CLAUDE.md to src/CLAUDE.md (exclude from wheel) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add hatch wheel exclude rule for CLAUDE.md instead of moving the file out of the package directory. Developers get the context file; end users don't get it in their install. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove monorepo-specific rule (no solwyn_api imports), add Pydantic v2 rule, switch commands to Makefile targets. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move 8 provider proxy classes from client.py into _proxies.py to improve readability. client.py drops from 750 to 617 lines, with the core interception logic now easier to follow. Add comment in _types.py explaining why TokenDetails lives in a separate module (circular-import avoidance). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Align with the GitHub account email. Replaces dev@solwyn.io in pyproject.toml authors and SECURITY.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add badges (CI, PyPI, Python versions, license) - Fix quickstart to include required api_key/project_id kwargs - Add provider-specific examples (OpenAI, Anthropic, Google) - Add async, streaming, and budget enforcement sections - Add configuration table with all env vars - Add error handling reference - Add contributing section with make commands - Keep data transparency table Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make api_key and project_id optional on both Solwyn and AsyncSolwyn constructors. When omitted, SolwynConfig loads them from SOLWYN_API_KEY and SOLWYN_PROJECT_ID environment variables — matching the convention used by openai-python and stripe-python. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tie the publish job to a GitHub 'pypi' environment. Required to match the PyPI trusted publisher config and enables protection rules + a deployment history page on GitHub. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Not using a GitHub environment for the trusted publisher config. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ties the publish job to a GitHub 'pypi' environment for release protection. Pair with a 'required reviewer' rule to add a manual approval gate before any PyPI publish. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Standalone Python SDK extracted from the Solwyn monorepo, fully configured for independent development, testing, and PyPI publishing.
The Solwyn SDK is a drop-in wrapper for OpenAI, Anthropic, and Google LLM clients that adds budget enforcement, circuit breaking, and usage tracking. It never sees customer prompts — the SDK only reports metadata (token counts, latency, model name) to the Solwyn API after each call. Pricing and budget logic live on the server, so pricing updates never require an SDK release.
What's in this repo
SDK source (
src/solwyn/)Solwyn/AsyncSolwyn— drop-in wrappers for sync and async provider clientsBudgetEnforcer— cloud budget check with local fallback + fail-open defaultCircuitBreaker— local-only circuit breaker state machine with failoverMetadataReporter— non-blocking background queue (threading for sync,asyncio.create_taskfor async)_privacy.py) — the only module allowed to touch prompt content, enforced by structural testsTesting (
tests/)tests/unit/— all marked@pytest.mark.unit, run in CI with-m unittests/integration/— auto-bootstraps test credentials via the API (signup → project creation → API key). CI opt-in viarun-integrationlabel orworkflow_dispatchunit,integration,chaos,performance,stressAsyncBudgetEnforcer,AsyncMetadataReporterlifecycle,AsyncSolwynnon-streaming path-Osafe), and stream non-blocking behaviorBudgetCheckResponse.denied_by_periodis required (no silentdefault=None) — contract drift fails loudlyTooling
Makefile—make check,make test,make install-hooksas single entry pointsscripts/pre-commit— runsmake check(ruff + format + mypy strict)-m unitfilteringCLAUDE.mdfiles at root,src/solwyn/, andtests/for development context (excluded from the wheel)ConfigDict,@model_validator,.model_dump()Developer experience
Environment variable discovery for credentials (matches openai-python / stripe-python conventions):
Test plan
make checkpasses (ruff + format + mypy strict)uv run pytest tests/ -m unitpasses (297 passed)uv run pytest tests/ -m integrationpasses against local API (10 passed)hatch buildproduces a clean wheel with no CLAUDE.md, no test files, nosolwyn_sharedpip install solwynfrom wheel works in clean venv