Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Default owners for the classic Python SDK
* @johnxing-amigo @caly-yang-amigo
* @johnxing-amigo @caly-amigo
38 changes: 27 additions & 11 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ on:
description: "Version increment type (patch|minor|major)"
required: true
type: string
default: "patch"
dry_run:
description: "Dry run (skip upload)"
required: false
Expand Down Expand Up @@ -57,11 +56,13 @@ jobs:
uses: ./.github/workflows/test.yml
with:
skip_codecov: true
secrets: inherit

release:
runs-on: blacksmith-4vcpu-ubuntu-2404
needs: test
env:
VERSION_TYPE: ${{ inputs.version_type }}
DRY_RUN: ${{ inputs.dry_run }}

steps:
- name: Create GitHub App token (release-bot)
Expand All @@ -85,16 +86,17 @@ jobs:
- name: Fetch OpenAPI spec
if: ${{ inputs.regenerate_models }}
id: fetch_spec
env:
SPEC_URL: ${{ inputs.spec_url }}
run: |
SPEC_URL="${{ inputs.spec_url }}"
if [ -z "$SPEC_URL" ]; then
SPEC_URL="https://api.amigo.ai/v1/openapi.json"
fi
mkdir -p specs
curl -fSL -o specs/openapi-new.json "$SPEC_URL"
cp specs/openapi-new.json specs/openapi-baseline.json

# Generator always fetches remote; no local spec path needed
# Generation uses the committed snapshot, or the explicit refresh above.

- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
Expand Down Expand Up @@ -127,11 +129,22 @@ jobs:
python -m scripts.gen_models
echo "✅ Models generated successfully"

- name: Validate regenerated package
if: ${{ inputs.regenerate_models }}
run: |
ruff check .
mypy src/amigo_sdk/ --ignore-missing-imports
pytest

- name: Increment version
id: new_version
run: |
echo "🔄 Incrementing ${{ inputs.version_type }} version..."
hatch version ${{ inputs.version_type }}
case "$VERSION_TYPE" in
patch|minor|major) ;;
*) echo "::error::Unsupported version type"; exit 1 ;;
esac
echo "🔄 Incrementing $VERSION_TYPE version..."
hatch version "$VERSION_TYPE"
NEW_VERSION=$(hatch version)
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
echo "✅ Version updated: ${{ steps.current_version.outputs.version }} → $NEW_VERSION"
Expand Down Expand Up @@ -208,6 +221,7 @@ jobs:
REPO: ${{ github.repository }}
NEW_VERSION: ${{ steps.new_version.outputs.version }}
PREV_VERSION: ${{ steps.current_version.outputs.version }}
RELEASE_COMMITS: ${{ steps.release_commits.outputs.markdown }}
run: |
PREV_TAG="v${PREV_VERSION}"
NEW_TAG="v${NEW_VERSION}"
Expand All @@ -219,7 +233,7 @@ jobs:
{
echo "## What's Changed in ${NEW_TAG}"
echo ""
echo "${{ steps.release_commits.outputs.markdown }}"
printf '%s\n' "$RELEASE_COMMITS"
echo ""
echo "---"
echo ""
Expand Down Expand Up @@ -285,20 +299,22 @@ jobs:
retention-days: 30

- name: Release Summary
env:
RELEASE_COMMITS: ${{ steps.release_commits.outputs.markdown }}
run: |
echo "## 🎉 Release Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Version**: ${{ steps.new_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Previous**: ${{ steps.current_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Type**: ${{ inputs.version_type }} release" >> $GITHUB_STEP_SUMMARY
echo "- **Type**: $VERSION_TYPE release" >> $GITHUB_STEP_SUMMARY
echo "- **Target**: PyPI" >> $GITHUB_STEP_SUMMARY
echo "- **Dry Run**: ${{ inputs.dry_run }}" >> $GITHUB_STEP_SUMMARY
echo "- **Dry Run**: $DRY_RUN" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🧾 New Commits" >> $GITHUB_STEP_SUMMARY
printf '%s\n' "${{ steps.release_commits.outputs.markdown }}" >> $GITHUB_STEP_SUMMARY
printf '%s\n' "$RELEASE_COMMITS" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

if [ "${{ inputs.dry_run }}" = "false" ]; then
if [ "$DRY_RUN" = "false" ]; then
echo "### 📦 Package Links" >> $GITHUB_STEP_SUMMARY
echo "- [PyPI Package](https://pypi.org/project/amigo_sdk/${{ steps.new_version.outputs.version }}/)" >> $GITHUB_STEP_SUMMARY
echo "- [GitHub Release](https://github.com/${{ github.repository }}/releases/tag/v${{ steps.new_version.outputs.version }})" >> $GITHUB_STEP_SUMMARY
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ coverage.xml

# CI/Temp OpenAPI spec (fetched during workflows)
specs/openapi-new.json

# Compiled Python artifacts
*.py[cod]

# Generated MkDocs site
/site/
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Amigo AI Python SDK (`amigo_sdk`) -- a Python client library for the Amigo AI AP
- **Format:** `ruff format src/ tests/` (check only: `ruff format --check src/ tests/`)
- **Generate models from OpenAPI:** `python scripts/gen_models.py`
- **Build:** `hatch build` (outputs sdist and wheel to `dist/`)
- **Type check:** `mypy src/amigo_sdk/` (mypy in dev deps, CI step runs with continue-on-error)
- **Type check:** `mypy src/amigo_sdk/` (mypy in dev deps; required CI check)

## Architecture

Expand Down Expand Up @@ -90,6 +90,6 @@ Tests for resources use shared helpers in `tests/resources/helpers.py`:
GitHub Actions workflow (`.github/workflows/test.yml`) runs on Python 3.11, 3.12, 3.13:
1. `ruff check .`
2. `ruff format --check .`
3. `mypy src/amigo_sdk/` (continue-on-error)
3. `mypy src/amigo_sdk/ --ignore-missing-imports` (required)
4. `pytest --cov=src`
5. Integration tests run separately (non-blocking, require secrets)
18 changes: 9 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ pip install -e ".[dev]"

### Validation

- `check` runs formatting, linting, and tests
- `check --fix` auto-fixes what it can, then reruns checks
- `check --fast` runs the fast path without tests
- `python scripts/check.py` runs formatting, linting, and tests
- `python scripts/check.py --fix` auto-fixes what it can, then reruns checks
- `python scripts/check.py --fast` runs the fast path without tests

### Codegen And Docs

- `gen-models` regenerates models from the committed `specs/openapi-baseline.json` snapshot
- `sync-openapi` refreshes `specs/openapi-baseline.json` from the live classic API before regeneration
- `mkdocs build --strict` builds the docs site
- `python scripts/gen_models.py` regenerates models from the committed `specs/openapi-baseline.json` snapshot
- `python scripts/sync_openapi.py` refreshes `specs/openapi-baseline.json` from the live classic API before regeneration
- Install docs dependencies with `pip install -e ".[docs]"`, then `mkdocs build --strict` builds the docs site

## Testing

Expand All @@ -34,7 +34,7 @@ python -m pytest -m integration
python -m pytest --cov=src
```

Integration tests require valid Amigo API credentials in the environment.
Integration tests require valid Amigo API credentials in the environment. Unit tests use mocked requests. Run `mypy src/amigo_sdk/ --ignore-missing-imports` as well; it is a required CI check. Development scripts run from this checkout and are not commands installed by the public wheel.

## Project Structure

Expand All @@ -57,9 +57,9 @@ examples/

Before opening a PR:

1. Run `check --fix`
1. Run `python scripts/check.py --fix`
2. Run `python -m pytest`
3. Run `sync-openapi` and `gen-models` if the API contract changed
3. Run `python scripts/sync_openapi.py` and `python scripts/gen_models.py` if the API contract changed
4. Update README or docs if customer-visible behavior changed

## Release Notes
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ The Platform API is where new workspace-scoped capabilities land first, but the
| If you need | Start here |
| --- | --- |
| Existing org-scoped integrations on `api.amigo.ai` from Python | `amigo_sdk` |
| New workspace-scoped integrations on `api.platform.amigo.ai` | [Platform API docs](https://docs.amigo.ai/api-reference) today. A first-party Python migration path will follow as platform-native coverage expands |
| New workspace-scoped integrations on `api.platform.amigo.ai` | [Platform API docs](https://docs.amigo.ai/api-reference) today. Use direct HTTP for Platform integrations from Python; this package remains Classic-only |

## Documentation

Expand All @@ -66,6 +66,10 @@ Python `3.11+` is required.
pip install amigo_sdk
```

Before making requests, obtain Classic organization credentials and a user authorized to read the target resources. Keep API keys in server-side environment variables or a secret manager. The examples below read conversation data; they require access to an existing organization.

For the 2.0.0 generated-model changes, review the [current SDK upgrade guidance](https://docs.amigo.ai/api-reference/change-logs/sdk-ecosystem#september-2026-compatibility-releases) and recheck the package registry when choosing a version.

## Quick Start

### Sync Client
Expand Down Expand Up @@ -142,11 +146,11 @@ from amigo_sdk.models import (
)
```

Public builds are generated from the committed [`specs/openapi-baseline.json`](./specs/openapi-baseline.json) snapshot in this repo so generated models stay deterministic across machines and CI runs. Refresh that snapshot before regenerating models:
Public builds are generated from the committed [`specs/openapi-baseline.json`](./specs/openapi-baseline.json) snapshot in this repo so generated models stay deterministic across machines and CI runs. From a source checkout with development dependencies installed, refresh that snapshot before regenerating models:

```bash
sync-openapi
gen-models
python scripts/sync_openapi.py
python scripts/gen_models.py
```

## Error Handling
Expand Down
15 changes: 5 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dynamic = ["version"]
dependencies = [
"httpx>=0.25,<1.0",
"pydantic>=2.7,<3.0",
"pydantic-settings>=2.0,<3.0",
"pydantic-settings>=2.14.2,<3.0",
"email-validator>=2.0,<3.0",
]

Expand All @@ -34,21 +34,16 @@ Repository = "https://github.com/amigo-ai/amigo-python-sdk"
Issues = "https://github.com/amigo-ai/amigo-python-sdk/issues"
Changelog = "https://github.com/amigo-ai/amigo-python-sdk/blob/main/CHANGELOG.md"

[project.scripts]
gen-models = "scripts.gen_models:main"
check = "scripts.check:main"
sync-openapi = "scripts.sync_openapi:main"

[project.optional-dependencies]
dev = [
"pytest>=7.0,<9.0",
"pytest-asyncio>=0.21,<1.0",
"pytest>=9.0.3,<10.0",
"pytest-asyncio>=1.0,<2.0",
"pytest-cov>=4.0,<6.0",
"pytest-httpx>=0.30,<1.0",
"python-dotenv>=1.0,<2.0",
"python-dotenv>=1.2.2,<2.0",
"ruff>=0.1,<1.0",
"mypy>=1.0",
"datamodel-code-generator[http]>=0.21,<1.0",
"datamodel-code-generator[http]>=0.64,<1.0",
]
docs = [
"mkdocs>=1.6",
Expand Down
Binary file removed scripts/__init__.pyc
Binary file not shown.
1 change: 1 addition & 0 deletions scripts/gen_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ def main() -> None:
use_operation_id_as_name=True,
reuse_model=True,
set_default_enum_member=True,
disable_timestamp=True,
aliases=aliases,
collapse_root_models=False,
)
Expand Down
1 change: 0 additions & 1 deletion src/amigo_sdk/generated/model.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# generated by datamodel-codegen:
# filename: <stdin>
# timestamp: 2026-09-08T01:00:51+00:00

from __future__ import annotations

Expand Down
Loading
Loading