v0.1.0: Initial askii-python SDK release#1
Merged
Merged
Conversation
Bootstraps the askii Python client used by SurfSense, Plane, and the MCP servers. Ships sync (Askii) + async (AsyncAskii) clients sharing one HTTPTransport, resource-oriented surface (keys, models) plus a low-level request() escape hatch, Pydantic v2 models (SecretStr-wrapped api_key), typed exception hierarchy with FieldError mapping for 422 responses, tenacity retries honoring Retry-After, pluggable Cache Protocol with InMemoryCache + optional RedisCache, opt-in JSON logging with secret redaction and correlation-ID propagation, lifecycle hooks for Prometheus /Datadog integration, and a typer-based askii CLI. Built with hatchling + hatch-vcs (git-tag-driven versioning), strict mypy in CI, ruff lint + format, pytest with 90% coverage gate, and a release workflow that attaches wheel/sdist artifacts to GitHub Releases. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pulled the 6 Platform Key Management path strings out of resources/ and test_clients.py into a single private module. Resources and tests now import named constants (PROVISION_KEY, LIST_KEYS, REVOKE_KEY, AVAILABLE_MODELS, GET_KEY_CONFIG, UPDATE_KEY_MODEL); a future API rename becomes a one-line edit instead of touching 5 files. The low-level client.request() escape hatch still accepts raw paths for endpoints not yet wrapped. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
P0 fixes: - mpass_token now merges last so a caller-supplied key in body cannot shadow the resolver's token (previous merge order let attackers/bugs override identity). - _parse_retry_after falls back to email.utils.parsedate_to_datetime when the value isn't delta-seconds, so HTTP-date form (RFC 7231 §7.1.3) is honored instead of being silently dropped. - Per-call idempotent flag on the transport, client.request escape hatch, and resource methods. keys.provision / keys.revoke / keys.update_model pass idempotent=False so a transient 5xx cannot double-apply the mutation. Read-only ops (keys.list, keys.get_config, models.list) keep the existing retry behavior. P1 hygiene: - CHANGELOG entries for URL centralization, P0 fixes, idempotent flag. - CI matrix and pyproject classifiers extended to Python 3.14. - New tests/unit/test_endpoints.py pins the _endpoints contract. - ASKII_CA_BUNDLE / ASKII_VERIFY recognized by AskiiConfig.from_env; README env-var table updated. 177 tests pass (was 152); coverage stays above the 90% gate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Brings the agent-guidance doc in line with what's actually on dev now: the centralized endpoint constants, the mpass_token merge-order invariant, the idempotent=False policy for mutating POSTs, the Retry-After HTTP-date support, and the new ASKII_CA_BUNDLE / ASKII_VERIFY env vars. Refreshes the verification baseline (177 tests, Python 3.10-3.14 matrix) and adds matching "don't do this" notes to keep future edits from regressing the invariants. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Renames the section so the release workflow's notes extractor (which greps for `## [<version>]`) picks up the right block when the v0.1.0 tag fires. Adds a fresh empty `[Unreleased]` placeholder and rewrites the compare-link footer to point at the tag. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
GitHub Actions runners surface as color-capable to Rich, so the
`stdout.print_json(...)` calls were emitting ANSI escape codes
around the JSON. `json.loads(result.stdout)` in the CLI test
suite then choked on `\x1b[1m{...` with "Expecting value: line 1
column 1". The 4 affected tests (test_keys_list_json,
test_keys_provision_unwraps_secret, test_keys_revoke_returns_json,
test_models_list_json) passed locally on macOS where Rich didn't
colorize, but failed on every CI matrix combination.
Switch the three JSON-output call sites to stdlib `print(
json.dumps(..., indent=2, default=str))` so the JSON is always
plain — pipe-friendly for `jq`, parseable by tests, and indented
for human readability. Tables and stderr error messages keep their
Rich colorization since they're human-facing.
Verified with `FORCE_COLOR=1 uv run pytest` (simulates the CI env);
all 177 tests pass, coverage 90.32%.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@v4...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 4 to 7. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](astral-sh/setup-uv@v4...v7) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
4 tasks
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
Bootstraps the askii Python SDK (sync + async clients, resource-oriented API, typed exceptions, retries, cache, CLI) that SurfSense / Plane / MCP servers consume. This PR lands the 5 commits that make up v0.1.0 against
mainso we can tag and release.What's included
9b1e616— v0.1 SDK scaffold (Askii/AsyncAskiisharing oneHTTPTransport;keys+modelsresources; Pydantic v2 models withSecretStr-wrappedapi_key; typed exception hierarchy withFieldErrorfor 422s; tenacity retries honoringRetry-After; pluggableCacheProtocol + optionalRedisCache; JSON logging with secret redaction;askiiCLI; Python 3.10–3.14 CI matrix).efb8544— Centralize Platform Key Management URL paths inaskii._endpoints.cfb5fad— P0 + P1 fixes:mpass_tokenmerge-order shadow protection;Retry-AfterHTTP-date parsing; per-callidempotentflag (mutating POSTs opt out of retries);ASKII_CA_BUNDLE/ASKII_VERIFYenv vars; Python 3.14 added to CI;tests/unit/test_endpoints.pycontract test.9a3a389—CLAUDE.mdagent-guidance refresh.598db60— CHANGELOG[Unreleased]→[0.1.0]promotion so the release workflow's notes extractor picks up the right section.Test plan
httpx.MockTransport(uv run pytest --cov=askii --cov-fail-under=90).api.sandbox.askii.ai:models listreturns 71 models, Pydanticextra="forbid"accepts the response shape.keys list / provision / get-config / update-model / revokeround-trip cleanly via both CLI and async SDK paths.AskiiAuthError(exit 2), 404 →AskiiNotFoundError(exit 6), connection refused →AskiiTransportError(exit 4).ruff check+ruff format --checkclean.uv buildproduces wheel + sdist withpy.typedshipped.Release flow after merge
main.v0.1.0on the merge commit..github/workflows/release.yml→ builds + publishes a GitHub Release with notes pulled from the[0.1.0]CHANGELOG section.🤖 Generated with Claude Code