Skip to content

refactor: simplify SDK auth, CLI output helpers, and alias CRUD#369

Merged
IonesioJunior merged 3 commits intomainfrom
refactor/simplify-sdk-cli-auth
Apr 28, 2026
Merged

refactor: simplify SDK auth, CLI output helpers, and alias CRUD#369
IonesioJunior merged 3 commits intomainfrom
refactor/simplify-sdk-cli-auth

Conversation

@IonesioJunior
Copy link
Copy Markdown
Member

@IonesioJunior IonesioJunior commented Apr 28, 2026

Summary

  • Go SDK: Introduced an authStrategy interface (bearerAuth, basicAuth, noAuth) replacing the separate basicAuthHTTPClient subtype. AccountingResource now delegates to the shared httpClient with a basicAuth strategy. Per-request auth overrides are supported via withAuthFunc. 401 retry logic gates on auth.canRefresh().
  • Python SDK: Collapsed _request_with_token into _request(token=), reusing the existing httpx client instead of spinning up a fresh one. Extracted _parallel_fetch_tokens to eliminate the duplicate fetch loop shared by get_satellite_tokens and get_guest_satellite_tokens. Added close() to the aggregator client.
  • TypeScript SDK: Extracted readSSEEvents async generator into utils.ts (shared SSE parser). Added per-key memoization caches for snakeToCamel/camelToSnake on hot paths.
  • CLI: Added clientutil.NewClient factory replacing copy-pasted client construction in every command. Added ReplyError/ReplyErrorSoft/ReplySuccess helpers and StatusSuccess/StatusError constants to the output package. Consolidated aggregator + accounting CRUD into a single generic aliasKind in alias_kind.go. Added TimeoutDuration() to nodeconfig.

Test plan

  • go test ./sdk/golang/syfthub/... — Go SDK unit tests
  • go build ./cli/... — CLI compiles cleanly
  • go vet ./... — no vet issues
  • mypy sdk/python/src/ — Python type checks pass
  • ruff check/format sdk/python/src/ — Python lint clean
  • tsc --noEmit in sdk/typescript/ — TypeScript checks pass
  • Manual smoke: syft login, syft ls, syft add aggregator, syft list aggregator, syft remove aggregator

- Go SDK: introduce authStrategy interface (bearerAuth/basicAuth/noAuth),
  eliminating basicAuthHTTPClient subtype; per-request auth override via
  withAuthFunc; accounting.go now delegates to shared httpClient
- Python SDK: collapse _request_with_token into _request(token=) param;
  extract _parallel_fetch_tokens to deduplicate satellite/guest token fetch
- TypeScript SDK: extract readSSEEvents async generator into utils.ts;
  memoize snakeToCamel/camelToSnake converters
- CLI: add clientutil.NewClient factory replacing per-command boilerplate;
  add ReplyError/ReplyErrorSoft/ReplySuccess helpers + StatusSuccess/StatusError
  constants in output package; consolidate aggregator+accounting CRUD into
  generic aliasKind in alias_kind.go; nodeconfig gains TimeoutDuration()
@IonesioJunior IonesioJunior merged commit ffb9a87 into main Apr 28, 2026
27 checks passed
@IonesioJunior IonesioJunior deleted the refactor/simplify-sdk-cli-auth branch April 28, 2026 15:51
IonesioJunior added a commit that referenced this pull request Apr 28, 2026
* fix: SyftHub compatibility with Syft Space multi-wallet-fr PR (#359)

* fix(xendit): align credits_url key and bundle-usage URL path with syft-space

The syft-space publish handler sends the balance-check URL under the key
'credits_url' at the path /api/v1/payments/gateway/bundle-usage/{slug}.
SyftHub was reading 'bundle_usage_url' and pointing tests at /bundles/{slug},
causing the Xendit balance check to silently return null and the 'not
subscribed' state to persist even after a completed purchase.

Changes:
- xendit-policy-content.tsx: read config.credits_url instead of config.bundle_usage_url
- test_endpoints.py: rename key bundle_usage_url -> credits_url in both fixtures
  (_XENDIT_POLICY, _XENDIT_POLICY_MINIMAL) and all four assertions that check
  the round-tripped value; update URL path /bundles/ -> /bundle-usage/ throughout

* fix(syfthub): address compatibility issues 4, 5, and 6 for multi-wallet-fr

Issue 4 — bundle format mismatch (xendit-policy-content.tsx, test_endpoints.py):
  The Syft Space PR sends Xendit policy config as {bundles:[{name,amount}]} +
  price_per_request instead of the legacy bundle_tiers format. The frontend now
  normalises both: tries bundle_tiers first; falls back to bundles and derives
  units = floor(amount / price_per_request). Adds _XENDIT_POLICY_V2 fixture and
  a round-trip test for the new format.

Issue 5 — mpp_accounting policy type unknown to frontend (policy-item.tsx):
  Adds mpp_accounting entry to POLICY_TYPE_CONFIG (Coins icon, emerald palette,
  MPP Micro-payment label). Without this entry the policy fell through to
  DEFAULT_POLICY_CONFIG and rendered as a generic unlabelled card with no context.

Issue 6 — archived endpoints not reflected in SyftHub (model, schemas, service, migration):
  Adds archived: bool (default False) to EndpointModel and all public schemas
  (EndpointBase -> EndpointCreate, EndpointUpdate, Endpoint, EndpointResponse,
  EndpointPublicResponse). When archived=True the service forces visibility to
  PRIVATE so the endpoint disappears from public marketplace listings. Adds
  Alembic migration 009_add_archived.

* refactor: remove legacy bundle_tiers compat, use bundles format only

Drop BundleTier interface and the conditional normalization block from
xendit-policy-content.tsx — the component now reads config.bundles
directly as MoneyBundle[]. fetchSubscriptionStatus reads only
remaining_balance (no more credits/units/balance fallback chain).
Remaining balance display now shows currency + amount.

In test_endpoints.py: replace _XENDIT_POLICY with the bundles format,
delete _XENDIT_POLICY_V2, remove the old bundle_tiers round-trip test,
rename test_create_endpoint_with_xendit_policy_v2 → _xendit_policy,
and update all bundle_tiers assertions to bundles.

* fix: align credits_url test fixtures with Space PR's /bundles/ path

The Syft Space publish_handler.py injects credits_url as
/api/v1/payments/gateway/bundles/{slug}. Revert our test fixtures
from /bundle-usage/ back to /bundles/ so SyftHub tests match what
the Space branch actually publishes.

* docs: update compatibility analysis with correct findings and fix status

* fix(ci): add missing archived field to test fixture and fix codecov input name

- Add archived=False to sample_endpoint fixture in test_endpoint_service.py;
  the Endpoint schema gained a required archived field on this branch but
  the fixture was never updated, causing all endpoint service tests to fail
  at setup with a pydantic ValidationError.
- Rename file: to files: in both codecov/codecov-action@v5 upload steps
  (cli and go-sdk); v5 dropped the singular file input in favour of files.

* fix(tests): add missing archived field to all Endpoint fixtures in test_main.py

The Endpoint schema on this branch requires archived: bool (no default).
All 13 Endpoint(…) instantiations in test_main.py were missing it,
causing every test that touched those fixtures to fail at setup with
pydantic ValidationError: 1 validation error for Endpoint / missing.

* chore(deps): bump the uv group across 4 directories with 3 updates (#363)

Bumps the uv group with 2 updates in the /components/aggregator directory: [pytest](https://github.com/pytest-dev/pytest) and [pillow](https://github.com/python-pillow/Pillow).
Bumps the uv group with 2 updates in the /components/backend directory: [pytest](https://github.com/pytest-dev/pytest) and [python-multipart](https://github.com/Kludex/python-multipart).
Bumps the uv group with 1 update in the /components/mcp directory: [python-multipart](https://github.com/Kludex/python-multipart).
Bumps the uv group with 1 update in the /sdk/python directory: [pytest](https://github.com/pytest-dev/pytest).


Updates `pytest` from 9.0.2 to 9.0.3
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@9.0.2...9.0.3)

Updates `pillow` from 12.1.1 to 12.2.0
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](python-pillow/Pillow@12.1.1...12.2.0)

Updates `pytest` from 8.4.2 to 9.0.3
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@9.0.2...9.0.3)

Updates `python-multipart` from 0.0.22 to 0.0.26
- [Release notes](https://github.com/Kludex/python-multipart/releases)
- [Changelog](https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md)
- [Commits](Kludex/python-multipart@0.0.22...0.0.26)

Updates `python-multipart` from 0.0.22 to 0.0.26
- [Release notes](https://github.com/Kludex/python-multipart/releases)
- [Changelog](https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md)
- [Commits](Kludex/python-multipart@0.0.22...0.0.26)

Updates `pytest` from 8.4.2 to 9.0.3
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@9.0.2...9.0.3)

---
updated-dependencies:
- dependency-name: pytest
  dependency-version: 9.0.3
  dependency-type: direct:production
  dependency-group: uv
- dependency-name: pillow
  dependency-version: 12.2.0
  dependency-type: indirect
  dependency-group: uv
- dependency-name: pytest
  dependency-version: 9.0.3
  dependency-type: direct:development
  dependency-group: uv
- dependency-name: python-multipart
  dependency-version: 0.0.26
  dependency-type: direct:production
  dependency-group: uv
- dependency-name: python-multipart
  dependency-version: 0.0.26
  dependency-type: direct:production
  dependency-group: uv
- dependency-name: pytest
  dependency-version: 9.0.3
  dependency-type: direct:production
  dependency-group: uv
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump the uv group across 3 directories with 3 updates (#366)

Bumps the uv group with 1 update in the /components/aggregator directory: [litellm](https://github.com/BerriAI/litellm).
Bumps the uv group with 1 update in the /components/backend directory: [python-dotenv](https://github.com/theskumar/python-dotenv).
Bumps the uv group with 1 update in the /components/mcp directory: [authlib](https://github.com/authlib/authlib).


Updates `litellm` from 1.83.0 to 1.83.7
- [Release notes](https://github.com/BerriAI/litellm/releases)
- [Commits](https://github.com/BerriAI/litellm/commits)

Updates `python-dotenv` from 1.2.1 to 1.0.1
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md)
- [Commits](theskumar/python-dotenv@v1.2.1...v1.2.2)

Updates `python-dotenv` from 1.2.1 to 1.2.2
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md)
- [Commits](theskumar/python-dotenv@v1.2.1...v1.2.2)

Updates `authlib` from 1.6.9 to 1.6.11
- [Release notes](https://github.com/authlib/authlib/releases)
- [Changelog](https://github.com/authlib/authlib/blob/v1.6.11/docs/changelog.rst)
- [Commits](authlib/authlib@v1.6.9...v1.6.11)

---
updated-dependencies:
- dependency-name: litellm
  dependency-version: 1.83.7
  dependency-type: indirect
  dependency-group: uv
- dependency-name: python-dotenv
  dependency-version: 1.0.1
  dependency-type: indirect
  dependency-group: uv
- dependency-name: python-dotenv
  dependency-version: 1.2.2
  dependency-type: direct:production
  dependency-group: uv
- dependency-name: authlib
  dependency-version: 1.6.11
  dependency-type: direct:production
  dependency-group: uv
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps): bump python-dotenv (#368)

Bumps the uv group with 1 update in the /components/aggregator directory: [python-dotenv](https://github.com/theskumar/python-dotenv).


Updates `python-dotenv` from 1.0.1 to 1.2.2
- [Release notes](https://github.com/theskumar/python-dotenv/releases)
- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md)
- [Commits](theskumar/python-dotenv@v1.0.1...v1.2.2)

---
updated-dependencies:
- dependency-name: python-dotenv
  dependency-version: 1.2.2
  dependency-type: indirect
  dependency-group: uv
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore(deps-dev): bump postcss (#367)

Bumps the npm_and_yarn group with 1 update in the /components/frontend directory: [postcss](https://github.com/postcss/postcss).


Updates `postcss` from 8.5.6 to 8.5.12
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.5.6...8.5.12)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.12
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix: add alembic merge migration to resolve multiple heads (#370)

009_wallet_fields and 009_add_archived both descend from
008_encrypt_accounting_pw, causing 'alembic upgrade head' to fail in
deploy.sh with "Multiple head revisions are present". Adds merge migration
010_merge_heads to unify the two branches into a single head.

Also fixes a mypy error in get_owner_endpoint: Starlette 0.36+ requires
TemplateResponse(request, name, context) — request moves out of context dict.

* refactor: simplify SDK auth, CLI output helpers, and alias CRUD (#369)

* refactor: simplify SDK auth, CLI output helpers, and alias CRUD

- Go SDK: introduce authStrategy interface (bearerAuth/basicAuth/noAuth),
  eliminating basicAuthHTTPClient subtype; per-request auth override via
  withAuthFunc; accounting.go now delegates to shared httpClient
- Python SDK: collapse _request_with_token into _request(token=) param;
  extract _parallel_fetch_tokens to deduplicate satellite/guest token fetch
- TypeScript SDK: extract readSSEEvents async generator into utils.ts;
  memoize snakeToCamel/camelToSnake converters
- CLI: add clientutil.NewClient factory replacing per-command boilerplate;
  add ReplyError/ReplyErrorSoft/ReplySuccess helpers + StatusSuccess/StatusError
  constants in output package; consolidate aggregator+accounting CRUD into
  generic aliasKind in alias_kind.go; nodeconfig gains TimeoutDuration()

* fix(go-sdk): remove unused noAuth authStrategy to satisfy staticcheck

* chore: remove accidentally committed md files and byproducts

* docs: consolidate READMEs and remove orphaned docs (#371)

* chore: remove orphaned byproduct docs

- COMPATIBILITY_ANALYSIS.md (root cross-repo analysis)
- sdk/golang/syfthubapi/REFACTORING_PLAN.md
- docs/agent-endpoint-workflow-design.md
- docs/llm-chat-workflow.md

None were referenced from docs/index.md or any other file.

* docs: rewrite READMEs in popular-repo style, switch license refs to Apache 2.0

- Slim each README to a clear purpose, brief feature list, minimal quick
  start, and links to /docs — instead of inlining full API specs.
- Backend README was a leftover uv template; replaced with a SyftHub-
  specific overview.
- All license mentions now match the LICENSE file (Apache 2.0).

* docs: remove all sub-READMEs in favor of single top-level README

All component, SDK, example, and skills READMEs are removed. The root
README plus /docs cover everything they previously did.

* fix: drop readme field from pyproject.toml files

Sub-READMEs were removed in d75ec10 but three pyproject.toml files
still referenced README.md, breaking editable builds in CI with
OSError: Readme file does not exist.

* docs: add OpenMined logo to README

* fix: remove stale README.md COPY from Dockerfiles (#372)

The consolidate-READMEs commit (e6e6a83) deleted README.md from component
directories and removed the readme field from pyproject.toml, but the
Dockerfiles still referenced COPY README.md, causing Docker builds to fail
with "not found" errors for all three failing CI jobs.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Ionésio Junior <ionesiojr@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[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.

1 participant