Type hints
Type-level conventions and exported types in easy-sdk (pip).
easylabs is fully typed. Public types are tested under pyright in
standard mode and ship with the wheel via PEP 561 — no separate stubs
package to install. If you use mypy, pyright, or any LSP that
respects inline annotations, autocomplete and type checking just work.
The SDK targets Python >= 3.10 so it can use native X | None unions,
PEP 604 syntax, and from __future__ import annotations throughout.
Response models — pydantic v2
Every method returns a pydantic v2 model (or a list/dict of them).
Models inherit from easylabs.EasyModel, which sets:
extra="allow"— forward-compatible. New fields the API adds appear on the model and survivemodel_dump()round-trips.populate_by_name=True— fields withField(alias=...)accept both the alias and the snake_case name on construction.
That means:
customer = client.customers.retrieve("cus_123")
customer.id # str
customer.email # str | None
customer.tags # dict[str, Any] | None
customer.model_dump() # plain dict — useful for logging / DB insertTo go the other way (dict → model), use Customer.model_validate(...):
from easylabs import Customer
raw = {"id": "cus_123", "email": "ada@example.com"}
customer = Customer.model_validate(raw)Public types
All of these are importable from the top-level easylabs package.
Client + errors
| Type | Purpose |
|---|---|
Client | The SDK entry point. |
EasyError | Base for every SDK error. |
AuthenticationError | 401. |
PermissionError | 403 (shadows the Python builtin). |
NotFoundError | 404. |
ConflictError | 409. |
InvalidRequestError | 400 / 422. |
RateLimitError | 429 (carries retry_after_seconds). |
ServerError | 5xx. |
Webhooks
| Type | Purpose |
|---|---|
Webhooks | Static utility namespace; exposes construct_event(...). |
WebhookEvent | Verified event payload (id, type, data, created_at). |
EVENT_TYPES | Tuple of every event name the SDK knows about. |
Resource models
Customer / billing / payments:
Customer, PaymentInstrument, FinixPaymentInstrument, Transfer,
Authorization, Order, Settlement, Dispute, Wallet.
Catalog & subscriptions:
Product, ProductPrice, Subscription, SubscriptionItem,
SubscriptionDiscount, SubscriptionPlan, Coupon, PromotionCode,
ValidatePromotionCodeResponse.
Checkout:
CheckoutResponse, PaymentLink, CreatePaymentLinkResponse,
EmbeddedCheckoutSession, EmbeddedCheckoutSessionStatus,
EmbeddedCheckoutConfig, ValidateEmbeddedCheckoutSessionResponse,
CryptoPaymentStatus.
Operations:
Invoice, DunningConfig, RevenueRecoveryAutomation,
RevenueRecoveryAutomationRun, ComplianceForm, AnalyticsResult,
WebhookEndpoint, RegisteredWebhookEndpoint, WebhookDelivery.
Treasury (importable from easylabs.models):
TreasuryBankAccount, TreasuryCategory, TreasuryRecipient,
TreasuryTransaction, TreasuryPayoutLink, TreasuryRecurringPayment,
TreasuryAutoTransferRule, TreasurySecurityRule,
TreasuryApprovalRequest.
Extending models
Because EasyModel sets extra="allow", brand-new fields the API ships
between SDK releases are still accessible — just not statically typed:
customer = client.customers.retrieve("cus_123")
# Statically-known field — type-checked.
print(customer.id)
# New field the SDK doesn't know about yet — accepted at runtime.
print(customer.model_extra.get("future_field"))If you need stronger typing for an extra field across your codebase, subclass the model:
from easylabs import Customer
class TenantCustomer(Customer):
tenant_id: str | None = None
raw = client.customers.retrieve("cus_123").model_dump()
tenant_customer = TenantCustomer.model_validate(raw)