amigo_sdk 0.9.0__tar.gz → 0.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of amigo_sdk might be problematic. Click here for more details.

Files changed (47) hide show
  1. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/.github/workflows/auto-release.yml +12 -10
  2. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/.github/workflows/release.yml +12 -7
  3. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/.gitignore +4 -1
  4. amigo_sdk-0.11.0/CONTRIBUTING.md +137 -0
  5. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/PKG-INFO +83 -3
  6. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/README.md +82 -2
  7. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/specs/openapi-baseline.json +1 -1
  8. amigo_sdk-0.11.0/src/amigo_sdk/__init__.py +4 -0
  9. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/generated/model.py +27 -21
  10. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/http_client.py +6 -5
  11. amigo_sdk-0.11.0/src/amigo_sdk/models.py +1 -0
  12. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/resources/conversation.py +5 -4
  13. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/resources/test_conversation.py +7 -4
  14. amigo_sdk-0.9.0/CONTRIBUTING.md +0 -77
  15. amigo_sdk-0.9.0/openapi-new.json +0 -1
  16. amigo_sdk-0.9.0/src/amigo_sdk/__init__.py +0 -8
  17. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/.github/workflows/test.yml +0 -0
  18. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/LICENSE +0 -0
  19. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/pyproject.toml +0 -0
  20. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/scripts/__init__.py +0 -0
  21. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/scripts/aliases.json +0 -0
  22. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/scripts/check.py +0 -0
  23. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/scripts/gen_models.py +0 -0
  24. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/_retry_utils.py +0 -0
  25. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/auth.py +0 -0
  26. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/config.py +0 -0
  27. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/errors.py +0 -0
  28. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/resources/organization.py +0 -0
  29. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/resources/service.py +0 -0
  30. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/resources/user.py +0 -0
  31. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/src/amigo_sdk/sdk_client.py +0 -0
  32. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/__init__.py +0 -0
  33. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/conftest.py +0 -0
  34. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/integration/test_conversation_integration.py +0 -0
  35. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/integration/test_organization_integration.py +0 -0
  36. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/integration/test_user_integration.py +0 -0
  37. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/resources/__init__.py +0 -0
  38. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/resources/helpers.py +0 -0
  39. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/resources/test_organization.py +0 -0
  40. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/resources/test_service.py +0 -0
  41. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/resources/test_user.py +0 -0
  42. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/test_auth.py +0 -0
  43. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/test_config.py +0 -0
  44. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/test_errors.py +0 -0
  45. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/test_http_client.py +0 -0
  46. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/test_retry_utils.py +0 -0
  47. {amigo_sdk-0.9.0 → amigo_sdk-0.11.0}/tests/test_sdk_client.py +0 -0
@@ -30,7 +30,9 @@ jobs:
30
30
  echo "spec_url=$SPEC_URL" >> $GITHUB_OUTPUT
31
31
 
32
32
  - name: Fetch current production spec
33
- run: curl -fSL -o openapi-new.json "${{ steps.spec.outputs.spec_url }}"
33
+ run: |
34
+ mkdir -p specs
35
+ curl -fSL -o specs/openapi-new.json "${{ steps.spec.outputs.spec_url }}"
34
36
 
35
37
  - name: Check baseline presence
36
38
  id: baseline
@@ -46,7 +48,7 @@ jobs:
46
48
  run: |
47
49
  mkdir -p specs
48
50
  if [ ! -f specs/openapi-baseline.json ]; then
49
- cp openapi-new.json specs/openapi-baseline.json
51
+ cp specs/openapi-new.json specs/openapi-baseline.json
50
52
  fi
51
53
 
52
54
  - name: Diagnostics (spec and baseline)
@@ -71,7 +73,7 @@ jobs:
71
73
  with_entries(.value |= sort_deep)
72
74
  else . end;
73
75
  (del(.info) | del(.servers)) | sort_deep
74
- ' openapi-new.json > new.norm.json
76
+ ' specs/openapi-new.json > new.norm.json
75
77
  if [ -f baseline.norm.json ]; then
76
78
  echo "BASELINE_NORM_SHA=$(sha256sum baseline.norm.json | awk '{print $1}')"
77
79
  else
@@ -99,10 +101,10 @@ jobs:
99
101
  BASELINE_PATHS_COUNT=0
100
102
  BASELINE_SCHEMAS_COUNT=0
101
103
  fi
102
- NEW_PATHS_SHA=$(jq -cS '(.paths // {})' openapi-new.json | sha256sum | awk '{print $1}')
103
- NEW_SCHEMAS_SHA=$(jq -cS '(.components.schemas // {})' openapi-new.json | sha256sum | awk '{print $1}')
104
- NEW_PATHS_COUNT=$(jq -r '(.paths // {}) | keys | length' openapi-new.json)
105
- NEW_SCHEMAS_COUNT=$(jq -r '(.components.schemas // {}) | keys | length' openapi-new.json)
104
+ NEW_PATHS_SHA=$(jq -cS '(.paths // {})' specs/openapi-new.json | sha256sum | awk '{print $1}')
105
+ NEW_SCHEMAS_SHA=$(jq -cS '(.components.schemas // {})' specs/openapi-new.json | sha256sum | awk '{print $1}')
106
+ NEW_PATHS_COUNT=$(jq -r '(.paths // {}) | keys | length' specs/openapi-new.json)
107
+ NEW_SCHEMAS_COUNT=$(jq -r '(.components.schemas // {}) | keys | length' specs/openapi-new.json)
106
108
  echo "BASELINE paths: count=$BASELINE_PATHS_COUNT sha=$BASELINE_PATHS_SHA"
107
109
  echo "NEW paths: count=$NEW_PATHS_COUNT sha=$NEW_PATHS_SHA"
108
110
  echo "BASELINE schemas: count=$BASELINE_SCHEMAS_COUNT sha=$BASELINE_SCHEMAS_SHA"
@@ -114,7 +116,7 @@ jobs:
114
116
  else
115
117
  : > baseline.paths.txt
116
118
  fi
117
- jq -r '(.paths // {}) | keys | sort[]' openapi-new.json > new.paths.txt
119
+ jq -r '(.paths // {}) | keys | sort[]' specs/openapi-new.json > new.paths.txt
118
120
  echo "Removed paths (in baseline, not in new):"; comm -23 baseline.paths.txt new.paths.txt || true
119
121
  echo "Added paths (in new, not in baseline):"; comm -13 baseline.paths.txt new.paths.txt || true
120
122
 
@@ -124,7 +126,7 @@ jobs:
124
126
  else
125
127
  : > baseline.schemas.txt
126
128
  fi
127
- jq -r '(.components.schemas // {}) | keys | sort[]' openapi-new.json > new.schemas.txt
129
+ jq -r '(.components.schemas // {}) | keys | sort[]' specs/openapi-new.json > new.schemas.txt
128
130
  echo "Removed schemas (in baseline, not in new):"; comm -23 baseline.schemas.txt new.schemas.txt || true
129
131
  echo "Added schemas (in new, not in baseline):"; comm -13 baseline.schemas.txt new.schemas.txt || true
130
132
 
@@ -152,7 +154,7 @@ jobs:
152
154
  with_entries(.value |= sort_deep)
153
155
  else . end;
154
156
  (del(.info) | del(.servers)) | sort_deep
155
- ' openapi-new.json > new.norm.json
157
+ ' specs/openapi-new.json > new.norm.json
156
158
  if diff -q baseline.norm.json new.norm.json >/dev/null 2>&1; then
157
159
  echo "changed=false" >> $GITHUB_OUTPUT
158
160
  else
@@ -51,13 +51,20 @@ jobs:
51
51
  needs: test
52
52
 
53
53
  steps:
54
+ - name: Create GitHub App token (release-bot)
55
+ id: app-token
56
+ uses: actions/create-github-app-token@v2
57
+ with:
58
+ app-id: ${{ secrets.RELEASE_BOT_APP_ID }}
59
+ private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }}
60
+
54
61
  - name: Checkout code
55
62
  uses: actions/checkout@v4
56
63
  with:
57
64
  # Fetch full history for version tagging
58
65
  fetch-depth: 0
59
66
  # Use a token that can push tags and create releases
60
- token: ${{ secrets.GITHUB_TOKEN }}
67
+ token: ${{ steps.app-token.outputs.token }}
61
68
 
62
69
  - name: Ensure jq
63
70
  run: sudo apt-get update && sudo apt-get install -y jq
@@ -69,13 +76,11 @@ jobs:
69
76
  if [ -z "$SPEC_URL" ]; then
70
77
  SPEC_URL="https://api.amigo.ai/v1/openapi.json"
71
78
  fi
72
- curl -fSL -o openapi-new.json "$SPEC_URL"
73
79
  mkdir -p specs
74
- cp openapi-new.json specs/openapi-baseline.json
80
+ curl -fSL -o specs/openapi-new.json "$SPEC_URL"
81
+ cp specs/openapi-new.json specs/openapi-baseline.json
75
82
 
76
- # Optional: if your generator can take a spec path
77
- - name: Set spec path for generator
78
- run: echo "OPENAPI_SPEC_PATH=$GITHUB_WORKSPACE/openapi-new.json" >> $GITHUB_ENV
83
+ # Generator always fetches remote; no local spec path needed
79
84
 
80
85
  - name: Setup Python
81
86
  uses: actions/setup-python@v5
@@ -152,7 +157,7 @@ jobs:
152
157
  if: ${{ !inputs.dry_run }}
153
158
  uses: actions/create-release@v1
154
159
  env:
155
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
160
+ GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
156
161
  with:
157
162
  tag_name: "v${{ steps.new_version.outputs.version }}"
158
163
  release_name: "Release v${{ steps.new_version.outputs.version }}"
@@ -12,4 +12,7 @@ dist/
12
12
  # Coverage files
13
13
  htmlcov/
14
14
  coverage.xml
15
- .coverage
15
+ .coverage
16
+
17
+ # CI/Temp OpenAPI spec (fetched during workflows)
18
+ specs/openapi-new.json
@@ -0,0 +1,137 @@
1
+ # Contributing Guide
2
+
3
+ ## Quick Setup
4
+
5
+ ```bash
6
+ # Create and activate virtual environment
7
+ python -m venv .venv
8
+ source .venv/bin/activate
9
+
10
+ # Install the project in development mode
11
+ pip install -e ".[dev]"
12
+ ```
13
+
14
+ ## Development Commands
15
+
16
+ ```bash
17
+ check # Run all checks (format, lint, tests)
18
+ check --fix # Auto-fix issues and run all checks
19
+ check --fast # Format + lint only (skip tests)
20
+
21
+ gen-models # Generate models from API spec
22
+ ```
23
+
24
+ ## Workflow
25
+
26
+ 1. **Before committing:** Run `check --fix` to auto-fix issues
27
+ 2. **During development:** Use `check --fast` for quick validation
28
+ 3. **Update models:** Run `gen-models` when API changes
29
+
30
+ ## Release Process
31
+
32
+ ### GitHub Actions Release
33
+
34
+ 1. Go to the **Actions** tab in GitHub
35
+ 2. Select the **Release** workflow
36
+ 3. Click **Run workflow** and choose:
37
+ - **Version type**: `patch` (default), `minor`, or `major`
38
+ - **Dry run**: Test the release process without publishing
39
+
40
+ The workflow will automatically:
41
+
42
+ - ✅ Run all tests, linting, and formatting checks (reuses existing test workflow)
43
+ - 🔄 Generate fresh models from the API spec
44
+ - 📈 Increment the version using Hatch
45
+ - 📦 Build the package
46
+ - 🚀 Upload to PyPI
47
+ - 🏷️ Create a Git tag and GitHub release
48
+ - 📋 Provide detailed summary with links
49
+
50
+ ### Required Repository Secrets
51
+
52
+ Configure these secrets in your GitHub repository settings:
53
+
54
+ - `PYPI_API_TOKEN`: Token for https://pypi.org/ (production releases)
55
+ - `CODECOV_TOKEN`: Token for Codecov uploads (used by CI test workflow)
56
+ - `RELEASE_BOT_APP_ID`: GitHub App ID used to create tags/releases
57
+ - `RELEASE_BOT_PRIVATE_KEY`: GitHub App private key (PEM) for the release bot
58
+
59
+ ### Getting API Tokens
60
+
61
+ 1. **PyPI**: Go to https://pypi.org/manage/account/token/
62
+ 2. Create a token with upload permissions
63
+ 3. Add the token to your repository secrets
64
+
65
+ ## Auto-Release (OpenAPI changes)
66
+
67
+ When the backend OpenAPI spec changes, the SDK can auto-release a new version.
68
+
69
+ - Trigger: a `repository_dispatch` event with type `openapi-updated`
70
+ - Detect job: fetches the provided `spec_url` (or defaults to `https://api.amigo.ai/v1/openapi.json`), normalizes and compares against `specs/openapi-baseline.json`
71
+ - If changed: invokes the release workflow with `version_type=minor` and passes `spec_url` (supports `dry_run`)
72
+ - Release workflow: regenerates models, bumps version, builds, publishes to PyPI, pushes tag, and creates a GitHub release
73
+
74
+ Manual trigger example (repository_dispatch):
75
+
76
+ ```bash
77
+ curl -X POST \
78
+ -H "Accept: application/vnd.github+json" \
79
+ -H "Authorization: Bearer $GH_TOKEN" \
80
+ https://api.github.com/repos/<OWNER>/<REPO>/dispatches \
81
+ -d '{
82
+ "event_type": "openapi-updated",
83
+ "client_payload": {
84
+ "spec_url": "https://api.amigo.ai/v1/openapi.json",
85
+ "dry_run": true
86
+ }
87
+ }'
88
+ ```
89
+
90
+ Notes:
91
+
92
+ - The baseline file `specs/openapi-baseline.json` is created on first run and updated as part of the release workflow.
93
+ - Ensure the secrets listed above are configured so the workflow can push tags, create releases, and publish to PyPI.
94
+
95
+ ### Manual trigger using GitHub CLI (gh)
96
+
97
+ Requires `gh` authenticated with a token that can dispatch events on the SDK repos.
98
+
99
+ ```bash
100
+ # Values that mirror the workflow
101
+ OWNER="amigo-ai"
102
+ BACKEND_REPO="$OWNER/backend"
103
+ COMMIT_SHA="$(git rev-parse HEAD 2>/dev/null || echo manual-test)"
104
+ RUN_ID="$(date +%s)" # stand-in for GitHub Actions run_id
105
+
106
+ for repo in amigo-typescript-sdk amigo-python-sdk; do
107
+ echo "Notifying $repo..."
108
+ gh api "repos/$OWNER/$repo/dispatches" \
109
+ --method POST \
110
+ --header 'Accept: application/vnd.github+json' \
111
+ --input - <<EOF || echo "⚠️ Failed to notify $repo"
112
+ {
113
+ "event_type": "openapi-updated",
114
+ "client_payload": {
115
+ "spec_url": "https://api.amigo.ai/v1/openapi.json",
116
+ "commit_sha": "$COMMIT_SHA",
117
+ "backend_repo": "$BACKEND_REPO",
118
+ "backend_run_id": "$RUN_ID"
119
+ }
120
+ }
121
+ EOF
122
+ done
123
+ ```
124
+
125
+ ## IDE Setup (VS Code)
126
+
127
+ Install extensions:
128
+
129
+ - [Ruff](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff)
130
+ - [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python)
131
+
132
+ ## Troubleshooting
133
+
134
+ - **Command not found:** Activate virtual environment with `source .venv/bin/activate`
135
+ - **Linting failures:** Run `check --fix` to auto-fix issues
136
+ - **Model import errors:** Run `gen-models` to regenerate models
137
+ - **Release failures:** Check API tokens are configured in repository secrets and try a dry run first
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amigo_sdk
3
- Version: 0.9.0
3
+ Version: 0.11.0
4
4
  Summary: Amigo AI Python SDK
5
5
  Author: Amigo AI
6
6
  License-File: LICENSE
@@ -50,7 +50,7 @@ This SDK auto-generates its types from the latest [Amigo OpenAPI schema](https:/
50
50
 
51
51
  ```python
52
52
  from amigo_sdk import AmigoClient
53
- from amigo_sdk.generated.model import GetConversationsParametersQuery
53
+ from amigo_sdk.models import GetConversationsParametersQuery
54
54
 
55
55
  # Initialize and use the client synchronously
56
56
  with AmigoClient(
@@ -65,9 +65,38 @@ with AmigoClient(
65
65
  print("Conversations:", conversations)
66
66
  ```
67
67
 
68
+ ## Quick Start (async)
69
+
70
+ ```python
71
+ import asyncio
72
+
73
+ from amigo_sdk import AsyncAmigoClient
74
+ from amigo_sdk.models import GetConversationsParametersQuery
75
+
76
+
77
+ async def main():
78
+ async with AsyncAmigoClient(
79
+ api_key="your-api-key",
80
+ api_key_id="your-api-key-id",
81
+ user_id="user-id",
82
+ organization_id="your-organization-id",
83
+ ) as client:
84
+ conversations = await client.conversation.get_conversations(
85
+ GetConversationsParametersQuery(limit=10, sort_by=["-created_at"])
86
+ )
87
+ print("Conversations:", conversations)
88
+
89
+
90
+ asyncio.run(main())
91
+ ```
92
+
68
93
  ## Examples
69
94
 
70
- For more SDK usage examples see checkout the [examples/](examples/README.md) folder.
95
+ For more SDK usage examples see the [examples overview](examples/README.md). Direct links:
96
+
97
+ - **Conversation (sync)**: [examples/conversation/conversation.py](examples/conversation/conversation.py)
98
+ - **Conversation (async)**: [examples/conversation/conversation_async.py](examples/conversation/conversation_async.py)
99
+ - **User management (sync)**: [examples/user/user-management.py](examples/user/user-management.py)
71
100
 
72
101
  ## Configuration
73
102
 
@@ -133,6 +162,43 @@ The SDK provides access to the following resources:
133
162
  - **Conversation**: Manage conversations
134
163
  - **User**: Manage users
135
164
 
165
+ ## Generated types
166
+
167
+ The SDK ships with Pydantic models generated from the latest OpenAPI schema.
168
+
169
+ - **Importing types**: Import directly from `amigo_sdk.models`
170
+
171
+ ```python
172
+ from amigo_sdk.models import (
173
+ GetConversationsParametersQuery,
174
+ ConversationCreateConversationRequest,
175
+ GetUsersParametersQuery,
176
+ )
177
+ ```
178
+
179
+ - **Using types when calling SDK functions**: Pass request/query models to resource methods.
180
+
181
+ ```python
182
+ from amigo_sdk import AmigoClient
183
+ from amigo_sdk.models import GetConversationsParametersQuery
184
+
185
+ with AmigoClient() as client:
186
+ conversations = client.conversation.get_conversations(
187
+ GetConversationsParametersQuery(limit=20, sort_by=["-created_at"])
188
+ )
189
+ ```
190
+
191
+ - **Parsing returned objects**: Responses are Pydantic models. Access fields directly or convert to dict/JSON.
192
+
193
+ ```python
194
+ # Access fields
195
+ first = conversations.conversations[0]
196
+ print(first.id, first.created_at)
197
+
198
+ # Convert to plain dict for logging/serialization
199
+ print(first.model_dump(mode="json"))
200
+ ```
201
+
136
202
  ## Error Handling
137
203
 
138
204
  The SDK provides typed error handling:
@@ -162,6 +228,20 @@ except Exception as error:
162
228
  print("Unexpected error:", error)
163
229
  ```
164
230
 
231
+ ## Retries
232
+
233
+ The HTTP client includes sensible, configurable retries:
234
+
235
+ - **Defaults**:
236
+
237
+ - max attempts: 3
238
+ - backoff base: 0.25s (exponential with full jitter)
239
+ - max delay per attempt: 30s
240
+ - retry on status: {408, 429, 500, 502, 503, 504}
241
+ - retry on methods: {"GET"}
242
+ - special-case: POST is retried on 429 when `Retry-After` is present
243
+ - 401 triggers a one-time token refresh and immediate retry
244
+
165
245
  ## Development
166
246
 
167
247
  For detailed development setup, testing, and contribution guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -28,7 +28,7 @@ This SDK auto-generates its types from the latest [Amigo OpenAPI schema](https:/
28
28
 
29
29
  ```python
30
30
  from amigo_sdk import AmigoClient
31
- from amigo_sdk.generated.model import GetConversationsParametersQuery
31
+ from amigo_sdk.models import GetConversationsParametersQuery
32
32
 
33
33
  # Initialize and use the client synchronously
34
34
  with AmigoClient(
@@ -43,9 +43,38 @@ with AmigoClient(
43
43
  print("Conversations:", conversations)
44
44
  ```
45
45
 
46
+ ## Quick Start (async)
47
+
48
+ ```python
49
+ import asyncio
50
+
51
+ from amigo_sdk import AsyncAmigoClient
52
+ from amigo_sdk.models import GetConversationsParametersQuery
53
+
54
+
55
+ async def main():
56
+ async with AsyncAmigoClient(
57
+ api_key="your-api-key",
58
+ api_key_id="your-api-key-id",
59
+ user_id="user-id",
60
+ organization_id="your-organization-id",
61
+ ) as client:
62
+ conversations = await client.conversation.get_conversations(
63
+ GetConversationsParametersQuery(limit=10, sort_by=["-created_at"])
64
+ )
65
+ print("Conversations:", conversations)
66
+
67
+
68
+ asyncio.run(main())
69
+ ```
70
+
46
71
  ## Examples
47
72
 
48
- For more SDK usage examples see checkout the [examples/](examples/README.md) folder.
73
+ For more SDK usage examples see the [examples overview](examples/README.md). Direct links:
74
+
75
+ - **Conversation (sync)**: [examples/conversation/conversation.py](examples/conversation/conversation.py)
76
+ - **Conversation (async)**: [examples/conversation/conversation_async.py](examples/conversation/conversation_async.py)
77
+ - **User management (sync)**: [examples/user/user-management.py](examples/user/user-management.py)
49
78
 
50
79
  ## Configuration
51
80
 
@@ -111,6 +140,43 @@ The SDK provides access to the following resources:
111
140
  - **Conversation**: Manage conversations
112
141
  - **User**: Manage users
113
142
 
143
+ ## Generated types
144
+
145
+ The SDK ships with Pydantic models generated from the latest OpenAPI schema.
146
+
147
+ - **Importing types**: Import directly from `amigo_sdk.models`
148
+
149
+ ```python
150
+ from amigo_sdk.models import (
151
+ GetConversationsParametersQuery,
152
+ ConversationCreateConversationRequest,
153
+ GetUsersParametersQuery,
154
+ )
155
+ ```
156
+
157
+ - **Using types when calling SDK functions**: Pass request/query models to resource methods.
158
+
159
+ ```python
160
+ from amigo_sdk import AmigoClient
161
+ from amigo_sdk.models import GetConversationsParametersQuery
162
+
163
+ with AmigoClient() as client:
164
+ conversations = client.conversation.get_conversations(
165
+ GetConversationsParametersQuery(limit=20, sort_by=["-created_at"])
166
+ )
167
+ ```
168
+
169
+ - **Parsing returned objects**: Responses are Pydantic models. Access fields directly or convert to dict/JSON.
170
+
171
+ ```python
172
+ # Access fields
173
+ first = conversations.conversations[0]
174
+ print(first.id, first.created_at)
175
+
176
+ # Convert to plain dict for logging/serialization
177
+ print(first.model_dump(mode="json"))
178
+ ```
179
+
114
180
  ## Error Handling
115
181
 
116
182
  The SDK provides typed error handling:
@@ -140,6 +206,20 @@ except Exception as error:
140
206
  print("Unexpected error:", error)
141
207
  ```
142
208
 
209
+ ## Retries
210
+
211
+ The HTTP client includes sensible, configurable retries:
212
+
213
+ - **Defaults**:
214
+
215
+ - max attempts: 3
216
+ - backoff base: 0.25s (exponential with full jitter)
217
+ - max delay per attempt: 30s
218
+ - retry on status: {408, 429, 500, 502, 503, 504}
219
+ - retry on methods: {"GET"}
220
+ - special-case: POST is retried on 429 when `Retry-After` is present
221
+ - 401 triggers a one-time token refresh and immediate retry
222
+
143
223
  ## Development
144
224
 
145
225
  For detailed development setup, testing, and contribution guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md).