amigo_sdk 0.95.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.
Files changed (47) hide show
  1. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/.github/workflows/test.yml +36 -0
  2. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/PKG-INFO +1 -1
  3. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/pyproject.toml +1 -0
  4. amigo_sdk-0.97.0/scripts/gen_models.py +122 -0
  5. amigo_sdk-0.97.0/specs/openapi-baseline.json +1 -0
  6. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/__init__.py +1 -1
  7. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/generated/model.py +1891 -2241
  8. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/resources/conversation.py +2 -2
  9. amigo_sdk-0.97.0/uv.lock +1318 -0
  10. amigo_sdk-0.95.0/scripts/gen_models.py +0 -71
  11. amigo_sdk-0.95.0/specs/openapi-baseline.json +0 -1
  12. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/.github/workflows/auto-release.yml +0 -0
  13. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/.github/workflows/release.yml +0 -0
  14. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/.gitignore +0 -0
  15. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/CONTRIBUTING.md +0 -0
  16. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/LICENSE +0 -0
  17. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/README.md +0 -0
  18. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/scripts/__init__.py +0 -0
  19. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/scripts/aliases.json +0 -0
  20. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/scripts/check.py +0 -0
  21. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/_retry_utils.py +0 -0
  22. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/auth.py +0 -0
  23. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/config.py +0 -0
  24. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/errors.py +0 -0
  25. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/http_client.py +0 -0
  26. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/models.py +0 -0
  27. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/resources/organization.py +0 -0
  28. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/resources/service.py +0 -0
  29. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/resources/user.py +0 -0
  30. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/src/amigo_sdk/sdk_client.py +0 -0
  31. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/__init__.py +0 -0
  32. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/conftest.py +0 -0
  33. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/integration/test_conversation_integration.py +0 -0
  34. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/integration/test_organization_integration.py +0 -0
  35. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/integration/test_user_integration.py +0 -0
  36. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/resources/__init__.py +0 -0
  37. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/resources/helpers.py +0 -0
  38. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/resources/test_conversation.py +0 -0
  39. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/resources/test_organization.py +0 -0
  40. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/resources/test_service.py +0 -0
  41. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/resources/test_user.py +0 -0
  42. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/test_auth.py +0 -0
  43. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/test_config.py +0 -0
  44. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/test_errors.py +0 -0
  45. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/test_http_client.py +0 -0
  46. {amigo_sdk-0.95.0 → amigo_sdk-0.97.0}/tests/test_retry_utils.py +0 -0
  47. {amigo_sdk-0.95.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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amigo_sdk
3
- Version: 0.95.0
3
+ Version: 0.97.0
4
4
  Summary: Amigo AI Python SDK
5
5
  Author: Amigo AI
6
6
  License-File: LICENSE
@@ -43,6 +43,7 @@ path = "src/amigo_sdk/__init__.py"
43
43
  [tool.hatch.build.targets.wheel]
44
44
  packages = [
45
45
  "src/amigo_sdk",
46
+ "scripts",
46
47
  ]
47
48
 
48
49
  [tool.hatch.build.targets.sdist]
@@ -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()