amigo_sdk 0.96.0__tar.gz → 0.97.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.
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/.github/workflows/test.yml +36 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/PKG-INFO +1 -1
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/pyproject.toml +1 -0
- amigo_sdk-0.97.0/scripts/gen_models.py +122 -0
- amigo_sdk-0.97.0/specs/openapi-baseline.json +1 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/__init__.py +1 -1
- amigo_sdk-0.97.0/src/amigo_sdk/generated/model.py +15959 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/resources/conversation.py +2 -2
- amigo_sdk-0.97.0/uv.lock +1318 -0
- amigo_sdk-0.96.0/scripts/gen_models.py +0 -71
- amigo_sdk-0.96.0/specs/openapi-baseline.json +0 -1
- amigo_sdk-0.96.0/src/amigo_sdk/generated/model.py +0 -11597
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/.github/workflows/auto-release.yml +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/.github/workflows/release.yml +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/.gitignore +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/CONTRIBUTING.md +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/LICENSE +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/README.md +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/scripts/__init__.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/scripts/aliases.json +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/scripts/check.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/_retry_utils.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/auth.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/config.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/errors.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/http_client.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/models.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/resources/organization.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/resources/service.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/resources/user.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/src/amigo_sdk/sdk_client.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/__init__.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/conftest.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/integration/test_conversation_integration.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/integration/test_organization_integration.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/integration/test_user_integration.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/resources/__init__.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/resources/helpers.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/resources/test_conversation.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/resources/test_organization.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/resources/test_service.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/resources/test_user.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/test_auth.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/test_config.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/test_errors.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/test_http_client.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/test_retry_utils.py +0 -0
- {amigo_sdk-0.96.0 → amigo_sdk-0.97.0}/tests/test_sdk_client.py +0 -0
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
name: Test
|
|
2
2
|
|
|
3
|
+
permissions:
|
|
4
|
+
contents: read
|
|
5
|
+
|
|
3
6
|
on:
|
|
4
7
|
push:
|
|
5
8
|
branches: [main]
|
|
@@ -48,3 +51,36 @@ jobs:
|
|
|
48
51
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
49
52
|
files: ./coverage.xml
|
|
50
53
|
fail_ci_if_error: true
|
|
54
|
+
|
|
55
|
+
integration-test:
|
|
56
|
+
runs-on: blacksmith-4vcpu-ubuntu-2404
|
|
57
|
+
needs: test # Only run if unit tests pass
|
|
58
|
+
# Skip for PRs from forks (they don't have access to secrets)
|
|
59
|
+
# This runs on: pushes to main, PRs from same repo
|
|
60
|
+
if: >
|
|
61
|
+
github.event_name == 'push' ||
|
|
62
|
+
github.event.pull_request.head.repo.full_name == github.repository
|
|
63
|
+
|
|
64
|
+
steps:
|
|
65
|
+
- name: Checkout code
|
|
66
|
+
uses: actions/checkout@v4
|
|
67
|
+
|
|
68
|
+
- name: Setup Python
|
|
69
|
+
uses: actions/setup-python@v5
|
|
70
|
+
with:
|
|
71
|
+
python-version: "3.13"
|
|
72
|
+
cache: "pip"
|
|
73
|
+
|
|
74
|
+
- name: Install dependencies
|
|
75
|
+
run: |
|
|
76
|
+
python -m pip install --upgrade pip
|
|
77
|
+
pip install -e ".[dev]"
|
|
78
|
+
|
|
79
|
+
- name: Run integration tests
|
|
80
|
+
env:
|
|
81
|
+
AMIGO_API_KEY: ${{ secrets.AMIGO_API_KEY }}
|
|
82
|
+
AMIGO_API_KEY_ID: ${{ secrets.AMIGO_API_KEY_ID }}
|
|
83
|
+
AMIGO_ORGANIZATION_ID: ${{ secrets.AMIGO_ORGANIZATION_ID }}
|
|
84
|
+
AMIGO_USER_ID: ${{ secrets.AMIGO_USER_ID }}
|
|
85
|
+
AMIGO_BASE_URL: ${{ secrets.AMIGO_BASE_URL }}
|
|
86
|
+
run: pytest -m integration -v
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
from datamodel_code_generator import (
|
|
6
|
+
DataModelType,
|
|
7
|
+
InputFileType,
|
|
8
|
+
OpenAPIScope,
|
|
9
|
+
generate,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
# Prefixes to strip from schema names (API-specific internal paths)
|
|
13
|
+
STRIP_PREFIXES = [
|
|
14
|
+
"src__app__endpoints__",
|
|
15
|
+
"src__app__amigo__",
|
|
16
|
+
"amigo_lib__",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def strip_prefixes_from_schema(spec: dict) -> dict:
|
|
21
|
+
"""
|
|
22
|
+
Pre-process the OpenAPI spec to strip internal prefixes from schema names.
|
|
23
|
+
This allows the code generator's built-in name sanitization to work correctly.
|
|
24
|
+
"""
|
|
25
|
+
schemas = spec.get("components", {}).get("schemas", {})
|
|
26
|
+
if not schemas:
|
|
27
|
+
return spec
|
|
28
|
+
|
|
29
|
+
# Build a mapping of old names to new names
|
|
30
|
+
rename_map: dict[str, str] = {}
|
|
31
|
+
for name in schemas:
|
|
32
|
+
new_name = name
|
|
33
|
+
for prefix in STRIP_PREFIXES:
|
|
34
|
+
if new_name.startswith(prefix):
|
|
35
|
+
new_name = new_name[len(prefix) :]
|
|
36
|
+
break
|
|
37
|
+
if new_name != name:
|
|
38
|
+
rename_map[name] = new_name
|
|
39
|
+
|
|
40
|
+
if not rename_map:
|
|
41
|
+
return spec
|
|
42
|
+
|
|
43
|
+
# Rename schemas
|
|
44
|
+
new_schemas = {}
|
|
45
|
+
for name, schema in schemas.items():
|
|
46
|
+
new_name = rename_map.get(name, name)
|
|
47
|
+
new_schemas[new_name] = schema
|
|
48
|
+
spec["components"]["schemas"] = new_schemas
|
|
49
|
+
|
|
50
|
+
# Update all $ref pointers throughout the spec
|
|
51
|
+
def update_refs(obj):
|
|
52
|
+
if isinstance(obj, dict):
|
|
53
|
+
if "$ref" in obj:
|
|
54
|
+
ref = obj["$ref"]
|
|
55
|
+
for old, new in rename_map.items():
|
|
56
|
+
old_ref = f"#/components/schemas/{old}"
|
|
57
|
+
new_ref = f"#/components/schemas/{new}"
|
|
58
|
+
if ref == old_ref:
|
|
59
|
+
obj["$ref"] = new_ref
|
|
60
|
+
break
|
|
61
|
+
for value in obj.values():
|
|
62
|
+
update_refs(value)
|
|
63
|
+
elif isinstance(obj, list):
|
|
64
|
+
for item in obj:
|
|
65
|
+
update_refs(item)
|
|
66
|
+
|
|
67
|
+
update_refs(spec)
|
|
68
|
+
return spec
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def main() -> None:
|
|
72
|
+
schema_url = "https://api.amigo.ai/v1/openapi.json"
|
|
73
|
+
root = Path(__file__).parent.parent
|
|
74
|
+
out_dir = root / "src" / "amigo_sdk" / "generated"
|
|
75
|
+
output_file = out_dir / "model.py"
|
|
76
|
+
aliases_path = root / "scripts" / "aliases.json"
|
|
77
|
+
|
|
78
|
+
# Create the generated directory if it doesn't exist
|
|
79
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
80
|
+
|
|
81
|
+
# Remove existing model.py if it exists
|
|
82
|
+
if output_file.exists():
|
|
83
|
+
output_file.unlink()
|
|
84
|
+
|
|
85
|
+
# Fetch the OpenAPI schema from the remote URL
|
|
86
|
+
print(f"Fetching OpenAPI schema from {schema_url}...")
|
|
87
|
+
response = httpx.get(schema_url)
|
|
88
|
+
response.raise_for_status()
|
|
89
|
+
spec = response.json()
|
|
90
|
+
|
|
91
|
+
# Pre-process: strip internal prefixes from schema names
|
|
92
|
+
spec = strip_prefixes_from_schema(spec)
|
|
93
|
+
|
|
94
|
+
# Load aliases as a mapping (Python API expects a dict)
|
|
95
|
+
aliases: dict[str, str] = {}
|
|
96
|
+
if aliases_path.exists():
|
|
97
|
+
aliases = json.loads(aliases_path.read_text())
|
|
98
|
+
|
|
99
|
+
generate(
|
|
100
|
+
json.dumps(spec),
|
|
101
|
+
input_file_type=InputFileType.OpenAPI,
|
|
102
|
+
output=output_file,
|
|
103
|
+
output_model_type=DataModelType.PydanticV2BaseModel,
|
|
104
|
+
openapi_scopes=[
|
|
105
|
+
OpenAPIScope.Schemas,
|
|
106
|
+
OpenAPIScope.Parameters,
|
|
107
|
+
OpenAPIScope.Paths,
|
|
108
|
+
OpenAPIScope.Tags,
|
|
109
|
+
],
|
|
110
|
+
snake_case_field=True,
|
|
111
|
+
field_constraints=True,
|
|
112
|
+
use_operation_id_as_name=True,
|
|
113
|
+
reuse_model=True,
|
|
114
|
+
aliases=aliases,
|
|
115
|
+
collapse_root_models=True,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
print(f"✅ Models regenerated → {output_file}")
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
main()
|