finished new customer routes

This commit is contained in:
John Yeo
2026-02-16 17:45:45 +00:00
268 changed files with 14181 additions and 5197 deletions

View File

@@ -2,63 +2,298 @@
alwaysApply: true
---
# SDK Architecture Rules (Speakeasy Monorepo)
# SDK Generation Pipeline
## Purpose
This rule explains how SDK generation and SDK-consumer packages are wired in this monorepo, and defines the required update path when adding or changing SDK-backed behavior.
This guide explains the complete SDK generation pipeline from Zod schemas to React hooks.
## Canonical Pipeline (Conceptual)
1. OpenAPI contract source lives in `shared/api/_openapi/v2.1/` (router + contracts).
2. `bun api` (root) delegates to `shared/api/api.ts` and generates OpenAPI YAML in `shared/openapi/openapi.yml` (default 2.1 flow).
3. For v2.1, Speakeasy runs from `packages/sdk` and regenerates `@useautumn/sdk`.
4. `autumn-js` consumes `@useautumn/sdk` and re-exports SDK client types/classes through `packages/autumn-js/src/sdk/index.ts`.
5. `autumn-js` backend adapters mount `/api/autumn/*` routes for host apps.
6. `autumn-js/react` hooks call those mounted backend routes.
7. `apps/sdk-test` exercises package integrations scenario-by-scenario.
## Pipeline Overview
```
Zod Schemas → ORPC Contracts → OpenAPI Spec → Speakeasy SDKs → autumn-js Wrapper → React Hooks
```
Run `bun api` from root to execute the full pipeline.
---
## 1. Zod Schema Layer
**Location:** `shared/api/`
Schemas define request/response shapes with field descriptions and internal field markers.
### Key Patterns
- Use `.describe()` for field descriptions that appear in API docs
- Use `.meta({ internal: true })` to mark fields that should be stripped from the public OpenAPI spec
- Use `.meta({ id: "SchemaName" })` for schema registration in OpenAPI components
### Example
```typescript
// shared/api/customers/crud/createCustomerParams.ts
export const CreateCustomerParamsV0Schema = z.object({
id: CustomerIdSchema.optional().nullable(),
name: z.string().optional().describe("Customer display name"),
// Internal fields - stripped from public API
entity_id: z.string().optional().meta({ internal: true }),
with_autumn_id: z.boolean().default(false).meta({ internal: true }),
});
```
---
## 2. ORPC Contract Layer
**Location:** `packages/openapi/v2.1/contracts/`
Uses `@orpc/contract` to define route contracts that reference Zod schemas.
### Contract Structure
Each contract defines:
- `method`: HTTP method (API is transitioning to RPC-style, so all POST)
- `path`: Route path (e.g., `/v1/customers.getOrCreate`)
- `operationId`: Unique operation identifier for SDK method naming
- `tags`: Grouping for docs
- `input`: Request body schema (with `.meta()` for examples)
- `output`: Response schema
### Example
```typescript
// packages/openapi/v2.1/contracts/customersContract.ts
export const getOrCreateCustomerContract = oc
.route({
method: "POST",
path: "/v1/customers.getOrCreate",
operationId: "getOrCreate",
tags: ["customers"],
description: getOrCreateCustomerJsDoc,
})
.input(
CreateCustomerParamsV1Schema.meta({
title: "GetOrCreateCustomerParams",
examples: [{ customer_id: "cus_123", name: "John Doe" }],
}),
)
.output(ApiCustomerV5Schema);
```
### Router Aggregation
All contracts are aggregated in `packages/openapi/v2.1/contracts/index.ts`:
```typescript
export const v2_1ContractRouter = oc.router({
getOrCreateCustomer: getOrCreateCustomerContract,
listPlans: listPlansContract,
attach: attachContract,
});
```
---
## 3. OpenAPI Generation
**Entry point:** `packages/openapi/v2.1/openapi2.1.ts`
### Step 3a: Register Internal Schemas
`packages/openapi/utils/registerInternalSchemas.ts` recursively walks Zod schemas and registers any with `.meta({ internal: true })` in the JSON_SCHEMA_INPUT_REGISTRY with `x-internal: true`. Call this for each schema that may contain internal fields.
### Step 3b: Generate via ORPC
Uses `@orpc/openapi` `OpenAPIGenerator` with `ZodToJsonSchemaConverter` to produce the raw OpenAPI document from the contract router.
### Step 3c: Apply Speakeasy Settings
`packages/openapi/utils/openapiTransform/applySpeakeasySettings.ts`:
- Adds `secretKey` bearer auth security scheme
- Configures `x-speakeasy-globals` with hidden `x-api-version` header parameter (defaults to "2.1")
### Step 3d: Inject Global Header Parameters
`packages/openapi/utils/openapiTransform/injectGlobalHeaderParameters.ts` adds the `x-api-version` header to every operation. This header is hidden in the SDK (users don't need to set it) but automatically sent with every request.
Server parses this in `server/src/honoMiddlewares/apiVersionMiddleware.ts` to determine API version for response formatting.
### Step 3e: Remove Internal Fields
`packages/openapi/utils/openapiTransform/removeInternalFields.ts` strips fields/parameters marked with `x-internal: true` or `internal: true` from the final spec. This ensures internal fields don't appear in the public API documentation or generated SDKs.
---
## 4. SDK Generation
**Entry point:** `packages/openapi/api.ts`
### Step 4a: Generate SDKs in Parallel
`packages/openapi/utils/sdkGeneration/generateSdks.ts` runs Speakeasy CLI for both targets:
- **TypeScript:** `bunx speakeasy run -t autumn` → `packages/sdk/`
- **Python:** `bunx speakeasy run -t autumn-python` → `others/python-sdk/`
Speakeasy config lives in `packages/sdk/.speakeasy/workflow.yaml` and `gen.yaml`.
### Step 4b: Patch Python SDK
`packages/openapi/utils/sdkGeneration/patchPythonSdk.ts` fixes a Speakeasy bug where `get_global_from_env` returns `None` and overrides Pydantic defaults for `x-api-version`. This ensures the default version header works correctly.
### Step 4c: Merge Code Samples
`packages/openapi/utils/sdkGeneration/mergeCodeSamples.ts` applies Speakeasy overlay files (`.speakeasy/code-samples.overlay.yaml`) to add TypeScript and Python code samples to the OpenAPI spec used for documentation.
---
## 5. Mintlify Documentation Transform
**Location:** `packages/openapi/utils/mintlifyTransform/`
### Step 5a: Transform OpenAPI
- **Strip JSDoc tags:** Removes `@example`, `@deprecated`, etc. from descriptions for cleaner docs
- **Transform code samples:** Converts Speakeasy SDK format to cleaner autumn-js format (simpler imports like `import { Autumn } from 'autumn-js'`, removes async wrappers and console.log)
- **Copy schema examples:** Moves examples from schema level to response content level for Mintlify rendering
### Step 5b: Generate API Reference MDX
`packages/openapi/utils/apiReferenceGenerator/` parses the OpenAPI spec and generates `DynamicParamField`/`DynamicResponseField` components. These enable dynamic field switching in Mintlify docs (showing different parameter descriptions based on context).
---
## 6. autumn-js Wrapper Layer
**Location:** `packages/autumn-js/`
The autumn-js package wraps the generated SDK and provides framework integrations.
### 6a: Backend Router
`packages/autumn-js/src/libraries/backend/routes/backendRouter.ts` creates pass-through routes that users mount on their backend (e.g., `/api/autumn/*`).
**Route groups:** customers, billing, entities, referrals, products, gen (general)
**Pattern:** Route handlers use `withAuth` to inject identity and call the SDK:
```typescript
export const handleGetOrCreateCustomer = withAuth({
fn: async ({ autumn, customerId, customerData, body }) => {
return await autumn.customers.getOrCreate({
customerId,
...customerData,
...body,
});
},
});
```
**Response format:** `packages/autumn-js/src/libraries/backend/utils/backendRes.ts` wraps responses in a consistent structure with `{ statusCode, body }`. Errors include `{ message, code, statusCode, details }` for frontend console logging.
### 6b: React Client
`packages/autumn-js/src/libraries/react/client/ReactAutumnClient.tsx` mirrors the SDK interface but routes through the mounted backend routes.
**CORS Detection:** The client auto-detects CORS credential support:
1. `detectCors()` makes test requests to `/api/autumn/cors` with and without credentials
2. `shouldIncludeCredentials()` caches the result and logs a warning suggesting users set `includeCredentials` explicitly
3. Users can override with the `includeCredentials` prop in `AutumnProvider`
**Client methods:** `attach`, `checkout`, `cancel`, `check`, `track`, `openBillingPortal`, `setupPayment`, `query`, plus namespaced methods for `customers`, `entities`, `referrals`, `products`.
### 6c: React Hooks
Hooks like `packages/autumn-js/src/libraries/react/hooks/useCustomer.tsx`:
- Use SWR for data fetching with automatic caching
- Accept `expand`, `errorOnNotFound`, and `swrConfig` params
- Return `{ customer, isLoading, error, refetch }` plus SDK action methods
- Get client from `AutumnContext` or accept a `client` prop directly
---
## 7. Framework Integrations
### Better Auth Plugin
`packages/autumn-js/src/libraries/backend/better-auth.ts` is a `BetterAuthPlugin` that:
- Mounts Autumn routes under `/api/auth/autumn/*`
- Extracts identity from Better Auth session
- Supports `customerScope: "user" | "organization" | "user_and_organization"`
- Auto-maps user/org to `customerId` and `customerData`
### Convex Client
`packages/autumn-js/src/libraries/react/client/ConvexAutumnClient.tsx`:
- Implements `IAutumnClient` interface
- Routes through Convex actions instead of HTTP (`convex.action()`)
- Stubs HTTP methods (`post`, `get`, etc.) with errors
- Same method signatures as `AutumnClient` for drop-in replacement
---
## 8. Testing (sdk-test)
**Location:** `apps/sdk-test/`
### Scenario Pattern
Each integration is tested via scenario pages organized by provider:
- `scenarios/core/` - Default HTTP provider
- `scenarios/better-auth/` - Better Auth integration
- `scenarios/convex/` - Convex integration
### Page Structure
Each scenario page follows a consistent pattern:
1. **Hook params panel:** Exact params passed to the hook
2. **Hook state panel:** Loading, error, lastUpdatedAt
3. **Payload viewer:** Customer/entity data returned
4. **Action controls:** Refetch, etc.
### Scenario Registry
`apps/sdk-test/lib/scenarios.ts` tracks all scenarios with status:
- `ready` - Implemented and working
- `wip` - Work in progress
- `planned` - Not yet implemented
---
## Source of Truth Rules
1. API behavior starts at contracts, not generated code.
2. Do not hand-edit generated `packages/sdk/src/**` as a source of truth; regeneration can overwrite it.
3. If SDK shapes are wrong, fix contracts/OpenAPI generation inputs first.
4. Keep backend route behavior aligned with generated SDK operation models from `@useautumn/sdk/models/operations`.
## `autumn-js` Component Map
### A) Backend routing layer
- Entry router: `packages/autumn-js/src/libraries/backend/routes/backendRouter.ts`
- Route groups: customers, billing, core/gen, entities, referrals, products.
- Route handlers call `Autumn` client methods (from `@useautumn/sdk`) and inject identity through `withAuth`.
- Adapters (`next`, `hono`, `express`, `fastify`, `better-auth`, etc.) all delegate into this shared router pattern.
1. **API behavior starts at Zod schemas and contracts**, not generated code
2. **Never hand-edit** `packages/sdk/src/**` - regeneration will overwrite
3. **If SDK shapes are wrong**, fix schemas/contracts first, then regenerate
4. **Keep backend routes aligned** with generated SDK operation models
### B) React client + hooks layer
- Provider: `AutumnProvider` (`ReactAutumnProvider`) sets client transport config (`backendUrl`, `pathPrefix`, auth headers).
- Hooks (`useCustomer`, `useEntity`, `useAutumn`, etc.) read from provider context and call backend routes.
- Hook payload types should come from `@useautumn/sdk` models/operations where possible.
### C) SDK wrapper layer
- `packages/autumn-js/src/sdk/index.ts` re-exports `Autumn` and SDK exports from `@useautumn/sdk`.
- Backend code imports `Autumn` via `@sdk` alias to keep a stable internal import surface.
### D) Integration test harness (`apps/sdk-test`)
- Scenario-driven app with one page per tested component/integration.
- Core pattern per scenario: params panel, state panel, payload viewer, action controls.
- Current and future integrations are represented uniformly (core, better-auth, convex).
- Use this app as the canonical manual verification surface for SDK-consumer packages.
---
## Required Change Workflow
When adding or changing an SDK-backed feature:
1. Update contract definitions under `shared/api/_openapi/v2.1/contracts/*`.
2. Ensure the v2.1 contract router includes the new operation.
3. Regenerate OpenAPI + SDK via existing pipeline.
4. Wire/adjust `autumn-js` backend route mapping.
5. Wire/adjust `autumn-js/react` client methods/hooks.
6. Add or update `apps/sdk-test` scenario coverage for the affected component.
## Consistency Rules for Agents
1. Always describe pipeline impacts in PR/task notes when touching contracts/SDK wrappers/hooks.
2. Keep naming consistent between operation intent, backend route path, and hook/action name.
3. Prefer shared route/auth handling (`withAuth` + central router) over one-off adapter logic.
4. Treat `apps/sdk-test` as required integration documentation, not optional demo code.
When adding or changing SDK-backed features:
## Scope Assumptions
- Convex integration is included as part of target architecture, even where implementation is still in progress.
- Rules describe intended steady-state architecture, while allowing explicit WIP markers in scenario status metadata.
1. **Update Zod schemas** in `shared/api/` (use `.meta({ internal: true })` for internal fields)
2. **Add/update ORPC contract** in `packages/openapi/v2.1/contracts/`
3. **Add contract to router** in `packages/openapi/v2.1/contracts/index.ts`
4. **Regenerate** via `bun api` from root
5. **Wire backend route** in `autumn-js` if needed
6. **Wire React hook method** if needed
7. **Add scenario test coverage** in `apps/sdk-test/`
---
## Key File Paths
| Purpose | Path |
|---------|------|
| Zod schemas | `shared/api/` |
| ORPC contracts | `packages/openapi/v2.1/contracts/` |
| OpenAPI generation | `packages/openapi/v2.1/openapi2.1.ts` |
| Pipeline entry | `packages/openapi/api.ts` |
| Generated TS SDK | `packages/sdk/` |
| Generated Python SDK | `others/python-sdk/` |
| autumn-js backend | `packages/autumn-js/src/libraries/backend/` |
| autumn-js react | `packages/autumn-js/src/libraries/react/` |
| SDK tests | `apps/sdk-test/` |

View File

@@ -16,7 +16,7 @@ Refactor `handleCreateCustomer` to:
Three overlapping types with duplicated ID validation logic:
- `CreateCustomerSchema` in `shared/models/cusModels/cusModels.ts`
- `CustomerDataSchema` in `shared/api/common/customerData.ts`
- `CreateCustomerParamsSchema` in `shared/api/customers/customerOpModels.ts`
- `CreateCustomerParamsV0Schema` in `shared/api/customers/crud/createCustomerParams.ts`
### Solution
@@ -87,8 +87,8 @@ import { CustomerDataSchema, CustomerIdSchema } from "../common/customerData.js"
// Remove duplicate customerId const, use CustomerIdSchema instead
export const CreateCustomerParamsSchema = z.object({
id: CustomerIdSchema.nullable().meta({
export const CreateCustomerParamsV0Schema = z.object({
id: CustomerIdSchema.optional().nullable().meta({
description: "Your unique identifier for the customer",
}),
...CustomerDataSchema.shape,

View File

@@ -500,3 +500,39 @@ import { DynamicResponseExample } from "/components/dynamic-response-example.jsx
<DynamicResponseField name="payment_method" type="any | null" />
<ResponseExample>
```json 200
{
"id": "cus_123",
"created_at": 1717000000,
"name": "John Doe",
"email": "john@example.com",
"fingerprint": "1234567890",
"stripe_id": "cus_123",
"env": "sandbox",
"metadata": {},
"subscriptions": [
{
"id": "sub_123",
"created_at": 1717000000,
"plan_id": "plan_123",
"status": "active",
"quantity": 1,
"interval": "month",
"interval_count": 1
}
],
"purchases": [],
"balances": {
"balance_1": {
"id": "balance_1",
"amount": 100,
"currency": "USD",
"created_at": 1717000000,
"updated_at": 1717000000
}
}
}
```
</ResponseExample>

View File

@@ -0,0 +1,144 @@
---
title: "Attach"
openapi: "openapi POST /v1/attach"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="options" type="object[] | null">
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="quantity" type="number" />
<DynamicParamField body="reset_after_trial_end" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="version" type="number" />
<DynamicParamField body="free_trial" type="object | null">
<Expandable title="properties">
<DynamicParamField body="length" type="number" required />
<DynamicParamField body="duration" type="'day' | 'month' | 'year'" required />
<DynamicParamField body="card_required" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
<Expandable title="properties">
<DynamicParamField body="type" type="'feature' | 'priced_feature' | 'price'">
The type of the product item.
</DynamicParamField>
<DynamicParamField body="feature_id" type="string | null">
The feature ID of the product item. Should be null for fixed price items.
</DynamicParamField>
<DynamicParamField body="included_usage" type="number | null">
The amount of usage included for this feature (per interval).
</DynamicParamField>
<DynamicParamField body="interval" type="enum">
The reset or billing interval of the product item. If null, feature will have no reset date, and if there's a price, it will be billed one-off.
</DynamicParamField>
<DynamicParamField body="interval_count" type="number | null">
Interval count of the feature.
</DynamicParamField>
<DynamicParamField body="entity_feature_id" type="string | null">
The feature ID of the entity (like seats) to track sub-balances for.
</DynamicParamField>
<DynamicParamField body="usage_model" type="'prepaid' | 'pay_per_use'">
Whether the feature should be prepaid upfront or billed for how much they use end of billing period.
</DynamicParamField>
<DynamicParamField body="price" type="number | null">
The price of the product item. Should be null if tiered pricing is set.
</DynamicParamField>
<DynamicParamField body="tiers" type="object[] | null">
Tiered pricing for the product item. Not applicable for fixed price items.
<Expandable title="properties">
<DynamicParamField body="to" type="number" required>
The maximum amount of usage for this tier.
</DynamicParamField>
<DynamicParamField body="amount" type="number" required>
The price of the product item for this tier.
</DynamicParamField>
</Expandable>
</DynamicParamField>
<DynamicParamField body="billing_units" type="number | null">
The billing units of the product item (eg $1 for 30 credits).
</DynamicParamField>
<DynamicParamField body="reset_usage_when_enabled" type="boolean | null">
Whether the usage should be reset when the product is enabled.
</DynamicParamField>
</Expandable>
</DynamicParamField>
<DynamicParamField body="product_id" type="string" required />
<DynamicParamField body="invoice" type="boolean" />
<DynamicParamField body="enable_product_immediately" type="boolean" />
<DynamicParamField body="finalize_invoice" type="boolean" />
<DynamicParamField body="redirect_mode" type="'always' | 'if_required' | 'never'" />
<DynamicParamField body="success_url" type="string" />
<DynamicParamField body="new_billing_subscription" type="boolean" />
<DynamicParamField body="plan_schedule" type="'immediate' | 'end_of_cycle'" />
<DynamicParamField body="billing_behavior" type="'prorate_immediately' | 'next_cycle_only'" />
<DynamicParamField body="adjustable_quantity" type="boolean" />
### Response
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="invoice" type="object">
<Expandable title="properties">
<DynamicResponseField name="status" type="string | null" />
<DynamicResponseField name="stripe_id" type="string" />
<DynamicResponseField name="total" type="number" />
<DynamicResponseField name="currency" type="string" />
<DynamicResponseField name="hosted_invoice_url" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="payment_url" type="string | null" />
<DynamicResponseField name="required_action" type="object">
<Expandable title="properties">
<DynamicResponseField name="code" type="'3ds_required' | 'payment_method_required' | 'payment_failed'" />
<DynamicResponseField name="reason" type="string" />
</Expandable>
</DynamicResponseField>

View File

@@ -0,0 +1,534 @@
---
title: "Get Or Create"
openapi: "openapi POST /v1/customers.getOrCreate"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string | null" required>
Your unique identifier for the customer
</DynamicParamField>
<DynamicParamField body="name" type="string | null">
Customer's name
</DynamicParamField>
<DynamicParamField body="email" type="string | null">
Customer's email address
</DynamicParamField>
<DynamicParamField body="fingerprint" type="string | null">
Unique identifier (eg, serial number) to detect duplicate customers and prevent free trial abuse
</DynamicParamField>
<DynamicParamField body="metadata" type="object | null">
Additional metadata for the customer
</DynamicParamField>
<DynamicParamField body="stripe_id" type="string | null">
Stripe customer ID if you already have one
</DynamicParamField>
<DynamicParamField body="create_in_stripe" type="boolean">
Whether to create the customer in Stripe
</DynamicParamField>
<DynamicParamField body="auto_enable_plan_id" type="string">
The ID of the free plan to auto-enable for the customer
</DynamicParamField>
<DynamicParamField body="send_email_receipts" type="boolean">
Whether to send email receipts to this customer
</DynamicParamField>
<DynamicParamField body="expand" type="enum[]">
Customer expand options
</DynamicParamField>
### Response
<DynamicResponseField name="name" type="string | null">
The name of the customer.
</DynamicResponseField>
<DynamicResponseField name="email" type="string | null">
The email address of the customer.
</DynamicResponseField>
<DynamicResponseField name="fingerprint" type="string | null">
A unique identifier (eg. serial number) to de-duplicate customers across devices or browsers. For example: apple device ID.
</DynamicResponseField>
<DynamicResponseField name="stripe_id" type="string | null">
Stripe customer ID.
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'">
The environment this customer was created in.
</DynamicResponseField>
<DynamicResponseField name="metadata" type="object">
The metadata for the customer.
</DynamicResponseField>
<DynamicResponseField name="send_email_receipts" type="boolean">
Whether to send email receipts to the customer.
</DynamicResponseField>
<DynamicResponseField name="subscriptions" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan" type="object">
<Expandable title="properties">
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="enum" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="status" type="'active' | 'scheduled' | 'expired'" />
<DynamicResponseField name="past_due" type="boolean" />
<DynamicResponseField name="canceled_at" type="number | null" />
<DynamicResponseField name="expires_at" type="number | null" />
<DynamicResponseField name="trial_ends_at" type="number | null" />
<DynamicResponseField name="started_at" type="number" />
<DynamicResponseField name="current_period_start" type="number | null" />
<DynamicResponseField name="current_period_end" type="number | null" />
<DynamicResponseField name="quantity" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="purchases" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan" type="object">
<Expandable title="properties">
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="enum" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="expires_at" type="number | null" />
<DynamicResponseField name="started_at" type="number" />
<DynamicResponseField name="quantity" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="balances" type="object" />
<DynamicResponseField name="invoices" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan_ids" type="string[]">
Array of plan IDs included in this invoice
</DynamicResponseField>
<DynamicResponseField name="stripe_id" type="string">
The Stripe invoice ID
</DynamicResponseField>
<DynamicResponseField name="status" type="string">
The status of the invoice
</DynamicResponseField>
<DynamicResponseField name="total" type="number">
The total amount of the invoice
</DynamicResponseField>
<DynamicResponseField name="currency" type="string">
The currency code for the invoice
</DynamicResponseField>
<DynamicResponseField name="hosted_invoice_url" type="string | null">
URL to the Stripe-hosted invoice page
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="entities" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="name" type="string | null">
The name of the entity
</DynamicResponseField>
<DynamicResponseField name="customer_id" type="string | null">
The customer ID this entity belongs to
</DynamicResponseField>
<DynamicResponseField name="feature_id" type="string | null">
The feature ID this entity belongs to
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'">
The environment (sandbox/live)
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="trials_used" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="fingerprint" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rewards" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="discounts" type="object[]">
Array of active discounts applied to the customer
<Expandable title="properties">
<DynamicResponseField name="name" type="string">
The name of the discount or coupon
</DynamicResponseField>
<DynamicResponseField name="type" type="'percentage_discount' | 'fixed_discount' | 'free_product' | 'invoice_credits'">
The type of reward
</DynamicResponseField>
<DynamicResponseField name="discount_value" type="number">
The discount value (percentage or fixed amount)
</DynamicResponseField>
<DynamicResponseField name="duration_type" type="'one_off' | 'months' | 'forever'">
How long the discount lasts
</DynamicResponseField>
<DynamicResponseField name="duration_value" type="number | null">
Number of billing periods the discount applies for repeating durations
</DynamicResponseField>
<DynamicResponseField name="currency" type="string | null">
The currency code for fixed amount discounts
</DynamicResponseField>
<DynamicResponseField name="start" type="number | null">
Timestamp when the discount becomes active
</DynamicResponseField>
<DynamicResponseField name="end" type="number | null">
Timestamp when the discount expires
</DynamicResponseField>
<DynamicResponseField name="subscription_id" type="string | null">
The Stripe subscription ID this discount is applied to
</DynamicResponseField>
<DynamicResponseField name="total_discount_amount" type="number | null">
Total amount saved from this discount
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="referrals" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="program_id" type="string" />
<DynamicResponseField name="customer" type="object">
<Expandable title="properties">
<DynamicResponseField name="name" type="string | null" />
<DynamicResponseField name="email" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="reward_applied" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="payment_method" type="any | null" />
<ResponseExample>
```json 200
{
"id": "cus_123",
"created_at": 1717000000,
"name": "John Doe",
"email": "john@example.com",
"fingerprint": "1234567890",
"stripe_id": "cus_123",
"env": "sandbox",
"metadata": {},
"subscriptions": [
{
"id": "sub_123",
"created_at": 1717000000,
"plan_id": "plan_123",
"status": "active",
"quantity": 1,
"interval": "month",
"interval_count": 1
}
],
"purchases": [],
"balances": {
"balance_1": {
"id": "balance_1",
"amount": 100,
"currency": "USD",
"created_at": 1717000000,
"updated_at": 1717000000
}
}
}
```
</ResponseExample>

View File

@@ -0,0 +1,131 @@
---
title: "List Plans"
openapi: "openapi GET /v1/products"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
### Response
<DynamicResponseField name="list" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="enum" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>

View File

@@ -795,8 +795,7 @@ paths:
$ref: "#/components/schemas/Customer"
example: *a2
parameters:
- &a3
name: x-api-version
- name: x-api-version
in: header
required: true
schema:
@@ -816,6 +815,18 @@ paths:
name: "John Doe",
email: "john@example.com",
});
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
autumn = Autumn(secret_key="am_sk_test...")
res = autumn.customers.get_or_create(
customer_id="cus_123",
name="John Doe",
email="john@example.com",
)
/v1/products:
get:
operationId: list
@@ -823,7 +834,13 @@ paths:
tags:
- plans
parameters:
- *a3
- name: x-api-version
in: header
required: true
schema:
type: string
default: "2.1"
x-speakeasy-globals-hidden: true
responses:
"200":
description: OK
@@ -847,6 +864,14 @@ paths:
const autumn = new Autumn()
const result = await autumn.plans.list();
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
autumn = Autumn(secret_key="am_sk_test...")
res = autumn.plans.list()
/v1/attach:
post:
operationId: attach
@@ -1075,7 +1100,13 @@ paths:
- customer_id
- payment_url
parameters:
- *a3
- name: x-api-version
in: header
required: true
schema:
type: string
default: "2.1"
x-speakeasy-globals-hidden: true
x-codeSamples:
- lang: typescript
label: Typescript (SDK)
@@ -1087,6 +1118,17 @@ paths:
const result = await autumn.billing.attach({
productId: "<id>",
});
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
autumn = Autumn(secret_key="am_sk_test...")
res = autumn.billing.attach(
product_id="<id>",
redirect_mode="always",
)
security:
- secretKey: []
x-speakeasy-globals:

View File

@@ -0,0 +1,92 @@
"use client";
import { usePricingTable } from "autumn-js/react";
import { useMemo, useState } from "react";
import { DataViewer } from "@/components/debug/DataViewer";
import { DebugCard } from "@/components/debug/DebugCard";
import { HookStatePanel } from "@/components/debug/HookStatePanel";
import { Button } from "@/components/ui/button";
export default function UsePricingTableScenarioPage() {
type UsePricingTableParams = Parameters<typeof usePricingTable>[0];
const params = useMemo(
(): NonNullable<UsePricingTableParams> => ({
productDetails: undefined,
}),
[],
);
const { products, isLoading, error, refetch } = usePricingTable(params);
const [lastUpdatedAt, setLastUpdatedAt] = useState<string | null>(null);
const onRefetch = async () => {
await refetch();
setLastUpdatedAt(new Date().toISOString());
};
return (
<div className="space-y-4">
<div>
<h1 className="text-lg font-semibold tracking-tight">
Core / usePricingTable
</h1>
<p className="mt-1 text-sm text-zinc-500">
This page validates the usePricingTable hook which fetches and merges
product data for pricing table display.
</p>
</div>
<DebugCard
title="Hook State"
description="Loading/error lifecycle for usePricingTable"
actions={
<Button variant="outline" size="sm" onClick={onRefetch}>
Refetch
</Button>
}
>
<HookStatePanel
isLoading={isLoading}
error={error}
lastUpdatedAt={lastUpdatedAt}
/>
</DebugCard>
<div className="grid gap-4 lg:grid-cols-2">
<DebugCard
title="Hook Params"
description="Exact params passed to usePricingTable()"
>
<DataViewer
title="usePricingTable params"
value={params}
defaultExpandedDepth={3}
/>
</DebugCard>
<DebugCard
title="Products Payload"
description="Merged products array returned by autumn-js/react"
>
<DataViewer
title="products"
value={products}
defaultExpandedDepth={2}
/>
</DebugCard>
</div>
<DebugCard title="Error Payload" description="Error object (if any)">
<DataViewer
title="error"
value={
error
? { name: error.name, message: error.message, stack: error.stack }
: null
}
defaultExpandedDepth={2}
/>
</DebugCard>
</div>
);
}

View File

@@ -6,8 +6,8 @@ import { useMemo, useState } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { cn } from "@/lib/utils";
import { findScenarioByHref, scenarioSections } from "@/lib/scenarios";
import { cn } from "@/lib/utils";
export const AppSidebarLayout = ({
children,
@@ -84,7 +84,9 @@ export const AppSidebarLayout = ({
{sidebarContent}
</aside>
<div
<button
type="button"
aria-label="Close menu"
className={cn(
"fixed inset-0 z-40 bg-black/40 backdrop-blur-sm transition-opacity md:hidden",
openMobile ? "opacity-100" : "pointer-events-none opacity-0",
@@ -103,19 +105,33 @@ export const AppSidebarLayout = ({
<div className="flex min-w-0 flex-1 flex-col">
<header className="flex h-12 items-center justify-between border-b border-zinc-200 bg-white px-3 dark:border-zinc-800 dark:bg-zinc-950 md:px-4">
<div className="flex items-center gap-2">
<Button
variant="outline"
size="sm"
className="md:hidden"
onClick={() => setOpenMobile((prev) => !prev)}
<Link
href="/"
className="inline-flex h-8 items-center justify-center rounded-md border border-zinc-300 bg-white px-3 text-xs font-medium text-zinc-900 transition-colors hover:bg-zinc-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-zinc-400 dark:border-zinc-700 dark:bg-black dark:text-zinc-100 dark:hover:bg-zinc-900"
>
Menu
</Button>
<p className="text-xs text-zinc-500">
{active
? `${active.section.title} / ${active.item.title}`
: "Select a scenario"}
</p>
</Link>
<div className="text-xs text-zinc-500">
{active ? (
<>
<Link
href={active.section.items[0]?.href ?? "/"}
className="hover:text-zinc-900 hover:underline dark:hover:text-zinc-100"
>
{active.section.title}
</Link>
<span className="mx-1">/</span>
<Link
href={active.item.href}
className="hover:text-zinc-900 hover:underline dark:hover:text-zinc-100"
>
{active.item.title}
</Link>
</>
) : (
"Select a scenario"
)}
</div>
</div>
</header>

View File

@@ -40,6 +40,13 @@ export const scenarioSections: Array<ScenarioSection> = [
description: "Inspect entity-level behavior.",
status: "planned",
},
{
id: "use-pricing-table",
title: "usePricingTable",
href: "/scenarios/core/use-pricing-table",
description: "Inspect pricing table product data.",
status: "ready",
},
],
},
{

588
bun.lock

File diff suppressed because it is too large Load Diff

2
others/python-sdk/.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# This allows generated code to be indexed correctly
*.py linguist-generated=false

13
others/python-sdk/.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
.venv/
venv/
src/*.egg-info/
**/__pycache__/
.pytest_cache/
.python-version
.DS_Store
pyrightconfig.json
**/.speakeasy/temp/
**/.speakeasy/logs/
.speakeasy/reports
.env
.env.local

View File

@@ -0,0 +1,59 @@
overlay: 1.0.0
info:
title: CodeSamples overlay for python target
version: 0.0.0
actions:
- target: $["paths"]["/v1/attach"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.billing.attach(product_id="<id>", redirect_mode="always")
# Handle response
print(res)
- target: $["paths"]["/v1/customers.getOrCreate"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
- target: $["paths"]["/v1/products"]["get"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.plans.list()
# Handle response
print(res)

View File

@@ -0,0 +1,590 @@
lockVersion: 2.0.0
id: 05940b80-1ef8-40f4-9878-822fb2792070
management:
docChecksum: b65ff198c2a9d322f115152bb4da709a
docVersion: 2.1.0
speakeasyVersion: 1.719.0
generationVersion: 2.824.1
releaseVersion: 0.1.7
configChecksum: 2ca0e0ba07824d6779e7d841b9a2ee6d
persistentEdits:
generation_id: 784a6b3b-2a97-4806-9c16-587b46852288
pristine_commit_hash: 930b7289d78f6d611338929e7b8f95b00015be23
pristine_tree_hash: 0a4bdce125e410db52980e1ad137f42b1f774545
features:
python:
additionalDependencies: 1.0.0
constsAndDefaults: 1.0.6
core: 6.0.5
defaultEnabledRetries: 0.2.0
enumUnions: 0.1.0
envVarSecurityUsage: 0.3.2
flatRequests: 1.0.1
flattening: 3.1.1
globalSecurity: 3.0.5
globalSecurityCallbacks: 1.0.0
globalSecurityFlattening: 1.0.0
globalServerURLs: 3.2.0
globals: 3.0.0
hiddenGlobals: 1.0.0
methodArguments: 1.0.2
nullables: 1.0.2
responseFormat: 1.1.0
retries: 3.0.3
sdkHooks: 1.2.1
unions: 3.1.3
trackedFiles:
.gitattributes:
id: 24139dae6567
last_write_checksum: sha1:53134de3ada576f37c22276901e1b5b6d85cd2da
pristine_git_object: 4d75d59008e4d8609876d263419a9dc56c8d6f3a
.vscode/settings.json:
id: 89aa447020cd
last_write_checksum: sha1:f84632c81029fcdda8c3b0c768d02b836fc80526
pristine_git_object: 8d79f0abb72526f1fb34a4c03e5bba612c6ba2ae
USAGE.md:
id: 3aed33ce6e6f
last_write_checksum: sha1:18592530e1b98bf3a258bc1f9fce53f93b26cd82
pristine_git_object: d96fd08db8799cf32fd7d9fd6398e2741963a46d
docs/models/attachfreetrial.md:
id: 9e54da4cf801
last_write_checksum: sha1:139d74e6b20dea51525b53f771e6ebe1d1d95706
pristine_git_object: e576c4dd894a6842dccb74263739eb327657165f
docs/models/attachglobals.md:
id: 1f2407e8c680
last_write_checksum: sha1:01adc2f34b6f6da134d5aee7cf79831b95918ea7
pristine_git_object: 103e8e64817edbc22a4016c8d664eea94ac6bcf7
docs/models/attachinterval.md:
id: 6a0f3a7e1cc3
last_write_checksum: sha1:7e8c965e03119c208e523b87fcd0ec9ea8af8597
pristine_git_object: cbfcc42fabf8b9d5976415408c625e810b58f658
docs/models/attachinvoice.md:
id: 9381f0386811
last_write_checksum: sha1:2177fe22f6d5c8688dc434ea11a622d15db59f7b
pristine_git_object: eadbb80eb63e02a2eee6ec1ec2217adb03ec19a3
docs/models/attachitem.md:
id: "787007952310"
last_write_checksum: sha1:9b2ab50d5d7c9b116c70ed6474b6d44745b0f520
pristine_git_object: 2f105e6faf21c499bf71666846a0a8a654c76999
docs/models/attachrequest.md:
id: 87d11495db02
last_write_checksum: sha1:a351084a815fe0639ebe450a21bf423d74407c9a
pristine_git_object: 5c70043e68e383500f83497612c9e11469fbbcd3
docs/models/attachresponse.md:
id: 8badce83e7c2
last_write_checksum: sha1:3bd1c1294e4a1d580c4f6f02c8bd4458f78bc680
pristine_git_object: 4bb1f22643dcfe7137622ef7440d8d569b9c04e9
docs/models/attachto.md:
id: 1b02aab4ff64
last_write_checksum: sha1:7769aa8b474ca8b6a0da7616022c4374accbd8be
pristine_git_object: 94221b2b912873053d8dd3fbacc225af730e7a75
docs/models/attachtype.md:
id: 3841a517cb42
last_write_checksum: sha1:f90bd699c24b9d25d9dc0eaa19725c2439ebaa3b
pristine_git_object: a6d9d9a218c907c01d5786f0a5b430c939038a93
docs/models/balances.md:
id: 2f042cf3d0aa
last_write_checksum: sha1:aa56f8208372a5108a4114a2da289a440006a26f
pristine_git_object: bf12416b00703fba55d846d3d609d62a58455177
docs/models/billingbehavior.md:
id: 9c13c728c39d
last_write_checksum: sha1:091c29eab3328e460e5c7807af617042c59a56c3
pristine_git_object: 0e877024644cd075f8bb62873f0a009767b138b9
docs/models/breakdown.md:
id: 786823ab8ff0
last_write_checksum: sha1:ec73aad7b26b34e1e6e899221b411f44904e627d
pristine_git_object: 1a69f2b543b3732e1c44a7aa28113d3f9c2a3f89
docs/models/code.md:
id: 2fcb3964c9c0
last_write_checksum: sha1:a8d5228992892af7137ee43f2bf01cb82ade6ed6
pristine_git_object: 29bc326de035ad5501f9ebac471464ca7b996646
docs/models/customer.md:
id: 42ac97d31359
last_write_checksum: sha1:bfde5042f593ec1186c9166ce0cd8ac19a4d4533
pristine_git_object: 3cd444dd5f1e02de685a0917c05a88612cf672da
docs/models/customerbillingmethod.md:
id: 6c89219094a5
last_write_checksum: sha1:794150f51d1174c921a5ad7208c2f30792b38acd
pristine_git_object: 0f5a43b73cc95444baa7a6111ad99750a0517c38
docs/models/customerdurationtype.md:
id: dc88db3adc93
last_write_checksum: sha1:42f7f4090ec893457e1f58865a7499a419dfcf4c
pristine_git_object: 8816de7792fb2034f720195e14f1324cbe0e67ad
docs/models/customereligibility.md:
id: 6ad6cc047223
last_write_checksum: sha1:935d36a8ec3552a9ec1132543f6a236549060e1e
pristine_git_object: 2bd1c2088248cfd43d8ed713b8fc10f4222518ac
docs/models/customerenv.md:
id: 714d5f271769
last_write_checksum: sha1:0339c99475930033694fa4b6d63c9d0266596379
pristine_git_object: b5fddc48061d589c49c65ec0cd5b65c5a1891178
docs/models/customerexpand.md:
id: e85805d3c1d6
last_write_checksum: sha1:499466ca32127bb204c44df01f958d11d6e5c753
pristine_git_object: 59e884824c96f6bd19141d7db0fcf71b8a707d50
docs/models/customerintervalenum.md:
id: d28f10412e40
last_write_checksum: sha1:1aaf2650bc5bda39177e2dfe610910446000d3e9
pristine_git_object: 712415b49ff39f41707cbc2ccf31fb21c0069114
docs/models/customerprice.md:
id: 14e62b292a06
last_write_checksum: sha1:17aa0c3e56fbb0f98a1e285a3f76dbc4fb5b56ea
pristine_git_object: 88630fbeae2a7d8f4f71202bd941fde03a1a1f7b
docs/models/customerreset.md:
id: 78338a885803
last_write_checksum: sha1:1b5d82bc6391adae16dd1ac689d3e300d31bbea2
pristine_git_object: c789011c5fc6339908e580eb1925ee5ed96b97f4
docs/models/customerrollover.md:
id: 9c4ad3a98d86
last_write_checksum: sha1:a44ed6945bc97ee12a289bd286d4a76aa23935b0
pristine_git_object: 8db9ac673ec170fc6bae016cf5ba93619c84197f
docs/models/customertier.md:
id: 08a259cc5760
last_write_checksum: sha1:6d85d922d5d530e7cad004e604e495976407616d
pristine_git_object: a8fcbbcccd95b8547992ad74648615f5a379121d
docs/models/customerto.md:
id: 9008a8e5a903
last_write_checksum: sha1:7d92a838adfa2d707b56d735eb29618fd10d9803
pristine_git_object: 9cee863933300366095f209c8a27042cff7cfc4c
docs/models/discount.md:
id: 003b28f6c8a6
last_write_checksum: sha1:ce1cdb8a7e931687a18c213147d9d34fb94abc82
pristine_git_object: 58e1eafe60442a088fdbf5b3fe6bab638b298ed1
docs/models/duration.md:
id: e63d42c932a8
last_write_checksum: sha1:375f7bb11bf8e8242c4354ee9d543a8625bb1b30
pristine_git_object: d3686dc5a288ae0becca372f5c106da540e2ccef
docs/models/entity.md:
id: 903c73579a5c
last_write_checksum: sha1:21d53cd4ec4b6f5c87308a0767cbf121490add1b
pristine_git_object: 68e0ec50e5ec1fa51706c5e81133b4973a7a14a7
docs/models/entityenv.md:
id: 5c026cde1184
last_write_checksum: sha1:8a7e9be1424504f599c97ab269154498bc9c498a
pristine_git_object: 4791ce7334f87c2857cfc98e758fa7623cbed062
docs/models/expirydurationtype.md:
id: 7ba992bf53cc
last_write_checksum: sha1:012c3bc7b1084ca6f478f19b7606cb19479fcc27
pristine_git_object: d73f4f219a02fe27c18ab0f923bacf7f99574623
docs/models/freetrial.md:
id: dc73eb37daef
last_write_checksum: sha1:c1789ef30367ada63ea75c3d2ccff9a6da3a8c3c
pristine_git_object: 8a319330306ea2ec52d9c5fd937d256a98c8a1d6
docs/models/getorcreatecustomerparams.md:
id: 6bb57e046821
last_write_checksum: sha1:53a4bc89541b3de7bfd893b894c386deee187129
pristine_git_object: 438b3c3d032a0b57e9c72778ba797375ab8898b4
docs/models/getorcreateglobals.md:
id: 6d11cd2282d2
last_write_checksum: sha1:44b3280ac5034199bf71a6870cf122c35dbdb6fe
pristine_git_object: 39abbf6e66b908cf05a7369c951c9b1bb562dda0
docs/models/includedusage.md:
id: e844c6f90fe1
last_write_checksum: sha1:f45eadc2eb0f9f2543fcfd3b0d671c8fc9e1c5a8
pristine_git_object: 6af710e8393ec0d5bd29b7bc2969174b69548d55
docs/models/internal/globals.md:
id: 9c173b87f41f
last_write_checksum: sha1:f1b8e7ce642026cd3ca1df79e67c7a011f487fca
pristine_git_object: b2f8dc32fc72edb1b050a6ff282c1498eaf928f4
docs/models/interval.md:
id: 11a74d2c19c0
last_write_checksum: sha1:c8e451ae26d40c202d6964d07232be112b7ac271
pristine_git_object: e07865e4eb6089a16c91ade3acfb97671d1e5071
docs/models/invoice.md:
id: 18e2034f11ad
last_write_checksum: sha1:f800c00cb9011e4badeb748a0f4a4b016e69b597
pristine_git_object: a50ac046213c5be53fa31c669dc57f485612ed6d
docs/models/item.md:
id: 40dd7473ab87
last_write_checksum: sha1:89b5e6126d327480462fe902c1ada54999abc817
pristine_git_object: 64761c2e934541b06250b4f14d6800ce120dfbfa
docs/models/itemprice.md:
id: f3e047ed55d5
last_write_checksum: sha1:e23355cd6dfed9bb07806b03dbd80afe8cd9f20a
pristine_git_object: 13197bfccebe058e0dde400ba4e947559b1979c1
docs/models/listglobals.md:
id: 9fec4ac692ff
last_write_checksum: sha1:ca9059d3b31cd4f7677cd3fe645fa51aad005fe4
pristine_git_object: 621172992c431f82ef0d153b0f5aca682b3d2d2f
docs/models/listrequest.md:
id: 7e80a4958244
last_write_checksum: sha1:e47f5bfc9539f6dc69e0d663c3b38dcab3860b76
pristine_git_object: eeb93a122ae3f678adb06df328b69269b03aa157
docs/models/listresponse.md:
id: 9f5b5153301d
last_write_checksum: sha1:d7f2028cd85e8b03f6028305063f96c9afcf9284
pristine_git_object: dca8216bcfba25191e8f3cc82406db7046b9fb10
docs/models/ondecrease.md:
id: 64eee91e295e
last_write_checksum: sha1:999ea60fe26a7b5c4e4156ec56df078b883168a1
pristine_git_object: 6303fefe338899d7d06e5f060715e1a40fdad6de
docs/models/onincrease.md:
id: 1c1351190e30
last_write_checksum: sha1:c42371e97c1eb94c4ce8c7b316f0a4eb33f06020
pristine_git_object: 39c4dc445027afe9bbb96efa1142f6eec8a90ebc
docs/models/options.md:
id: 5363d2a90efd
last_write_checksum: sha1:3403b06562642a4c17976a29cc13d42468a9a27e
pristine_git_object: 261c7d6183f2ff6b64aeb97f507b9475e7e14ab8
docs/models/plan.md:
id: 900c4149ef4b
last_write_checksum: sha1:a310e074b9c469c0ebd761e55bdc590258103961
pristine_git_object: 2ca3f0581334b68677614ab5a0d7019dc1cfcc58
docs/models/planbillingmethod.md:
id: ac90cee4f6c5
last_write_checksum: sha1:09b695044d92084978297b9e878857938bda8366
pristine_git_object: 94bdd58e5622f19d29267d15f91f96ab6a9679dc
docs/models/plandurationtype.md:
id: 7eb9a5f1eacb
last_write_checksum: sha1:a0b5b8d9066dd79472e2abf269e73c8b4a7f3e06
pristine_git_object: f3977f1f0ea875c5bca2f2c4e10dec923ed7d762
docs/models/planenv.md:
id: 0e584adaa5a5
last_write_checksum: sha1:62f06d32c624064b18ee6ebd2fe1fe909cecf237
pristine_git_object: da89cacf400e948cbfcc677c541918736473b531
docs/models/planprice.md:
id: 70699ad0c942
last_write_checksum: sha1:8d7fc0762a0873c87e8f565b194336d60013f034
pristine_git_object: ad2a83713f9d06a4aefcfb921cccca7b5de25bed
docs/models/planreset.md:
id: 08cb2753f6e6
last_write_checksum: sha1:6f73e545b179866a81ad746b2bf1b5f1039da727
pristine_git_object: 13eee8120fb853374a525631049ac13954ef2c80
docs/models/planresetinterval.md:
id: 1d0c7c8f25db
last_write_checksum: sha1:21bd652be1344c91d4492448f3bea12e3d234487
pristine_git_object: 0d028f3dfa9b3ffe2aa2c5ba750811e20009cf09
docs/models/planrollover.md:
id: d432fcd32015
last_write_checksum: sha1:f1bdfda2727529076d221f4ed0682dcd9899eeb6
pristine_git_object: 61e6fbec44052b3197a543f27c05c28a54b91917
docs/models/planschedule.md:
id: 1d348820e14e
last_write_checksum: sha1:128e20d94a60078b1adba243d69cf3c9363f0400
pristine_git_object: d70f6a50ce7f7da7586a40897db83fab395ea928
docs/models/plantier.md:
id: 6c3492fd8bbf
last_write_checksum: sha1:b157b295184794131b0a9764e7a82dc518602e9b
pristine_git_object: 139f62e12ba0dd833daecb48fca92e5f008dbb44
docs/models/planto.md:
id: 642e67b335e5
last_write_checksum: sha1:699b39d870e41c1926ca1f043c3273b00c8b80c0
pristine_git_object: 5c73883ba8a35a3b1c168ea4f8b6b66cdfdd0a86
docs/models/priceinterval.md:
id: 55c918da8ebf
last_write_checksum: sha1:5e27d187a022e69060afb4783b5694b03f757297
pristine_git_object: 6e906a884172e5870c3a232d6fc24d877faf5a8d
docs/models/priceiteminterval.md:
id: 5697f84ac0ff
last_write_checksum: sha1:f4e97f6695c774c0104ac06359bd924478f2d732
pristine_git_object: 38e422048337da7fb15ac0bdb007937710e61356
docs/models/proration.md:
id: ac1d089c0fd1
last_write_checksum: sha1:8e99d5a7e22633074b779591132d0894a750486f
pristine_git_object: aebfc4cbff8307ee1e606db1b538d58f3312c6ba
docs/models/purchase.md:
id: f872769b6939
last_write_checksum: sha1:af1a5ca0f4ec065db553dc337d2d02bc88ff9527
pristine_git_object: f01a0bf062f43d599f7c0c96611a11391b0f2898
docs/models/redirectmode.md:
id: 8f723d15dfc1
last_write_checksum: sha1:22bca4fdc56c2a2cf5079d305e37f3c001aff507
pristine_git_object: 402014e08c38d09a97d5e4be12e032f2f66b4f5a
docs/models/referral.md:
id: b58def2d8bbe
last_write_checksum: sha1:e3db145687c24e759f4abc69a1ab113372b56dff
pristine_git_object: 8a192f999932ad1af99c971a70a094c9534ecc33
docs/models/referralcustomer.md:
id: 7a0bc0d8989b
last_write_checksum: sha1:792e8d834522ab2166ef7f9b92226624e9b7a83a
pristine_git_object: da8b2e17f7a1a9be041072354741037d687e9a47
docs/models/requiredaction.md:
id: cd2da198d086
last_write_checksum: sha1:3f20a7d2d5c5b428e46c85cf3f0943a9a6f95b3d
pristine_git_object: 53ba86a8cf75e68783ef795598411db8310eadb4
docs/models/rewards.md:
id: 4551c882db3e
last_write_checksum: sha1:49d41902a34cb66859df2528ed2fe8597e8eae84
pristine_git_object: fcbd3790d73d6a7157b9665d8221be09af8822bf
docs/models/scenario.md:
id: e3aad8ab5efa
last_write_checksum: sha1:10d2ef18c8acb243a1519493cea42c958126ec92
pristine_git_object: c89b05ac929a4da23f05763cd36890c22cda2a02
docs/models/security.md:
id: 452e4d4eb67a
last_write_checksum: sha1:64787360e0bddbe1d2d2ede91992fa1a27c15a0e
pristine_git_object: a5c3adda6c609878c33600537edbd46c90aa1711
docs/models/status.md:
id: 959cd204aadf
last_write_checksum: sha1:6b9d5a57cb48cdf0a343ce4ae8f3acf470ab508d
pristine_git_object: ea0eb8293ad6f96373b3e3934811a73c4837b628
docs/models/subscription.md:
id: 4a200793e0f4
last_write_checksum: sha1:985d78373197de378488e772fbcf7a62bdda47ae
pristine_git_object: e7c4060bc95b77c9df7f9f5f9bce7d0f4a3364c9
docs/models/tiers.md:
id: 06571cdb201f
last_write_checksum: sha1:7cd0da02298206ef858f44a44768fde5a3166bab
pristine_git_object: 64cf2d638de4681345c98d429ddeff5b6adcd7ae
docs/models/trialsused.md:
id: d3a87e402a87
last_write_checksum: sha1:e94b335fde33fa867d83a085af54e56e003b468d
pristine_git_object: 8eba6942218e21e379f0886cbcba182ceffed7b1
docs/models/type.md:
id: 98c32f09b2c8
last_write_checksum: sha1:b504008378bf5b29ea853cf1d0f9cf4d8ff71495
pristine_git_object: 7af50db5c4bd28b5005c5648c6550b6f0af0c132
docs/models/usagemodel.md:
id: 1e12a2a8fc52
last_write_checksum: sha1:6e6803b39c0b8d88be49568c7a1bbcf8b4dba4c1
pristine_git_object: 04bed5b0edb595538e12de13f5b395a74ecdbe2e
docs/models/utils/retryconfig.md:
id: 4343ac43161c
last_write_checksum: sha1:562c0f21e308ad10c27f85f75704c15592c6929d
pristine_git_object: 69dd549ec7f5f885101d08dd502e25748183aebf
docs/sdks/billing/README.md:
id: dc915331dd9d
last_write_checksum: sha1:612ebd1ad87568e101b964755d32dd954650ad4a
pristine_git_object: f9f02df10fb1df3fa3ecb7b388a5bd2f7cfb7c49
docs/sdks/customers/README.md:
id: 9332759cffc2
last_write_checksum: sha1:3ecf4d415c7d8472c66b347946c99134d5e3697e
pristine_git_object: 0a3f98c0ffc05d7fb1f17ce978dbcbaa63906d99
docs/sdks/plans/README.md:
id: 2d8c741fff57
last_write_checksum: sha1:6e2eaf4d124140cee1d24cf09cc5bfdc16b50eb5
pristine_git_object: b7fa85fb6e50ff5a1c3b1a9ead20e56325c8daea
py.typed:
id: 258c3ed47ae4
last_write_checksum: sha1:8efc425ffe830805ffcc0f3055871bdcdc542c60
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
pylintrc:
id: 7ce8b9f946e6
last_write_checksum: sha1:ff065e1d3d6054c876fd6cf0ebd710ce14491221
pristine_git_object: 58d705283949cf00d6776293f493c8b937fad995
pyproject.toml:
id: 5d07e7d72637
last_write_checksum: sha1:6f22321d9ae998b27d4b15a939ad40b9e1f39b81
pristine_git_object: a05c06c14c54a1f0d733d2f8f3054a66e7c5f967
scripts/publish.sh:
id: fe273b08f514
last_write_checksum: sha1:adc9b741c12ad1591ab4870eabe20f0d0a86cd1a
pristine_git_object: ef28dc10c60d7d6a4bac0c6a1e9caba36b471861
src/autumn_sdk/__init__.py:
id: 6716f42f400c
last_write_checksum: sha1:da077c0bdfcef64a4a5aea91a17292f72fa2b088
pristine_git_object: 833c68cd526fe34aab2b7e7c45f974f7f4b9e120
src/autumn_sdk/_hooks/__init__.py:
id: 9cc0f4a4b4f1
last_write_checksum: sha1:e3111289afd28ad557c21d9e2f918caabfb7037d
pristine_git_object: 2ee66cdd592fe41731c24ddd407c8ca31c50aec1
src/autumn_sdk/_hooks/sdkhooks.py:
id: 44a3b91b081a
last_write_checksum: sha1:aa048f851cf2d0282481e0f74f220a1efa9fd7d1
pristine_git_object: 243e0a91b158b2a5bff9c640d2aeeb8b1ce37361
src/autumn_sdk/_hooks/types.py:
id: f938ddbbb3a7
last_write_checksum: sha1:de7842637a90364a72c1cf63807f25576c27a27f
pristine_git_object: 3e604651c1eae73d815b276806e73b2f1334bb79
src/autumn_sdk/_version.py:
id: a98babfdf4fc
last_write_checksum: sha1:e0b31129f0ea0d8fe9033dfd9a20d389b7216e28
pristine_git_object: 1491b5fb6df1f030f8187d959a3a90ad19b45295
src/autumn_sdk/basesdk.py:
id: 8c9c35fe744d
last_write_checksum: sha1:5d6abacbd251bd806538b19ab9662994bbfc6e24
pristine_git_object: b8da96bd89ddafaedb32f4ecac64c27027fcca79
src/autumn_sdk/billing.py:
id: e6cffdbf2221
last_write_checksum: sha1:46dfd5fd8c9b0423e831a196131751162bdc5cd5
pristine_git_object: 09ec0b7c21dc808420b61719fdc91de131cba206
src/autumn_sdk/customers.py:
id: 5c5a0a07a433
last_write_checksum: sha1:3c228451abfc1f8fcb6d1183b90aa4193410aa55
pristine_git_object: eae96197bd8150c542ded362580d5d639a381f7c
src/autumn_sdk/errors/__init__.py:
id: 242853123cf2
last_write_checksum: sha1:3185fbf12ed61a9845f94127cb110bce8f7f8f66
pristine_git_object: 712bfe798f42e653816668fe6a5f13e2957f12a2
src/autumn_sdk/errors/autumndefaulterror.py:
id: 4c2d6cac83ee
last_write_checksum: sha1:f45d500766d652f899f6cacbfaab5669e190f19e
pristine_git_object: 0d2bbd70da1bb3a5ac1effa98d3507f2498e42c6
src/autumn_sdk/errors/autumnerror.py:
id: 2792f28e9998
last_write_checksum: sha1:8a2c81e8babe5b90711063473f1becc4a57ffc9a
pristine_git_object: c24010e78b0fca46c210a27e6265642a2c043dab
src/autumn_sdk/errors/no_response_error.py:
id: 4151c0c74ded
last_write_checksum: sha1:7f326424a7d5ae1bcd5c89a0d6b3dbda9138942f
pristine_git_object: 1deab64bc43e1e65bf3c412d326a4032ce342366
src/autumn_sdk/errors/responsevalidationerror.py:
id: 8343146a8667
last_write_checksum: sha1:77aa85827ae606d2dcbd9a91056038d696d4eae7
pristine_git_object: 1efa993593b78b8f93587adf8a12ce2efbb11002
src/autumn_sdk/httpclient.py:
id: d09fa60cf82e
last_write_checksum: sha1:5e55338d6ee9f01ab648cad4380201a8a3da7dd7
pristine_git_object: 89560b566073785535643e694c112bedbd3db13d
src/autumn_sdk/models/__init__.py:
id: bcf3802243ff
last_write_checksum: sha1:b9457640216dbfb69d65ad6350adc964870c3959
pristine_git_object: a392d40e36275bb393258a01757cb4fb9f113274
src/autumn_sdk/models/attachop.py:
id: ebb59e06476c
last_write_checksum: sha1:014995810b7c10548f80cf690771105234934454
pristine_git_object: 3aefdfdb33ce47ca84f60d30ff8368a6c734b1e3
src/autumn_sdk/models/customer.py:
id: 8ed0174f7272
last_write_checksum: sha1:0d634e5ad085f76ed5fe6f0af4d346d325984bd3
pristine_git_object: d891471aace0d8451a48529f3607b34ad0ec07b6
src/autumn_sdk/models/customerexpand.py:
id: 9d337d480baa
last_write_checksum: sha1:27c32a524c500e8f9a03258ffab34a7ac1605ed3
pristine_git_object: 1220188fafa06dc42573c1ce7f98e84b13bde31d
src/autumn_sdk/models/getorcreateop.py:
id: 55a4c0cf5ac8
last_write_checksum: sha1:07d15f96dbfb559688619c057b700f6260a0031d
pristine_git_object: 4609818c2d80df2abe23857841135a5af9242da7
src/autumn_sdk/models/internal/__init__.py:
id: 2906fe7f2cde
last_write_checksum: sha1:5beaf7e5a713d3eead465c6edcfdeb7f8076175c
pristine_git_object: e7070a1222c2ed3fa3f6f54e6f122cae7ff9a449
src/autumn_sdk/models/internal/globals.py:
id: 4e33eb99f463
last_write_checksum: sha1:d93338d6e5fddf8e022ddc96aaa7033832c17aa7
pristine_git_object: e6ef4341edccbf10916d0f08d7f2717c65c5f8ee
src/autumn_sdk/models/listop.py:
id: 1a5423b9677e
last_write_checksum: sha1:a2c38ba2e204e58e62aef307defcc684b3b591ef
pristine_git_object: 7fa36b65893ebb4f8924e8589f9b401c22a5021b
src/autumn_sdk/models/plan.py:
id: f85c4e07540d
last_write_checksum: sha1:e0a7d4dda7f7995e64ffacee2c8d5d686e5cfeb1
pristine_git_object: 17efb1b3dc348d1525e96441eca47be09ed21251
src/autumn_sdk/models/security.py:
id: 27d01b755fbe
last_write_checksum: sha1:e5ac2e52ed9c2db46d4989c4744c230dd12bdf01
pristine_git_object: aa686dd6f85ae1e27450392fcfe02527adfe8e61
src/autumn_sdk/plans.py:
id: cf1ebabb687c
last_write_checksum: sha1:0ed87aa09c1b67b27ea580d408985205389152cd
pristine_git_object: a5c0eadaa5bed2cff71e5218299698635e34cefd
src/autumn_sdk/py.typed:
id: 9b75cee1c007
last_write_checksum: sha1:8efc425ffe830805ffcc0f3055871bdcdc542c60
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
src/autumn_sdk/sdk.py:
id: 9e733b372628
last_write_checksum: sha1:02a411e53a0b3131df887c3e9ce5edd791469a73
pristine_git_object: 44c47a2a89e707dd143020effd0a6917a2db6c7a
src/autumn_sdk/sdkconfiguration.py:
id: e65df2e44fc0
last_write_checksum: sha1:9cd4e2b7d75cbc01d6c7d1c9e676a48ea85c5c22
pristine_git_object: 1c6017c3d909b9e3f4d9a7e53d571bc4557da0d1
src/autumn_sdk/types/__init__.py:
id: 5be951fe5e8d
last_write_checksum: sha1:140ebdd01a46f92ffc710c52c958c4eba3cf68ed
pristine_git_object: fc76fe0c5505e29859b5d2bb707d48fd27661b8c
src/autumn_sdk/types/basemodel.py:
id: 8bd6f75194fb
last_write_checksum: sha1:10d84aedeb9d35edfdadf2c3020caa1d24d8b584
pristine_git_object: a9a640a1a7048736383f96c67c6290c86bf536ee
src/autumn_sdk/utils/__init__.py:
id: e8add1cf9e39
last_write_checksum: sha1:a1f6ae620fb6a3ccc30e99b427e49a0c8be463af
pristine_git_object: 15394a08a7e30033d319e44dd5734664ddb587e5
src/autumn_sdk/utils/annotations.py:
id: 781e615bef82
last_write_checksum: sha1:a4824ad65f730303e4e1e3ec1febf87b4eb46dbc
pristine_git_object: 12e0aa4f1151bb52474cc02e88397329b90703f6
src/autumn_sdk/utils/datetimes.py:
id: ae6f3bef0a07
last_write_checksum: sha1:c721e4123000e7dc61ec52b28a739439d9e17341
pristine_git_object: a6c52cd61bbe2d459046c940ce5e8c469f2f0664
src/autumn_sdk/utils/enums.py:
id: 6274197449b4
last_write_checksum: sha1:bc8c3c1285ae09ba8a094ee5c3d9c7f41fa1284d
pristine_git_object: 3324e1bc2668c54c4d5f5a1a845675319757a828
src/autumn_sdk/utils/eventstreaming.py:
id: 987e3dcdf32d
last_write_checksum: sha1:ffa870a25a7e4e2015bfd7a467ccd3aa1de97f0e
pristine_git_object: f2052fc22d9fd6c663ba3dce019fe234ca37108b
src/autumn_sdk/utils/forms.py:
id: 62fce1e7404c
last_write_checksum: sha1:0ca31459b99f761fcc6d0557a0a38daac4ad50f4
pristine_git_object: 1e550bd5c2c35d977ddc10f49d77c23cb12c158d
src/autumn_sdk/utils/headers.py:
id: 03d39bce3d2f
last_write_checksum: sha1:7c6df233ee006332b566a8afa9ce9a245941d935
pristine_git_object: 37864cbbbc40d1a47112bbfdd3ba79568fc8818a
src/autumn_sdk/utils/logger.py:
id: 437a1c090d2c
last_write_checksum: sha1:f3fdb154a3f09b8cc43d74c7e9c02f899f8086e4
pristine_git_object: b661aff65d38b77d035149699aea09b2785d2fc6
src/autumn_sdk/utils/metadata.py:
id: cfa061783b06
last_write_checksum: sha1:c6a560bd0c63ab158582f34dadb69433ea73b3d4
pristine_git_object: 173b3e5ce658675c2f504222a56b3daaaa68107d
src/autumn_sdk/utils/queryparams.py:
id: 04a0435c55f9
last_write_checksum: sha1:b94c3f314fd3da0d1d215afc2731f48748e2aa59
pristine_git_object: c04e0db82b68eca041f2cb2614d748fbac80fd41
src/autumn_sdk/utils/requestbodies.py:
id: fb822990fb2a
last_write_checksum: sha1:41e2d2d2d3ecc394c8122ca4d4b85e1c3e03f054
pristine_git_object: 1de32b6d26f46590232f398fdba6ce0072f1659c
src/autumn_sdk/utils/retries.py:
id: 7b3d494f85a1
last_write_checksum: sha1:5b97ac4f59357d70c2529975d50364c88bcad607
pristine_git_object: 88a91b10cd2076b4a2c6cff2ac6bfaa5e3c5ad13
src/autumn_sdk/utils/security.py:
id: 205e1b4aa7c9
last_write_checksum: sha1:435dd8b180cefcd733e635b9fa45512da091d9c0
pristine_git_object: 17996bd54b8624009802fbbdf30bcb4225b8dfed
src/autumn_sdk/utils/serializers.py:
id: 7e3c1b25377d
last_write_checksum: sha1:ce1d8d7f500a9ccba0aeca5057cee9c271f4dfd7
pristine_git_object: 14321eb479de81d0d9580ec8291e0ff91bf29e57
src/autumn_sdk/utils/unmarshal_json_response.py:
id: b73873b9076e
last_write_checksum: sha1:b68339d259e2184158d7c760d28eb48d367fcc61
pristine_git_object: f51b452c48809819defbc04c0b7af230b866377d
src/autumn_sdk/utils/url.py:
id: ddbea54e58a7
last_write_checksum: sha1:6479961baa90432ca25626f8e40a7bbc32e73b41
pristine_git_object: c78ccbae426ce6d385709d97ce0b1c2813ea2418
src/autumn_sdk/utils/values.py:
id: dc215a4b822d
last_write_checksum: sha1:acaa178a7c41ddd000f58cc691e4632d925b2553
pristine_git_object: dae01a44384ac3bc13ae07453a053bf6c898ebe3
examples:
getOrCreate:
speakeasy-default-get-or-create:
parameters:
header:
x-api-version: "2.1"
requestBody:
application/json: {"customer_id": "cus_123", "name": "John Doe", "email": "john@example.com"}
responses:
"200":
application/json: {"name": "John Doe", "email": "john@example.com", "fingerprint": "1234567890", "stripe_id": "cus_123", "env": "sandbox", "metadata": {}, "send_email_receipts": true, "subscriptions": [{"plan_id": "plan_123", "auto_enable": false, "add_on": false, "status": "active", "past_due": true, "canceled_at": 4013.42, "expires_at": 5474.14, "trial_ends_at": 2917.49, "started_at": 9912.5, "current_period_start": 2438.36, "current_period_end": 124.65, "quantity": 1}], "purchases": [], "balances": {"balance_1": {"feature_id": "<id>", "granted": 8304.41, "remaining": 3422.44, "usage": 6175.05, "unlimited": false, "overage_allowed": false, "max_purchase": 6363.06, "next_reset_at": 4916.32}}}
list:
speakeasy-default-list:
parameters:
header:
x-api-version: "2.1"
responses:
"200":
application/json: {"list": [{"name": "<value>", "description": "distant recompense trick", "group": "<value>", "version": 9615.63, "add_on": true, "auto_enable": false, "price": {"amount": 2384.12, "interval": "week"}, "items": [{"feature_id": "<id>", "included": 4974.83, "unlimited": false, "reset": {"interval": "day"}, "price": {"interval": "month", "billing_units": 5281.09, "billing_method": "prepaid", "max_purchase": 8873.17}}], "env": "live", "archived": false, "base_variant_id": "<id>"}]}
attach:
speakeasy-default-attach:
parameters:
header:
x-api-version: "2.1"
requestBody:
application/json: {"product_id": "<id>", "redirect_mode": "always"}
responses:
"200":
application/json: {"customer_id": "<id>", "payment_url": null}
examplesVersion: 1.0.2

View File

@@ -0,0 +1,87 @@
configVersion: 2.0.0
generation:
sdkClassName: Autumn
maintainOpenAPIOrder: true
usageSnippets:
optionalPropertyRendering: withExample
sdkInitStyle: constructor
useClassNamesForArrayFields: true
fixes:
nameResolutionDec2023: true
nameResolutionFeb2025: true
parameterOrderingFeb2024: true
requestResponseComponentNamesFeb2024: true
securityFeb2025: true
sharedErrorComponentsApr2025: true
sharedNestedComponentsJan2026: true
auth:
oAuth2ClientCredentialsEnabled: true
oAuth2PasswordEnabled: true
hoistGlobalSecurity: true
inferSSEOverload: true
sdkHooksConfigAccess: true
schemas:
allOfMergeStrategy: shallowMerge
requestBodyFieldName: body
versioningStrategy: automatic
persistentEdits: {}
tests:
generateTests: false
generateNewTests: true
skipResponseBodyAssertions: false
python:
version: 0.1.7
additionalDependencies:
dev: {}
main: {}
allowedRedefinedBuiltins:
- id
- object
- input
asyncMode: both
author: Autumn
authors:
- Autumn
baseErrorName: AutumnError
clientServerStatusCodesAsErrors: true
constFieldCasing: normal
defaultErrorName: AutumnDefaultError
description: Python SDK for the Autumn billing API
enableCustomCodeRegions: false
enumFormat: union
fixFlags:
asyncPaginationSep2025: true
responseRequiredSep2024: true
flattenGlobalSecurity: true
flattenRequests: true
flatteningOrder: parameters-first
forwardCompatibleEnumsByDefault: true
forwardCompatibleUnionsByDefault: tagged-only
imports:
option: openapi
paths:
callbacks: ""
errors: errors
operations: ""
shared: ""
webhooks: ""
inferUnionDiscriminators: true
inputModelSuffix: input
license: Apache-2.0
maxMethodParams: 999
methodArguments: infer-optional-args
moduleName: ""
multipartArrayFormat: standard
outputModelSuffix: output
packageManager: uv
packageName: autumn-sdk
preApplyUnionDiscriminators: true
projectUrls:
Documentation: https://docs.useautumn.com
Homepage: https://useautumn.com
pytestFilterWarnings: []
pytestTimeout: 0
responseFormat: flat
sseFlatResponse: false
templateVersion: v2
useAsyncHooks: false

View File

@@ -0,0 +1,6 @@
{
"python.testing.pytestArgs": ["tests", "-vv"],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"pylint.args": ["--rcfile=pylintrc"]
}

View File

@@ -0,0 +1,26 @@
# Contributing to This Repository
Thank you for your interest in contributing to this repository. Please note that this repository contains generated code. As such, we do not accept direct changes or pull requests. Instead, we encourage you to follow the guidelines below to report issues and suggest improvements.
## How to Report Issues
If you encounter any bugs or have suggestions for improvements, please open an issue on GitHub. When reporting an issue, please provide as much detail as possible to help us reproduce the problem. This includes:
- A clear and descriptive title
- Steps to reproduce the issue
- Expected and actual behavior
- Any relevant logs, screenshots, or error messages
- Information about your environment (e.g., operating system, software versions)
- For example can be collected using the `npx envinfo` command from your terminal if you have Node.js installed
## Issue Triage and Upstream Fixes
We will review and triage issues as quickly as possible. Our goal is to address bugs and incorporate improvements in the upstream source code. Fixes will be included in the next generation of the generated code.
## Contact
If you have any questions or need further assistance, please feel free to reach out by opening an issue.
Thank you for your understanding and cooperation!
The Maintainers

499
others/python-sdk/README.md Normal file
View File

@@ -0,0 +1,499 @@
# autumn-sdk
Developer-friendly & type-safe Python SDK specifically catered to leverage *autumn-sdk* API.
[![Built by Speakeasy](https://img.shields.io/badge/Built_by-SPEAKEASY-374151?style=for-the-badge&labelColor=f3f4f6)](https://www.speakeasy.com/?utm_source=autumn-sdk&utm_campaign=python)
[![License: MIT](https://img.shields.io/badge/LICENSE_//_MIT-3b5bdb?style=for-the-badge&labelColor=eff6ff)](https://opensource.org/licenses/MIT)
<br /><br />
> [!IMPORTANT]
> This SDK is not yet ready for production use. To complete setup please follow the steps outlined in your [workspace](https://app.speakeasy.com/org/autumn-gne/autumn). Delete this section before > publishing to a package manager.
<!-- Start Summary [summary] -->
## Summary
<!-- End Summary [summary] -->
<!-- Start Table of Contents [toc] -->
## Table of Contents
<!-- $toc-max-depth=2 -->
* [autumn-sdk](#autumn-sdk)
* [SDK Installation](#sdk-installation)
* [IDE Support](#ide-support)
* [SDK Example Usage](#sdk-example-usage)
* [Authentication](#authentication)
* [Available Resources and Operations](#available-resources-and-operations)
* [Retries](#retries)
* [Error Handling](#error-handling)
* [Server Selection](#server-selection)
* [Custom HTTP Client](#custom-http-client)
* [Resource Management](#resource-management)
* [Debugging](#debugging)
* [Development](#development)
* [Maturity](#maturity)
* [Contributions](#contributions)
<!-- End Table of Contents [toc] -->
<!-- Start SDK Installation [installation] -->
## SDK Installation
> [!TIP]
> To finish publishing your SDK to PyPI you must [run your first generation action](https://www.speakeasy.com/docs/github-setup#step-by-step-guide).
> [!NOTE]
> **Python version upgrade policy**
>
> Once a Python version reaches its [official end of life date](https://devguide.python.org/versions/), a 3-month grace period is provided for users to upgrade. Following this grace period, the minimum python version supported in the SDK will be updated.
The SDK can be installed with *uv*, *pip*, or *poetry* package managers.
### uv
*uv* is a fast Python package installer and resolver, designed as a drop-in replacement for pip and pip-tools. It's recommended for its speed and modern Python tooling capabilities.
```bash
uv add git+<UNSET>.git
```
### PIP
*PIP* is the default package installer for Python, enabling easy installation and management of packages from PyPI via the command line.
```bash
pip install git+<UNSET>.git
```
### Poetry
*Poetry* is a modern tool that simplifies dependency management and package publishing by using a single `pyproject.toml` file to handle project metadata and dependencies.
```bash
poetry add git+<UNSET>.git
```
### Shell and script usage with `uv`
You can use this SDK in a Python shell with [uv](https://docs.astral.sh/uv/) and the `uvx` command that comes with it like so:
```shell
uvx --from autumn-sdk python
```
It's also possible to write a standalone Python script without needing to set up a whole project like so:
```python
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "autumn-sdk",
# ]
# ///
from autumn_sdk import Autumn
sdk = Autumn(
# SDK arguments
)
# Rest of script here...
```
Once that is saved to a file, you can run it with `uv run script.py` where
`script.py` can be replaced with the actual file name.
<!-- End SDK Installation [installation] -->
<!-- Start IDE Support [idesupport] -->
## IDE Support
### PyCharm
Generally, the SDK will work well with most IDEs out of the box. However, when using PyCharm, you can enjoy much better integration with Pydantic by installing an additional plugin.
- [PyCharm Pydantic Plugin](https://docs.pydantic.dev/latest/integrations/pycharm/)
<!-- End IDE Support [idesupport] -->
<!-- Start SDK Example Usage [usage] -->
## SDK Example Usage
### Example
```python
# Synchronous Example
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
```
</br>
The same SDK client can also be used to make asynchronous requests by importing asyncio.
```python
# Asynchronous Example
import asyncio
from autumn_sdk import Autumn
async def main():
async with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = await autumn.customers.get_or_create_async(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
asyncio.run(main())
```
<!-- End SDK Example Usage [usage] -->
<!-- Start Authentication [security] -->
## Authentication
### Per-Client Security Schemes
This SDK supports the following security scheme globally:
| Name | Type | Scheme |
| ------------ | ---- | ----------- |
| `secret_key` | http | HTTP Bearer |
To authenticate with the API the `secret_key` parameter must be set when initializing the SDK client instance. For example:
```python
from autumn_sdk import Autumn
with Autumn(
secret_key="<YOUR_BEARER_TOKEN_HERE>",
x_api_version="2.1",
) as autumn:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
```
<!-- End Authentication [security] -->
<!-- Start Available Resources and Operations [operations] -->
## Available Resources and Operations
<details open>
<summary>Available methods</summary>
### [Billing](docs/sdks/billing/README.md)
* [attach](docs/sdks/billing/README.md#attach)
### [Customers](docs/sdks/customers/README.md)
* [get_or_create](docs/sdks/customers/README.md#get_or_create) - Creates a customer if they do not exist, or returns the existing customer by your external customer ID.
Use this as the primary entrypoint before billing operations so the customer record is always present and up to date.
@example
```typescript
// Create or fetch a customer by external ID
const response = await client.getOrCreate({
"id": "cus_123",
"name": "John Doe",
"email": "john@example.com"
});
```
### [Plans](docs/sdks/plans/README.md)
* [list](docs/sdks/plans/README.md#list) - List Plans
</details>
<!-- End Available Resources and Operations [operations] -->
<!-- Start Retries [retries] -->
## Retries
Some of the endpoints in this SDK support retries. If you use the SDK without any configuration, it will fall back to the default retry strategy provided by the API. However, the default retry strategy can be overridden on a per-operation basis, or across the entire SDK.
To change the default retry strategy for a single API call, simply provide a `RetryConfig` object to the call:
```python
from autumn_sdk import Autumn
from autumn_sdk.utils import BackoffStrategy, RetryConfig
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com",
RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False))
# Handle response
print(res)
```
If you'd like to override the default retry strategy for all operations that support retries, you can use the `retry_config` optional parameter when initializing the SDK:
```python
from autumn_sdk import Autumn
from autumn_sdk.utils import BackoffStrategy, RetryConfig
with Autumn(
retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False),
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
```
<!-- End Retries [retries] -->
<!-- Start Error Handling [errors] -->
## Error Handling
[`AutumnError`](./src/autumn_sdk/errors/autumnerror.py) is the base class for all HTTP error responses. It has the following properties:
| Property | Type | Description |
| ------------------ | ---------------- | ------------------------------------------------------ |
| `err.message` | `str` | Error message |
| `err.status_code` | `int` | HTTP response status code eg `404` |
| `err.headers` | `httpx.Headers` | HTTP response headers |
| `err.body` | `str` | HTTP body. Can be empty string if no body is returned. |
| `err.raw_response` | `httpx.Response` | Raw HTTP response |
### Example
```python
from autumn_sdk import Autumn, errors
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = None
try:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
except errors.AutumnError as e:
# The base class for HTTP error responses
print(e.message)
print(e.status_code)
print(e.body)
print(e.headers)
print(e.raw_response)
```
### Error Classes
**Primary error:**
* [`AutumnError`](./src/autumn_sdk/errors/autumnerror.py): The base class for HTTP error responses.
<details><summary>Less common errors (5)</summary>
<br />
**Network errors:**
* [`httpx.RequestError`](https://www.python-httpx.org/exceptions/#httpx.RequestError): Base class for request errors.
* [`httpx.ConnectError`](https://www.python-httpx.org/exceptions/#httpx.ConnectError): HTTP client was unable to make a request to a server.
* [`httpx.TimeoutException`](https://www.python-httpx.org/exceptions/#httpx.TimeoutException): HTTP request timed out.
**Inherit from [`AutumnError`](./src/autumn_sdk/errors/autumnerror.py)**:
* [`ResponseValidationError`](./src/autumn_sdk/errors/responsevalidationerror.py): Type mismatch between the response data and the expected Pydantic model. Provides access to the Pydantic validation error via the `cause` attribute.
</details>
<!-- End Error Handling [errors] -->
<!-- Start Server Selection [server] -->
## Server Selection
### Override Server URL Per-Client
The default server can be overridden globally by passing a URL to the `server_url: str` optional parameter when initializing the SDK client instance. For example:
```python
from autumn_sdk import Autumn
with Autumn(
server_url="http://localhost:8080",
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
```
<!-- End Server Selection [server] -->
<!-- Start Custom HTTP Client [http-client] -->
## Custom HTTP Client
The Python SDK makes API calls using the [httpx](https://www.python-httpx.org/) HTTP library. In order to provide a convenient way to configure timeouts, cookies, proxies, custom headers, and other low-level configuration, you can initialize the SDK client with your own HTTP client instance.
Depending on whether you are using the sync or async version of the SDK, you can pass an instance of `HttpClient` or `AsyncHttpClient` respectively, which are Protocol's ensuring that the client has the necessary methods to make API calls.
This allows you to wrap the client with your own custom logic, such as adding custom headers, logging, or error handling, or you can just pass an instance of `httpx.Client` or `httpx.AsyncClient` directly.
For example, you could specify a header for every request that this sdk makes as follows:
```python
from autumn_sdk import Autumn
import httpx
http_client = httpx.Client(headers={"x-custom-header": "someValue"})
s = Autumn(client=http_client)
```
or you could wrap the client with your own custom logic:
```python
from autumn_sdk import Autumn
from autumn_sdk.httpclient import AsyncHttpClient
import httpx
class CustomClient(AsyncHttpClient):
client: AsyncHttpClient
def __init__(self, client: AsyncHttpClient):
self.client = client
async def send(
self,
request: httpx.Request,
*,
stream: bool = False,
auth: Union[
httpx._types.AuthTypes, httpx._client.UseClientDefault, None
] = httpx.USE_CLIENT_DEFAULT,
follow_redirects: Union[
bool, httpx._client.UseClientDefault
] = httpx.USE_CLIENT_DEFAULT,
) -> httpx.Response:
request.headers["Client-Level-Header"] = "added by client"
return await self.client.send(
request, stream=stream, auth=auth, follow_redirects=follow_redirects
)
def build_request(
self,
method: str,
url: httpx._types.URLTypes,
*,
content: Optional[httpx._types.RequestContent] = None,
data: Optional[httpx._types.RequestData] = None,
files: Optional[httpx._types.RequestFiles] = None,
json: Optional[Any] = None,
params: Optional[httpx._types.QueryParamTypes] = None,
headers: Optional[httpx._types.HeaderTypes] = None,
cookies: Optional[httpx._types.CookieTypes] = None,
timeout: Union[
httpx._types.TimeoutTypes, httpx._client.UseClientDefault
] = httpx.USE_CLIENT_DEFAULT,
extensions: Optional[httpx._types.RequestExtensions] = None,
) -> httpx.Request:
return self.client.build_request(
method,
url,
content=content,
data=data,
files=files,
json=json,
params=params,
headers=headers,
cookies=cookies,
timeout=timeout,
extensions=extensions,
)
s = Autumn(async_client=CustomClient(httpx.AsyncClient()))
```
<!-- End Custom HTTP Client [http-client] -->
<!-- Start Resource Management [resource-management] -->
## Resource Management
The `Autumn` class implements the context manager protocol and registers a finalizer function to close the underlying sync and async HTTPX clients it uses under the hood. This will close HTTP connections, release memory and free up other resources held by the SDK. In short-lived Python programs and notebooks that make a few SDK method calls, resource management may not be a concern. However, in longer-lived programs, it is beneficial to create a single SDK instance via a [context manager][context-manager] and reuse it across the application.
[context-manager]: https://docs.python.org/3/reference/datamodel.html#context-managers
```python
from autumn_sdk import Autumn
def main():
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
# Rest of application here...
# Or when using async:
async def amain():
async with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
# Rest of application here...
```
<!-- End Resource Management [resource-management] -->
<!-- Start Debugging [debug] -->
## Debugging
You can setup your SDK to emit debug logs for SDK requests and responses.
You can pass your own logger class directly into your SDK.
```python
from autumn_sdk import Autumn
import logging
logging.basicConfig(level=logging.DEBUG)
s = Autumn(debug_logger=logging.getLogger("autumn_sdk"))
```
<!-- End Debugging [debug] -->
<!-- Placeholder for Future Speakeasy SDK Sections -->
# Development
## Maturity
This SDK is in beta, and there may be breaking changes between versions without a major version update. Therefore, we recommend pinning usage
to a specific package version. This way, you can install the same version each time without breaking changes unless you are intentionally
looking for the latest version.
## Contributions
While we value open-source contributions to this SDK, this library is generated programmatically. Any manual changes added to internal files will be overwritten on the next generation.
We look forward to hearing your feedback. Feel free to open a PR or an issue with a proof of concept and we'll do our best to include it in a future release.
### SDK Created by [Speakeasy](https://www.speakeasy.com/?utm_source=autumn-sdk&utm_campaign=python)

View File

@@ -0,0 +1,41 @@
<!-- Start SDK Example Usage [usage] -->
```python
# Synchronous Example
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
```
</br>
The same SDK client can also be used to make asynchronous requests by importing asyncio.
```python
# Asynchronous Example
import asyncio
from autumn_sdk import Autumn
async def main():
async with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = await autumn.customers.get_or_create_async(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
asyncio.run(main())
```
<!-- End SDK Example Usage [usage] -->

View File

@@ -0,0 +1,10 @@
# AttachFreeTrial
## Fields
| Field | Type | Required | Description |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| `length` | *float* | :heavy_check_mark: | N/A |
| `duration` | [models.Duration](../models/duration.md) | :heavy_check_mark: | N/A |
| `card_required` | *Optional[bool]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,8 @@
# AttachGlobals
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `x_api_version` | *Optional[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,15 @@
# AttachInterval
## Values
| Name | Value |
| ------------- | ------------- |
| `MINUTE` | minute |
| `HOUR` | hour |
| `DAY` | day |
| `WEEK` | week |
| `MONTH` | month |
| `QUARTER` | quarter |
| `SEMI_ANNUAL` | semi_annual |
| `YEAR` | year |

View File

@@ -0,0 +1,12 @@
# AttachInvoice
## Fields
| Field | Type | Required | Description |
| -------------------- | -------------------- | -------------------- | -------------------- |
| `status` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `stripe_id` | *str* | :heavy_check_mark: | N/A |
| `total` | *float* | :heavy_check_mark: | N/A |
| `currency` | *str* | :heavy_check_mark: | N/A |
| `hosted_invoice_url` | *Nullable[str]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,18 @@
# AttachItem
## Fields
| Field | Type | Required | Description |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | [OptionalNullable[models.AttachType]](../models/attachtype.md) | :heavy_minus_sign: | The type of the product item. |
| `feature_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The feature ID of the product item. Should be null for fixed price items. |
| `included_usage` | [OptionalNullable[models.IncludedUsage]](../models/includedusage.md) | :heavy_minus_sign: | The amount of usage included for this feature (per interval). |
| `interval` | [OptionalNullable[models.AttachInterval]](../models/attachinterval.md) | :heavy_minus_sign: | The reset or billing interval of the product item. If null, feature will have no reset date, and if there's a price, it will be billed one-off. |
| `interval_count` | *OptionalNullable[float]* | :heavy_minus_sign: | Interval count of the feature. |
| `entity_feature_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The feature ID of the entity (like seats) to track sub-balances for. |
| `usage_model` | [OptionalNullable[models.UsageModel]](../models/usagemodel.md) | :heavy_minus_sign: | Whether the feature should be prepaid upfront or billed for how much they use end of billing period. |
| `price` | *OptionalNullable[float]* | :heavy_minus_sign: | The price of the product item. Should be null if tiered pricing is set. |
| `tiers` | List[[models.Tiers](../models/tiers.md)] | :heavy_minus_sign: | Tiered pricing for the product item. Not applicable for fixed price items. |
| `billing_units` | *OptionalNullable[float]* | :heavy_minus_sign: | The billing units of the product item (eg $1 for 30 credits). |
| `reset_usage_when_enabled` | *OptionalNullable[bool]* | :heavy_minus_sign: | Whether the usage should be reset when the product is enabled. |

View File

@@ -0,0 +1,21 @@
# AttachRequest
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| `options` | List[[models.Options](../models/options.md)] | :heavy_minus_sign: | N/A |
| `version` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `free_trial` | [OptionalNullable[models.AttachFreeTrial]](../models/attachfreetrial.md) | :heavy_minus_sign: | N/A |
| `items` | List[[models.AttachItem](../models/attachitem.md)] | :heavy_minus_sign: | N/A |
| `product_id` | *str* | :heavy_check_mark: | N/A |
| `invoice` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `enable_product_immediately` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `finalize_invoice` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `redirect_mode` | [Optional[models.RedirectMode]](../models/redirectmode.md) | :heavy_minus_sign: | N/A |
| `success_url` | *Optional[str]* | :heavy_minus_sign: | N/A |
| `new_billing_subscription` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `plan_schedule` | [Optional[models.PlanSchedule]](../models/planschedule.md) | :heavy_minus_sign: | N/A |
| `billing_behavior` | [Optional[models.BillingBehavior]](../models/billingbehavior.md) | :heavy_minus_sign: | N/A |
| `adjustable_quantity` | *Optional[bool]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,13 @@
# AttachResponse
OK
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
| `customer_id` | *str* | :heavy_check_mark: | N/A |
| `invoice` | [Optional[models.AttachInvoice]](../models/attachinvoice.md) | :heavy_minus_sign: | N/A |
| `payment_url` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `required_action` | [Optional[models.RequiredAction]](../models/requiredaction.md) | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,19 @@
# AttachTo
The maximum amount of usage for this tier.
## Supported Types
### `float`
```python
value: float = /* values here */
```
### `str`
```python
value: str = /* values here */
```

View File

@@ -0,0 +1,10 @@
# AttachType
## Values
| Name | Value |
| ---------------- | ---------------- |
| `FEATURE` | feature |
| `PRICED_FEATURE` | priced_feature |
| `PRICE` | price |

View File

@@ -0,0 +1,17 @@
# Balances
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------- |
| `feature_id` | *str* | :heavy_check_mark: | N/A |
| `granted` | *float* | :heavy_check_mark: | N/A |
| `remaining` | *float* | :heavy_check_mark: | N/A |
| `usage` | *float* | :heavy_check_mark: | N/A |
| `unlimited` | *bool* | :heavy_check_mark: | N/A |
| `overage_allowed` | *bool* | :heavy_check_mark: | N/A |
| `max_purchase` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `next_reset_at` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `breakdown` | List[[models.Breakdown](../models/breakdown.md)] | :heavy_minus_sign: | N/A |
| `rollovers` | List[[models.CustomerRollover](../models/customerrollover.md)] | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# BillingBehavior
## Values
| Name | Value |
| --------------------- | --------------------- |
| `PRORATE_IMMEDIATELY` | prorate_immediately |
| `NEXT_CYCLE_ONLY` | next_cycle_only |

View File

@@ -0,0 +1,16 @@
# Breakdown
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `plan_id` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `included_grant` | *float* | :heavy_check_mark: | N/A |
| `prepaid_grant` | *float* | :heavy_check_mark: | N/A |
| `remaining` | *float* | :heavy_check_mark: | N/A |
| `usage` | *float* | :heavy_check_mark: | N/A |
| `unlimited` | *bool* | :heavy_check_mark: | N/A |
| `reset` | [Nullable[models.CustomerReset]](../models/customerreset.md) | :heavy_check_mark: | N/A |
| `price` | [Nullable[models.CustomerPrice]](../models/customerprice.md) | :heavy_check_mark: | N/A |
| `expires_at` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,10 @@
# Code
## Values
| Name | Value |
| ------------------------- | ------------------------- |
| `THREEDS_REQUIRED` | 3ds_required |
| `PAYMENT_METHOD_REQUIRED` | payment_method_required |
| `PAYMENT_FAILED` | payment_failed |

View File

@@ -0,0 +1,23 @@
# Customer
## Fields
| Field | Type | Required | Description |
| --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `name` | *Nullable[str]* | :heavy_check_mark: | The name of the customer. |
| `email` | *Nullable[str]* | :heavy_check_mark: | The email address of the customer. |
| `fingerprint` | *Nullable[str]* | :heavy_check_mark: | A unique identifier (eg. serial number) to de-duplicate customers across devices or browsers. For example: apple device ID. |
| `stripe_id` | *Nullable[str]* | :heavy_check_mark: | Stripe customer ID. |
| `env` | [models.CustomerEnv](../models/customerenv.md) | :heavy_check_mark: | The environment this customer was created in. |
| `metadata` | Dict[str, *Any*] | :heavy_check_mark: | The metadata for the customer. |
| `send_email_receipts` | *bool* | :heavy_check_mark: | Whether to send email receipts to the customer. |
| `subscriptions` | List[[models.Subscription](../models/subscription.md)] | :heavy_check_mark: | N/A |
| `purchases` | List[[models.Purchase](../models/purchase.md)] | :heavy_check_mark: | N/A |
| `balances` | Dict[str, [models.Balances](../models/balances.md)] | :heavy_check_mark: | N/A |
| `invoices` | List[[models.Invoice](../models/invoice.md)] | :heavy_minus_sign: | N/A |
| `entities` | List[[models.Entity](../models/entity.md)] | :heavy_minus_sign: | N/A |
| `trials_used` | List[[models.TrialsUsed](../models/trialsused.md)] | :heavy_minus_sign: | N/A |
| `rewards` | [OptionalNullable[models.Rewards]](../models/rewards.md) | :heavy_minus_sign: | N/A |
| `referrals` | List[[models.Referral](../models/referral.md)] | :heavy_minus_sign: | N/A |
| `payment_method` | *OptionalNullable[Any]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# CustomerBillingMethod
## Values
| Name | Value |
| ------------- | ------------- |
| `PREPAID` | prepaid |
| `USAGE_BASED` | usage_based |

View File

@@ -0,0 +1,12 @@
# CustomerDurationType
How long the discount lasts
## Values
| Name | Value |
| --------- | --------- |
| `ONE_OFF` | one_off |
| `MONTHS` | months |
| `FOREVER` | forever |

View File

@@ -0,0 +1,9 @@
# CustomerEligibility
## Fields
| Field | Type | Required | Description |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| `trial_available` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `scenario` | [models.Scenario](../models/scenario.md) | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,11 @@
# CustomerEnv
The environment this customer was created in.
## Values
| Name | Value |
| --------- | --------- |
| `SANDBOX` | sandbox |
| `LIVE` | live |

View File

@@ -0,0 +1,16 @@
# CustomerExpand
## Values
| Name | Value |
| -------------------- | -------------------- |
| `INVOICES` | invoices |
| `TRIALS_USED` | trials_used |
| `REWARDS` | rewards |
| `ENTITIES` | entities |
| `REFERRALS` | referrals |
| `PAYMENT_METHOD` | payment_method |
| `SUBSCRIPTIONS_PLAN` | subscriptions.plan |
| `PURCHASES_PLAN` | purchases.plan |
| `BALANCES_FEATURE` | balances.feature |

View File

@@ -0,0 +1,16 @@
# CustomerIntervalEnum
## Values
| Name | Value |
| ------------- | ------------- |
| `ONE_OFF` | one_off |
| `MINUTE` | minute |
| `HOUR` | hour |
| `DAY` | day |
| `WEEK` | week |
| `MONTH` | month |
| `QUARTER` | quarter |
| `SEMI_ANNUAL` | semi_annual |
| `YEAR` | year |

View File

@@ -0,0 +1,12 @@
# CustomerPrice
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| `amount` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `tiers` | List[[models.CustomerTier](../models/customertier.md)] | :heavy_minus_sign: | N/A |
| `billing_units` | *float* | :heavy_check_mark: | N/A |
| `billing_method` | [models.CustomerBillingMethod](../models/customerbillingmethod.md) | :heavy_check_mark: | N/A |
| `max_purchase` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,10 @@
# CustomerReset
## Fields
| Field | Type | Required | Description |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| `interval` | [models.Interval](../models/interval.md) | :heavy_check_mark: | N/A |
| `interval_count` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `resets_at` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,9 @@
# CustomerRollover
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `balance` | *float* | :heavy_check_mark: | N/A |
| `expires_at` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,9 @@
# CustomerTier
## Fields
| Field | Type | Required | Description |
| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- |
| `to` | [models.CustomerTo](../models/customerto.md) | :heavy_check_mark: | N/A |
| `amount` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,17 @@
# CustomerTo
## Supported Types
### `float`
```python
value: float = /* values here */
```
### `str`
```python
value: str = /* values here */
```

View File

@@ -0,0 +1,17 @@
# Discount
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `name` | *str* | :heavy_check_mark: | The name of the discount or coupon |
| `type` | [models.Type](../models/type.md) | :heavy_check_mark: | The type of reward |
| `discount_value` | *float* | :heavy_check_mark: | The discount value (percentage or fixed amount) |
| `duration_type` | [models.CustomerDurationType](../models/customerdurationtype.md) | :heavy_check_mark: | How long the discount lasts |
| `duration_value` | *OptionalNullable[float]* | :heavy_minus_sign: | Number of billing periods the discount applies for repeating durations |
| `currency` | *OptionalNullable[str]* | :heavy_minus_sign: | The currency code for fixed amount discounts |
| `start` | *OptionalNullable[float]* | :heavy_minus_sign: | Timestamp when the discount becomes active |
| `end` | *OptionalNullable[float]* | :heavy_minus_sign: | Timestamp when the discount expires |
| `subscription_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The Stripe subscription ID this discount is applied to |
| `total_discount_amount` | *OptionalNullable[float]* | :heavy_minus_sign: | Total amount saved from this discount |

View File

@@ -0,0 +1,10 @@
# Duration
## Values
| Name | Value |
| ------- | ------- |
| `DAY` | day |
| `MONTH` | month |
| `YEAR` | year |

View File

@@ -0,0 +1,11 @@
# Entity
## Fields
| Field | Type | Required | Description |
| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ |
| `name` | *Nullable[str]* | :heavy_check_mark: | The name of the entity |
| `customer_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The customer ID this entity belongs to |
| `feature_id` | *OptionalNullable[str]* | :heavy_minus_sign: | The feature ID this entity belongs to |
| `env` | [models.EntityEnv](../models/entityenv.md) | :heavy_check_mark: | The environment (sandbox/live) |

View File

@@ -0,0 +1,11 @@
# EntityEnv
The environment (sandbox/live)
## Values
| Name | Value |
| --------- | --------- |
| `SANDBOX` | sandbox |
| `LIVE` | live |

View File

@@ -0,0 +1,9 @@
# ExpiryDurationType
## Values
| Name | Value |
| --------- | --------- |
| `MONTH` | month |
| `FOREVER` | forever |

View File

@@ -0,0 +1,10 @@
# FreeTrial
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- |
| `duration_length` | *float* | :heavy_check_mark: | N/A |
| `duration_type` | [models.PlanDurationType](../models/plandurationtype.md) | :heavy_check_mark: | N/A |
| `card_required` | *bool* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,17 @@
# GetOrCreateCustomerParams
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| `customer_id` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `name` | *OptionalNullable[str]* | :heavy_minus_sign: | Customer's name |
| `email` | *OptionalNullable[str]* | :heavy_minus_sign: | Customer's email address |
| `fingerprint` | *OptionalNullable[str]* | :heavy_minus_sign: | Unique identifier (eg, serial number) to detect duplicate customers and prevent free trial abuse |
| `metadata` | Dict[str, *Any*] | :heavy_minus_sign: | Additional metadata for the customer |
| `stripe_id` | *OptionalNullable[str]* | :heavy_minus_sign: | Stripe customer ID if you already have one |
| `create_in_stripe` | *Optional[bool]* | :heavy_minus_sign: | Whether to create the customer in Stripe |
| `auto_enable_plan_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the free plan to auto-enable for the customer |
| `send_email_receipts` | *Optional[bool]* | :heavy_minus_sign: | Whether to send email receipts to this customer |
| `expand` | List[[models.CustomerExpand](../models/customerexpand.md)] | :heavy_minus_sign: | Customer expand options |

View File

@@ -0,0 +1,8 @@
# GetOrCreateGlobals
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `x_api_version` | *Optional[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,17 @@
# IncludedUsage
## Supported Types
### `float`
```python
value: float = /* values here */
```
### `str`
```python
value: str = /* values here */
```

View File

@@ -0,0 +1,8 @@
# Globals
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `x_api_version` | *Optional[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,17 @@
# Interval
## Supported Types
### `models.CustomerIntervalEnum`
```python
value: models.CustomerIntervalEnum = /* values here */
```
### `str`
```python
value: str = /* values here */
```

View File

@@ -0,0 +1,13 @@
# Invoice
## Fields
| Field | Type | Required | Description |
| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ |
| `plan_ids` | List[*str*] | :heavy_check_mark: | Array of plan IDs included in this invoice |
| `stripe_id` | *str* | :heavy_check_mark: | The Stripe invoice ID |
| `status` | *str* | :heavy_check_mark: | The status of the invoice |
| `total` | *float* | :heavy_check_mark: | The total amount of the invoice |
| `currency` | *str* | :heavy_check_mark: | The currency code for the invoice |
| `hosted_invoice_url` | *OptionalNullable[str]* | :heavy_minus_sign: | URL to the Stripe-hosted invoice page |

View File

@@ -0,0 +1,14 @@
# Item
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| `feature_id` | *str* | :heavy_check_mark: | N/A |
| `included` | *float* | :heavy_check_mark: | N/A |
| `unlimited` | *bool* | :heavy_check_mark: | N/A |
| `reset` | [Nullable[models.PlanReset]](../models/planreset.md) | :heavy_check_mark: | N/A |
| `price` | [Nullable[models.ItemPrice]](../models/itemprice.md) | :heavy_check_mark: | N/A |
| `rollover` | [Optional[models.PlanRollover]](../models/planrollover.md) | :heavy_minus_sign: | N/A |
| `proration` | [Optional[models.Proration]](../models/proration.md) | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,14 @@
# ItemPrice
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| `amount` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `tiers` | List[[models.PlanTier](../models/plantier.md)] | :heavy_minus_sign: | N/A |
| `interval` | [models.PriceItemInterval](../models/priceiteminterval.md) | :heavy_check_mark: | N/A |
| `interval_count` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `billing_units` | *float* | :heavy_check_mark: | N/A |
| `billing_method` | [models.PlanBillingMethod](../models/planbillingmethod.md) | :heavy_check_mark: | N/A |
| `max_purchase` | *Nullable[float]* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,8 @@
# ListGlobals
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `x_api_version` | *Optional[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,7 @@
# ListRequest
## Fields
| Field | Type | Required | Description |
| ----------- | ----------- | ----------- | ----------- |

View File

@@ -0,0 +1,10 @@
# ListResponse
OK
## Fields
| Field | Type | Required | Description |
| -------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------------------- |
| `list` | List[[models.Plan](../models/plan.md)] | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,12 @@
# OnDecrease
## Values
| Name | Value |
| --------------------- | --------------------- |
| `PRORATE` | prorate |
| `PRORATE_IMMEDIATELY` | prorate_immediately |
| `PRORATE_NEXT_CYCLE` | prorate_next_cycle |
| `NONE` | none |
| `NO_PRORATIONS` | no_prorations |

View File

@@ -0,0 +1,11 @@
# OnIncrease
## Values
| Name | Value |
| --------------------- | --------------------- |
| `BILL_IMMEDIATELY` | bill_immediately |
| `PRORATE_IMMEDIATELY` | prorate_immediately |
| `PRORATE_NEXT_CYCLE` | prorate_next_cycle |
| `BILL_NEXT_CYCLE` | bill_next_cycle |

View File

@@ -0,0 +1,10 @@
# Options
## Fields
| Field | Type | Required | Description |
| ----------------------- | ----------------------- | ----------------------- | ----------------------- |
| `feature_id` | *str* | :heavy_check_mark: | N/A |
| `quantity` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `reset_after_trial_end` | *Optional[bool]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,20 @@
# Plan
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| `name` | *str* | :heavy_check_mark: | N/A |
| `description` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `group` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `version` | *float* | :heavy_check_mark: | N/A |
| `add_on` | *bool* | :heavy_check_mark: | N/A |
| `auto_enable` | *bool* | :heavy_check_mark: | N/A |
| `price` | [Nullable[models.PlanPrice]](../models/planprice.md) | :heavy_check_mark: | N/A |
| `items` | List[[models.Item](../models/item.md)] | :heavy_check_mark: | N/A |
| `free_trial` | [Optional[models.FreeTrial]](../models/freetrial.md) | :heavy_minus_sign: | N/A |
| `env` | [models.PlanEnv](../models/planenv.md) | :heavy_check_mark: | N/A |
| `archived` | *bool* | :heavy_check_mark: | N/A |
| `base_variant_id` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `customer_eligibility` | [Optional[models.CustomerEligibility]](../models/customereligibility.md) | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# PlanBillingMethod
## Values
| Name | Value |
| ------------- | ------------- |
| `PREPAID` | prepaid |
| `USAGE_BASED` | usage_based |

View File

@@ -0,0 +1,10 @@
# PlanDurationType
## Values
| Name | Value |
| ------- | ------- |
| `DAY` | day |
| `MONTH` | month |
| `YEAR` | year |

View File

@@ -0,0 +1,9 @@
# PlanEnv
## Values
| Name | Value |
| --------- | --------- |
| `SANDBOX` | sandbox |
| `LIVE` | live |

View File

@@ -0,0 +1,10 @@
# PlanPrice
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- |
| `amount` | *float* | :heavy_check_mark: | N/A |
| `interval` | [models.PriceInterval](../models/priceinterval.md) | :heavy_check_mark: | N/A |
| `interval_count` | *Optional[float]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# PlanReset
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| `interval` | [models.PlanResetInterval](../models/planresetinterval.md) | :heavy_check_mark: | N/A |
| `interval_count` | *Optional[float]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,16 @@
# PlanResetInterval
## Values
| Name | Value |
| ------------- | ------------- |
| `ONE_OFF` | one_off |
| `MINUTE` | minute |
| `HOUR` | hour |
| `DAY` | day |
| `WEEK` | week |
| `MONTH` | month |
| `QUARTER` | quarter |
| `SEMI_ANNUAL` | semi_annual |
| `YEAR` | year |

View File

@@ -0,0 +1,10 @@
# PlanRollover
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `max` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `expiry_duration_type` | [models.ExpiryDurationType](../models/expirydurationtype.md) | :heavy_check_mark: | N/A |
| `expiry_duration_length` | *Optional[float]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# PlanSchedule
## Values
| Name | Value |
| -------------- | -------------- |
| `IMMEDIATE` | immediate |
| `END_OF_CYCLE` | end_of_cycle |

View File

@@ -0,0 +1,9 @@
# PlanTier
## Fields
| Field | Type | Required | Description |
| ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ |
| `to` | [models.PlanTo](../models/planto.md) | :heavy_check_mark: | N/A |
| `amount` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,17 @@
# PlanTo
## Supported Types
### `float`
```python
value: float = /* values here */
```
### `str`
```python
value: str = /* values here */
```

View File

@@ -0,0 +1,13 @@
# PriceInterval
## Values
| Name | Value |
| ------------- | ------------- |
| `ONE_OFF` | one_off |
| `WEEK` | week |
| `MONTH` | month |
| `QUARTER` | quarter |
| `SEMI_ANNUAL` | semi_annual |
| `YEAR` | year |

View File

@@ -0,0 +1,13 @@
# PriceItemInterval
## Values
| Name | Value |
| ------------- | ------------- |
| `ONE_OFF` | one_off |
| `WEEK` | week |
| `MONTH` | month |
| `QUARTER` | quarter |
| `SEMI_ANNUAL` | semi_annual |
| `YEAR` | year |

View File

@@ -0,0 +1,9 @@
# Proration
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ |
| `on_increase` | [Optional[models.OnIncrease]](../models/onincrease.md) | :heavy_minus_sign: | N/A |
| `on_decrease` | [Optional[models.OnDecrease]](../models/ondecrease.md) | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,12 @@
# Purchase
## Fields
| Field | Type | Required | Description |
| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ |
| `plan` | [Optional[models.Plan]](../models/plan.md) | :heavy_minus_sign: | N/A |
| `plan_id` | *str* | :heavy_check_mark: | N/A |
| `expires_at` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `started_at` | *float* | :heavy_check_mark: | N/A |
| `quantity` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,10 @@
# RedirectMode
## Values
| Name | Value |
| ------------- | ------------- |
| `ALWAYS` | always |
| `IF_REQUIRED` | if_required |
| `NEVER` | never |

View File

@@ -0,0 +1,10 @@
# Referral
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- |
| `program_id` | *str* | :heavy_check_mark: | N/A |
| `customer` | [models.ReferralCustomer](../models/referralcustomer.md) | :heavy_check_mark: | N/A |
| `reward_applied` | *bool* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,9 @@
# ReferralCustomer
## Fields
| Field | Type | Required | Description |
| ----------------------- | ----------------------- | ----------------------- | ----------------------- |
| `name` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |
| `email` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,9 @@
# RequiredAction
## Fields
| Field | Type | Required | Description |
| -------------------------------- | -------------------------------- | -------------------------------- | -------------------------------- |
| `code` | [models.Code](../models/code.md) | :heavy_check_mark: | N/A |
| `reason` | *str* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,8 @@
# Rewards
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- |
| `discounts` | List[[models.Discount](../models/discount.md)] | :heavy_check_mark: | Array of active discounts applied to the customer |

View File

@@ -0,0 +1,16 @@
# Scenario
## Values
| Name | Value |
| ----------- | ----------- |
| `SCHEDULED` | scheduled |
| `ACTIVE` | active |
| `NEW` | new |
| `RENEW` | renew |
| `UPGRADE` | upgrade |
| `DOWNGRADE` | downgrade |
| `CANCEL` | cancel |
| `EXPIRED` | expired |
| `PAST_DUE` | past_due |

View File

@@ -0,0 +1,8 @@
# Security
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `secret_key` | *str* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,10 @@
# Status
## Values
| Name | Value |
| ----------- | ----------- |
| `ACTIVE` | active |
| `SCHEDULED` | scheduled |
| `EXPIRED` | expired |

View File

@@ -0,0 +1,20 @@
# Subscription
## Fields
| Field | Type | Required | Description |
| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ |
| `plan` | [Optional[models.Plan]](../models/plan.md) | :heavy_minus_sign: | N/A |
| `plan_id` | *str* | :heavy_check_mark: | N/A |
| `auto_enable` | *bool* | :heavy_check_mark: | N/A |
| `add_on` | *bool* | :heavy_check_mark: | N/A |
| `status` | [models.Status](../models/status.md) | :heavy_check_mark: | N/A |
| `past_due` | *bool* | :heavy_check_mark: | N/A |
| `canceled_at` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `expires_at` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `trial_ends_at` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `started_at` | *float* | :heavy_check_mark: | N/A |
| `current_period_start` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `current_period_end` | *Nullable[float]* | :heavy_check_mark: | N/A |
| `quantity` | *float* | :heavy_check_mark: | N/A |

View File

@@ -0,0 +1,9 @@
# Tiers
## Fields
| Field | Type | Required | Description |
| -------------------------------------------- | -------------------------------------------- | -------------------------------------------- | -------------------------------------------- |
| `to` | [models.AttachTo](../models/attachto.md) | :heavy_check_mark: | The maximum amount of usage for this tier. |
| `amount` | *float* | :heavy_check_mark: | The price of the product item for this tier. |

View File

@@ -0,0 +1,10 @@
# TrialsUsed
## Fields
| Field | Type | Required | Description |
| ----------------------- | ----------------------- | ----------------------- | ----------------------- |
| `plan_id` | *str* | :heavy_check_mark: | N/A |
| `customer_id` | *str* | :heavy_check_mark: | N/A |
| `fingerprint` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A |

View File

@@ -0,0 +1,13 @@
# Type
The type of reward
## Values
| Name | Value |
| --------------------- | --------------------- |
| `PERCENTAGE_DISCOUNT` | percentage_discount |
| `FIXED_DISCOUNT` | fixed_discount |
| `FREE_PRODUCT` | free_product |
| `INVOICE_CREDITS` | invoice_credits |

View File

@@ -0,0 +1,9 @@
# UsageModel
## Values
| Name | Value |
| ------------- | ------------- |
| `PREPAID` | prepaid |
| `PAY_PER_USE` | pay_per_use |

View File

@@ -0,0 +1,24 @@
# RetryConfig
Allows customizing the default retry configuration. Only usable with methods that mention they support retries.
## Fields
| Name | Type | Description | Example |
| ------------------------- | ----------------------------------- | --------------------------------------- | --------- |
| `strategy` | `*str*` | The retry strategy to use. | `backoff` |
| `backoff` | [BackoffStrategy](#backoffstrategy) | Configuration for the backoff strategy. | |
| `retry_connection_errors` | `*bool*` | Whether to retry on connection errors. | `true` |
## BackoffStrategy
The backoff strategy allows retrying a request with an exponential backoff between each retry.
### Fields
| Name | Type | Description | Example |
| ------------------ | --------- | ----------------------------------------- | -------- |
| `initial_interval` | `*int*` | The initial interval in milliseconds. | `500` |
| `max_interval` | `*int*` | The maximum interval in milliseconds. | `60000` |
| `exponent` | `*float*` | The exponent to use for the backoff. | `1.5` |
| `max_elapsed_time` | `*int*` | The maximum elapsed time in milliseconds. | `300000` |

View File

@@ -0,0 +1,58 @@
# Billing
## Overview
### Available Operations
* [attach](#attach)
## attach
### Example Usage
<!-- UsageSnippet language="python" operationID="attach" method="post" path="/v1/attach" -->
```python
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.billing.attach(product_id="<id>", redirect_mode="always")
# Handle response
print(res)
```
### Parameters
| Parameter | Type | Required | Description |
| --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `product_id` | *str* | :heavy_check_mark: | N/A |
| `options` | List[[models.Options](../../models/options.md)] | :heavy_minus_sign: | N/A |
| `version` | *Optional[float]* | :heavy_minus_sign: | N/A |
| `free_trial` | [OptionalNullable[models.AttachFreeTrial]](../../models/attachfreetrial.md) | :heavy_minus_sign: | N/A |
| `items` | List[[models.AttachItem](../../models/attachitem.md)] | :heavy_minus_sign: | N/A |
| `invoice` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `enable_product_immediately` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `finalize_invoice` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `redirect_mode` | [Optional[models.RedirectMode]](../../models/redirectmode.md) | :heavy_minus_sign: | N/A |
| `success_url` | *Optional[str]* | :heavy_minus_sign: | N/A |
| `new_billing_subscription` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `plan_schedule` | [Optional[models.PlanSchedule]](../../models/planschedule.md) | :heavy_minus_sign: | N/A |
| `billing_behavior` | [Optional[models.BillingBehavior]](../../models/billingbehavior.md) | :heavy_minus_sign: | N/A |
| `adjustable_quantity` | *Optional[bool]* | :heavy_minus_sign: | N/A |
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
### Response
**[models.AttachResponse](../../models/attachresponse.md)**
### Errors
| Error Type | Status Code | Content Type |
| ------------------------- | ------------------------- | ------------------------- |
| errors.AutumnDefaultError | 4XX, 5XX | \*/\* |

View File

@@ -0,0 +1,84 @@
# Customers
## Overview
### Available Operations
* [get_or_create](#get_or_create) - Creates a customer if they do not exist, or returns the existing customer by your external customer ID.
Use this as the primary entrypoint before billing operations so the customer record is always present and up to date.
@example
```typescript
// Create or fetch a customer by external ID
const response = await client.getOrCreate({
"id": "cus_123",
"name": "John Doe",
"email": "john@example.com"
});
```
## get_or_create
Creates a customer if they do not exist, or returns the existing customer by your external customer ID.
Use this as the primary entrypoint before billing operations so the customer record is always present and up to date.
@example
```typescript
// Create or fetch a customer by external ID
const response = await client.getOrCreate({
"id": "cus_123",
"name": "John Doe",
"email": "john@example.com"
});
```
### Example Usage
<!-- UsageSnippet language="python" operationID="getOrCreate" method="post" path="/v1/customers.getOrCreate" -->
```python
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.customers.get_or_create(customer_id="cus_123", name="John Doe", email="john@example.com")
# Handle response
print(res)
```
### Parameters
| Parameter | Type | Required | Description |
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| `customer_id` | *Nullable[str]* | :heavy_check_mark: | N/A |
| `name` | *OptionalNullable[str]* | :heavy_minus_sign: | Customer's name |
| `email` | *OptionalNullable[str]* | :heavy_minus_sign: | Customer's email address |
| `fingerprint` | *OptionalNullable[str]* | :heavy_minus_sign: | Unique identifier (eg, serial number) to detect duplicate customers and prevent free trial abuse |
| `metadata` | Dict[str, *Any*] | :heavy_minus_sign: | Additional metadata for the customer |
| `stripe_id` | *OptionalNullable[str]* | :heavy_minus_sign: | Stripe customer ID if you already have one |
| `create_in_stripe` | *Optional[bool]* | :heavy_minus_sign: | Whether to create the customer in Stripe |
| `auto_enable_plan_id` | *Optional[str]* | :heavy_minus_sign: | The ID of the free plan to auto-enable for the customer |
| `send_email_receipts` | *Optional[bool]* | :heavy_minus_sign: | Whether to send email receipts to this customer |
| `expand` | List[[models.CustomerExpand](../../models/customerexpand.md)] | :heavy_minus_sign: | Customer expand options |
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
### Response
**[models.Customer](../../models/customer.md)**
### Errors
| Error Type | Status Code | Content Type |
| ------------------------- | ------------------------- | ------------------------- |
| errors.AutumnDefaultError | 4XX, 5XX | \*/\* |

View File

@@ -0,0 +1,47 @@
# Plans
## Overview
### Available Operations
* [list](#list) - List Plans
## list
List Plans
### Example Usage
<!-- UsageSnippet language="python" operationID="list" method="get" path="/v1/products" -->
```python
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.1",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.plans.list()
# Handle response
print(res)
```
### Parameters
| Parameter | Type | Required | Description |
| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- |
| `request` | [models.ListRequest](../../models/listrequest.md) | :heavy_check_mark: | The request object to use for the request. |
| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. |
### Response
**[models.ListResponse](../../models/listresponse.md)**
### Errors
| Error Type | Status Code | Content Type |
| ------------------------- | ------------------------- | ------------------------- |
| errors.AutumnDefaultError | 4XX, 5XX | \*/\* |

View File

@@ -0,0 +1 @@
# Marker file for PEP 561. The package enables type hints.

662
others/python-sdk/pylintrc Normal file
View File

@@ -0,0 +1,662 @@
[MAIN]
# Analyse import fallback blocks. This can be used to support both Python 2 and
# 3 compatible code, which means that the block might have code that exists
# only in one or another interpreter, leading to false positives when analysed.
analyse-fallback-blocks=no
# Clear in-memory caches upon conclusion of linting. Useful if running pylint
# in a server-like mode.
clear-cache-post-run=no
# Load and enable all available extensions. Use --list-extensions to see a list
# all available extensions.
#enable-all-extensions=
# In error mode, messages with a category besides ERROR or FATAL are
# suppressed, and no reports are done by default. Error mode is compatible with
# disabling specific errors.
#errors-only=
# Always return a 0 (non-error) status code, even if lint errors are found.
# This is primarily useful in continuous integration scripts.
#exit-zero=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code.
extension-pkg-allow-list=
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code. (This is an alternative name to extension-pkg-allow-list
# for backward compatibility.)
extension-pkg-whitelist=
# Return non-zero exit code if any of these messages/categories are detected,
# even if score is above --fail-under value. Syntax same as enable. Messages
# specified are enabled, while categories only check already-enabled messages.
fail-on=
# Specify a score threshold under which the program will exit with error.
fail-under=10
# Interpret the stdin as a python script, whose filename needs to be passed as
# the module_or_package argument.
#from-stdin=
# Files or directories to be skipped. They should be base names, not paths.
ignore=CVS
# Add files or directories matching the regular expressions patterns to the
# ignore-list. The regex matches against paths and can be in Posix or Windows
# format. Because '\\' represents the directory delimiter on Windows systems,
# it can't be used as an escape character.
ignore-paths=
# Files or directories matching the regular expression patterns are skipped.
# The regex matches against base names, not paths. The default value ignores
# Emacs file locks
ignore-patterns=^\.#
# List of module names for which member attributes should not be checked and
# will not be imported (useful for modules/projects where namespaces are
# manipulated during runtime and thus existing member attributes cannot be
# deduced by static analysis). It supports qualified module names, as well as
# Unix pattern matching.
ignored-modules=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
# number of processors available to use, and will cap the count on Windows to
# avoid hangs.
jobs=1
# Control the amount of potential inferred values when inferring a single
# object. This can help the performance when dealing with large functions or
# complex, nested conditions.
limit-inference-results=100
# List of plugins (as comma separated values of python module names) to load,
# usually to register additional checkers.
load-plugins=
# Pickle collected data for later comparisons.
persistent=yes
# Minimum Python version to use for version dependent checks. Will default to
# the version used to run pylint.
py-version=3.10
# Discover python modules and packages in the file system subtree.
recursive=no
# Add paths to the list of the source roots. Supports globbing patterns. The
# source root is an absolute path or a path relative to the current working
# directory used to determine a package namespace for modules located under the
# source root.
source-roots=src
# When enabled, pylint would attempt to guess common misconfiguration and emit
# user-friendly hints instead of false-positive error messages.
suggestion-mode=yes
# Allow loading of arbitrary C extensions. Extensions are imported into the
# active Python interpreter and may run arbitrary code.
unsafe-load-any-extension=no
# In verbose mode, extra non-checker-related info will be displayed.
#verbose=
[BASIC]
# Naming style matching correct argument names.
argument-naming-style=snake_case
# Regular expression matching correct argument names. Overrides argument-
# naming-style. If left empty, argument names will be checked with the set
# naming style.
#argument-rgx=
# Naming style matching correct attribute names.
#attr-naming-style=snake_case
# Regular expression matching correct attribute names. Overrides attr-naming-
# style. If left empty, attribute names will be checked with the set naming
# style.
attr-rgx=[^\W\d][^\W]*|__.*__$
# Bad variable names which should always be refused, separated by a comma.
bad-names=
# Bad variable names regexes, separated by a comma. If names match any regex,
# they will always be refused
bad-names-rgxs=
# Naming style matching correct class attribute names.
class-attribute-naming-style=any
# Regular expression matching correct class attribute names. Overrides class-
# attribute-naming-style. If left empty, class attribute names will be checked
# with the set naming style.
#class-attribute-rgx=
# Naming style matching correct class constant names.
class-const-naming-style=UPPER_CASE
# Regular expression matching correct class constant names. Overrides class-
# const-naming-style. If left empty, class constant names will be checked with
# the set naming style.
#class-const-rgx=
# Naming style matching correct class names.
class-naming-style=PascalCase
# Regular expression matching correct class names. Overrides class-naming-
# style. If left empty, class names will be checked with the set naming style.
#class-rgx=
# Naming style matching correct constant names.
const-naming-style=UPPER_CASE
# Regular expression matching correct constant names. Overrides const-naming-
# style. If left empty, constant names will be checked with the set naming
# style.
#const-rgx=
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
# Naming style matching correct function names.
function-naming-style=snake_case
# Regular expression matching correct function names. Overrides function-
# naming-style. If left empty, function names will be checked with the set
# naming style.
#function-rgx=
# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
Run,
_,
e,
to
# Good variable names regexes, separated by a comma. If names match any regex,
# they will always be accepted
good-names-rgxs=
# Include a hint for the correct naming format with invalid-name.
include-naming-hint=no
# Naming style matching correct inline iteration names.
inlinevar-naming-style=any
# Regular expression matching correct inline iteration names. Overrides
# inlinevar-naming-style. If left empty, inline iteration names will be checked
# with the set naming style.
#inlinevar-rgx=
# Naming style matching correct method names.
method-naming-style=snake_case
# Regular expression matching correct method names. Overrides method-naming-
# style. If left empty, method names will be checked with the set naming style.
#method-rgx=
# Naming style matching correct module names.
module-naming-style=snake_case
# Regular expression matching correct module names. Overrides module-naming-
# style. If left empty, module names will be checked with the set naming style.
#module-rgx=
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=^_
# List of decorators that produce properties, such as abc.abstractproperty. Add
# to this list to register other decorators that produce valid properties.
# These decorators are taken in consideration only for invalid-name.
property-classes=abc.abstractproperty
# Regular expression matching correct type alias names. If left empty, type
# alias names will be checked with the set naming style.
typealias-rgx=.*
# Regular expression matching correct type variable names. If left empty, type
# variable names will be checked with the set naming style.
#typevar-rgx=
# Naming style matching correct variable names.
variable-naming-style=snake_case
# Regular expression matching correct variable names. Overrides variable-
# naming-style. If left empty, variable names will be checked with the set
# naming style.
#variable-rgx=
[CLASSES]
# Warn about protected attribute access inside special methods
check-protected-access-in-special-methods=no
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,
__new__,
setUp,
asyncSetUp,
__post_init__
# List of member names, which should be excluded from the protected access
# warning.
exclude-protected=_asdict,_fields,_replace,_source,_make,os._exit
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[DESIGN]
# List of regular expressions of class ancestor names to ignore when counting
# public methods (see R0903)
exclude-too-few-public-methods=
# List of qualified class names to ignore when counting class parents (see
# R0901)
ignored-parents=
# Maximum number of arguments for function / method.
max-args=5
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Maximum number of boolean expressions in an if statement (see R0916).
max-bool-expr=5
# Maximum number of branch for function / method body.
max-branches=12
# Maximum number of locals for function / method body.
max-locals=15
# Maximum number of parents for a class (see R0901).
max-parents=7
# Maximum number of public methods for a class (see R0904).
max-public-methods=25
# Maximum number of return / yield for function / method body.
max-returns=6
# Maximum number of statements in function / method body.
max-statements=50
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
[EXCEPTIONS]
# Exceptions that will emit a warning when caught.
overgeneral-exceptions=builtins.BaseException,builtins.Exception
[FORMAT]
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
expected-line-ending-format=
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Number of spaces of indent required inside a hanging or continued line.
indent-after-paren=4
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Maximum number of characters on a single line.
max-line-length=100
# Maximum number of lines in a module.
max-module-lines=1000
# Allow the body of a class to be on the same line as the declaration if body
# contains single statement.
single-line-class-stmt=no
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
[IMPORTS]
# List of modules that can be imported at any level, not just the top level
# one.
allow-any-import-level=
# Allow explicit reexports by alias from a package __init__.
allow-reexport-from-package=no
# Allow wildcard imports from modules that define __all__.
allow-wildcard-with-all=no
# Deprecated modules which should not be used, separated by a comma.
deprecated-modules=
# Output a graph (.gv or any supported image format) of external dependencies
# to the given file (report RP0402 must not be disabled).
ext-import-graph=
# Output a graph (.gv or any supported image format) of all (i.e. internal and
# external) dependencies to the given file (report RP0402 must not be
# disabled).
import-graph=
# Output a graph (.gv or any supported image format) of internal dependencies
# to the given file (report RP0402 must not be disabled).
int-import-graph=
# Force import order to recognize a module as part of the standard
# compatibility libraries.
known-standard-library=
# Force import order to recognize a module as part of a third party library.
known-third-party=enchant
# Couples of modules and preferred modules, separated by a comma.
preferred-modules=
[LOGGING]
# The type of string formatting that logging methods do. `old` means using %
# formatting, `new` is for `{}` formatting.
logging-format-style=old
# Logging modules to check that the string format arguments are in logging
# function parameter format.
logging-modules=logging
[MESSAGES CONTROL]
# Only show warnings with the listed confidence levels. Leave empty to show
# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE,
# UNDEFINED.
confidence=HIGH,
CONTROL_FLOW,
INFERENCE,
INFERENCE_FAILURE,
UNDEFINED
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once). You can also use "--disable=all" to
# disable everything first and then re-enable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use "--disable=all --enable=classes
# --disable=W".
disable=raw-checker-failed,
bad-inline-option,
locally-disabled,
file-ignored,
suppressed-message,
useless-suppression,
deprecated-pragma,
use-implicit-booleaness-not-comparison-to-string,
use-implicit-booleaness-not-comparison-to-zero,
use-symbolic-message-instead,
trailing-whitespace,
line-too-long,
missing-class-docstring,
missing-module-docstring,
missing-function-docstring,
too-many-instance-attributes,
wrong-import-order,
too-many-arguments,
broad-exception-raised,
too-few-public-methods,
too-many-branches,
duplicate-code,
trailing-newlines,
too-many-public-methods,
too-many-locals,
too-many-lines,
using-constant-test,
too-many-statements,
cyclic-import,
too-many-nested-blocks,
too-many-boolean-expressions,
no-else-raise,
bare-except,
broad-exception-caught,
fixme,
relative-beyond-top-level,
consider-using-with,
wildcard-import,
unused-wildcard-import,
too-many-return-statements
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time (only on the command line, not in the configuration file where
# it should appear only once). See also the "--disable" option for examples.
enable=
[METHOD_ARGS]
# List of qualified names (i.e., library.method) which require a timeout
# parameter e.g. 'requests.api.get,requests.api.post'
timeout-methods=requests.api.delete,requests.api.get,requests.api.head,requests.api.options,requests.api.patch,requests.api.post,requests.api.put,requests.api.request
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,
XXX,
TODO
# Regular expression of note tags to take in consideration.
notes-rgx=
[REFACTORING]
# Maximum number of nested blocks for function / method body
max-nested-blocks=5
# Complete name of functions that never returns. When checking for
# inconsistent-return-statements if a never returning function is called then
# it will be considered as an explicit return statement and no message will be
# printed.
never-returning-functions=sys.exit,argparse.parse_error
[REPORTS]
# Python expression which should return a score less than or equal to 10. You
# have access to the variables 'fatal', 'error', 'warning', 'refactor',
# 'convention', and 'info' which contain the number of messages in each
# category, as well as 'statement' which is the total number of statements
# analyzed. This score is used by the global evaluation report (RP0004).
evaluation=max(0, 0 if fatal else 10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10))
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details.
msg-template=
# Set the output format. Available formats are: text, parseable, colorized,
# json2 (improved json format), json (old json format) and msvs (visual
# studio). You can also give a reporter class, e.g.
# mypackage.mymodule.MyReporterClass.
#output-format=
# Tells whether to display a full report or only the messages.
reports=no
# Activate the evaluation score.
score=yes
[SIMILARITIES]
# Comments are removed from the similarity computation
ignore-comments=yes
# Docstrings are removed from the similarity computation
ignore-docstrings=yes
# Imports are removed from the similarity computation
ignore-imports=yes
# Signatures are removed from the similarity computation
ignore-signatures=yes
# Minimum lines number of a similarity.
min-similarity-lines=4
[SPELLING]
# Limits count of emitted suggestions for spelling mistakes.
max-spelling-suggestions=4
# Spelling dictionary name. No available dictionaries : You need to install
# both the python package and the system dependency for enchant to work.
spelling-dict=
# List of comma separated words that should be considered directives if they
# appear at the beginning of a comment and should not be checked.
spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy:
# List of comma separated words that should not be checked.
spelling-ignore-words=
# A path to a file that contains the private dictionary; one word per line.
spelling-private-dict-file=
# Tells whether to store unknown words to the private dictionary (see the
# --spelling-private-dict-file option) instead of raising a message.
spelling-store-unknown-words=no
[STRING]
# This flag controls whether inconsistent-quotes generates a warning when the
# character used as a quote delimiter is used inconsistently within a module.
check-quote-consistency=no
# This flag controls whether the implicit-str-concat should generate a warning
# on implicit string concatenation in sequences defined over several lines.
check-str-concat-over-line-jumps=no
[TYPECHECK]
# List of decorators that produce context managers, such as
# contextlib.contextmanager. Add to this list to register other decorators that
# produce valid context managers.
contextmanager-decorators=contextlib.contextmanager
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E1101 when accessed. Python regular
# expressions are accepted.
generated-members=
# Tells whether to warn about missing members when the owner of the attribute
# is inferred to be None.
ignore-none=yes
# This flag controls whether pylint should warn about no-member and similar
# checks whenever an opaque object is returned when inferring. The inference
# can return multiple potential results while evaluating a Python object, but
# some branches might not be evaluated, which results in partial inference. In
# that case, it might be useful to still emit no-member and other checks for
# the rest of the inferred objects.
ignore-on-opaque-inference=yes
# List of symbolic message names to ignore for Mixin members.
ignored-checks-for-mixins=no-member,
not-async-context-manager,
not-context-manager,
attribute-defined-outside-init
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=optparse.Values,thread._local,_thread._local,argparse.Namespace
# Show a hint with possible names when a member name was not found. The aspect
# of finding the hint is based on edit distance.
missing-member-hint=yes
# The minimum edit distance a name should have in order to be considered a
# similar match for a missing member name.
missing-member-hint-distance=1
# The total number of similar names that should be taken in consideration when
# showing a hint for a missing member.
missing-member-max-choices=1
# Regex pattern to define which classes are considered mixins.
mixin-class-rgx=.*[Mm]ixin
# List of decorators that change the signature of a decorated function.
signature-mutators=
[VARIABLES]
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid defining new builtins when possible.
additional-builtins=
# Tells whether unused global variables should be treated as a violation.
allow-global-unused-variables=yes
# List of names allowed to shadow builtins
allowed-redefined-builtins=id,object,input
# List of strings which can identify a callback function by name. A callback
# name must start or end with one of those strings.
callbacks=cb_,
_cb
# A regular expression matching the name of dummy variables (i.e. expected to
# not be used).
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
# Argument names that match this expression will be ignored.
ignored-argument-names=_.*|^ignored_|^unused_
# Tells whether we should check for unused import in __init__ files.
init-import=no
# List of qualified module names which can have objects that can redefine
# builtins.
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io

View File

@@ -0,0 +1,53 @@
[project]
name = "autumn-sdk"
version = "0.1.7"
description = "Python SDK for the Autumn billing API"
authors = [{ name = "Autumn" },]
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"httpcore >=1.0.9",
"httpx >=0.28.1",
"pydantic >=2.11.2",
]
license = { text = "Apache-2.0" }
[dependency-groups]
dev = [
"mypy ==1.15.0",
"pylint ==3.2.3",
"pyright ==1.1.398",
]
[tool.setuptools.packages.find]
where = ["src"]
[tool.setuptools.package-data]
"*" = ["py.typed"]
[build-system]
requires = ["setuptools>=80", "wheel"]
build-backend = "setuptools.build_meta"
[tool.pytest.ini_options]
asyncio_default_fixture_loop_scope = "function"
pythonpath = ["src"]
[tool.mypy]
disable_error_code = "misc"
explicit_package_bases = true
mypy_path = "src"
[[tool.mypy.overrides]]
module = "typing_inspect"
ignore_missing_imports = true
[[tool.mypy.overrides]]
module = "jsonpath"
ignore_missing_imports = true
[tool.pyright]
venvPath = "."
venv = ".venv"

Some files were not shown because too many files have changed in this diff Show More