Skip to content

v0.1.0: Initial askii-python SDK release#1

Merged
hunzlahmalik merged 9 commits into
mainfrom
dev
May 21, 2026
Merged

v0.1.0: Initial askii-python SDK release#1
hunzlahmalik merged 9 commits into
mainfrom
dev

Conversation

@hunzlahmalik
Copy link
Copy Markdown
Collaborator

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 main so we can tag and release.

What's included

  • 9b1e616 — v0.1 SDK scaffold (Askii / AsyncAskii sharing one HTTPTransport; keys + models resources; Pydantic v2 models with SecretStr-wrapped api_key; typed exception hierarchy with FieldError for 422s; tenacity retries honoring Retry-After; pluggable Cache Protocol + optional RedisCache; JSON logging with secret redaction; askii CLI; Python 3.10–3.14 CI matrix).
  • efb8544 — Centralize Platform Key Management URL paths in askii._endpoints.
  • cfb5fad — P0 + P1 fixes: mpass_token merge-order shadow protection; Retry-After HTTP-date parsing; per-call idempotent flag (mutating POSTs opt out of retries); ASKII_CA_BUNDLE / ASKII_VERIFY env vars; Python 3.14 added to CI; tests/unit/test_endpoints.py contract test.
  • 9a3a389CLAUDE.md agent-guidance refresh.
  • 598db60 — CHANGELOG [Unreleased][0.1.0] promotion so the release workflow's notes extractor picks up the right section.

Test plan

  • 177 unit tests pass locally via httpx.MockTransport (uv run pytest --cov=askii --cov-fail-under=90).
  • Sandbox validation against api.sandbox.askii.ai:
    • models list returns 71 models, Pydantic extra="forbid" accepts the response shape.
    • keys list / provision / get-config / update-model / revoke round-trip cleanly via both CLI and async SDK paths.
    • Error mapping: 401 → AskiiAuthError (exit 2), 404 → AskiiNotFoundError (exit 6), connection refused → AskiiTransportError (exit 4).
  • ruff check + ruff format --check clean.
  • uv build produces wheel + sdist with py.typed shipped.

Release flow after merge

  1. Merge this PR into main.
  2. Tag v0.1.0 on the merge commit.
  3. Pushing the tag triggers .github/workflows/release.yml → builds + publishes a GitHub Release with notes pulled from the [0.1.0] CHANGELOG section.

🤖 Generated with Claude Code

hunzlahmalik and others added 9 commits May 21, 2026 13:08
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>
@hunzlahmalik hunzlahmalik merged commit eb7591d into main May 21, 2026
26 checks passed
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.

1 participant