Case study / SDK Builder for 9AI
9ai-in/salla-python-sdk
Built during my backend developer internship at 9AI: an async Python SDK for Salla auth, merchant/store APIs, and webhook operations.
At a glance
- The goal was to remove repeated integration code from backend services.
- Core flow: App code -> Salla client -> Service layer -> Typed schemas
- Primary stack: Python, aiohttp, Pydantic, Async APIs
Request flow
Backend service -> async SDK -> Salla API
Application code calls one async client. The SDK routes auth, merchant/store, and webhook operations through service modules, validates payloads with typed schemas, and sends the request through a shared aiohttp base client.
App code
Backend service imports Salla() and calls token, merchant, store, or webhook methods
Salla client
One async class exposes generate_access_token_from_code, refresh token, merchant/store info, and webhook operations
Service layer
Auth, merchant, and webhook modules keep each API surface isolated instead of mixing request logic in one file
Typed schemas
Pydantic payload and response models validate access-token data, merchant/store responses, and webhook payloads
aiohttp base client
Shared async HTTP client handles outgoing requests to Salla endpoints with the right headers and auth tokens
App code
Backend service imports Salla() and calls token, merchant, store, or webhook methods
Salla client
One async class exposes generate_access_token_from_code, refresh token, merchant/store info, and webhook operations
Service layer
Auth, merchant, and webhook modules keep each API surface isolated instead of mixing request logic in one file
Typed schemas
Pydantic payload and response models validate access-token data, merchant/store responses, and webhook payloads
aiohttp base client
Shared async HTTP client handles outgoing requests to Salla endpoints with the right headers and auth tokens
Contributions
What I built
- Implemented async client methods for token exchange, merchant/store reads, and webhook lifecycle operations.
- Added typed payload and response schemas so callers can rely on validated objects instead of raw JSON.
- Shipped v0.1.0 and followed with auth and webhook refinements.
Technical decisions
Key engineering decisions
- Split auth, merchant, and webhook logic into separate service modules so each endpoint family stays easy to extend and test.
- Used async aiohttp under the hood so the SDK fits naturally into backend services that already run async workloads.
- Wrapped requests and responses in Pydantic models to keep OAuth payloads, webhook subscriptions, and API responses predictable.
Challenges
Constraints and challenges
- OAuth token exchange is easy to get wrong when a wrapper supports both authorization-code and refresh-token flows.
- Webhook integrations need more than a POST helper; the SDK also had to cover listing registered hooks, listing available events, and unsubscribing by id or url.
- The public API had to stay simple for users while still exposing enough structure for backend teams to debug failed integrations.
Outcomes
Impact
- Replaced repeated per-service integration code with one reusable SDK surface.
- Covered the full integration loop: auth, merchant/store reads, webhook registration, discovery, and cleanup.
- Delivered as a public package with 5 merged PRs and 12 commits.