amigo_sdk 0.97.0__tar.gz → 0.98.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 (45) hide show
  1. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/.github/workflows/test.yml +1 -1
  2. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/PKG-INFO +1 -1
  3. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/__init__.py +1 -1
  4. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/generated/model.py +1 -1
  5. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/resources/user.py +16 -0
  6. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/integration/test_user_integration.py +27 -0
  7. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/test_user.py +58 -0
  8. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/.github/workflows/auto-release.yml +0 -0
  9. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/.github/workflows/release.yml +0 -0
  10. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/.gitignore +0 -0
  11. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/CONTRIBUTING.md +0 -0
  12. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/LICENSE +0 -0
  13. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/README.md +0 -0
  14. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/pyproject.toml +0 -0
  15. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/scripts/__init__.py +0 -0
  16. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/scripts/aliases.json +0 -0
  17. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/scripts/check.py +0 -0
  18. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/scripts/gen_models.py +0 -0
  19. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/specs/openapi-baseline.json +0 -0
  20. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/_retry_utils.py +0 -0
  21. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/auth.py +0 -0
  22. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/config.py +0 -0
  23. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/errors.py +0 -0
  24. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/http_client.py +0 -0
  25. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/models.py +0 -0
  26. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/resources/conversation.py +0 -0
  27. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/resources/organization.py +0 -0
  28. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/resources/service.py +0 -0
  29. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/sdk_client.py +0 -0
  30. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/__init__.py +0 -0
  31. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/conftest.py +0 -0
  32. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/integration/test_conversation_integration.py +0 -0
  33. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/integration/test_organization_integration.py +0 -0
  34. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/__init__.py +0 -0
  35. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/helpers.py +0 -0
  36. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/test_conversation.py +0 -0
  37. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/test_organization.py +0 -0
  38. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/test_service.py +0 -0
  39. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_auth.py +0 -0
  40. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_config.py +0 -0
  41. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_errors.py +0 -0
  42. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_http_client.py +0 -0
  43. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_retry_utils.py +0 -0
  44. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_sdk_client.py +0 -0
  45. {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/uv.lock +0 -0
@@ -83,4 +83,4 @@ jobs:
83
83
  AMIGO_ORGANIZATION_ID: ${{ secrets.AMIGO_ORGANIZATION_ID }}
84
84
  AMIGO_USER_ID: ${{ secrets.AMIGO_USER_ID }}
85
85
  AMIGO_BASE_URL: ${{ secrets.AMIGO_BASE_URL }}
86
- run: pytest -m integration -v
86
+ run: pytest -m integration -v -s
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amigo_sdk
3
- Version: 0.97.0
3
+ Version: 0.98.0
4
4
  Summary: Amigo AI Python SDK
5
5
  Author: Amigo AI
6
6
  License-File: LICENSE
@@ -1,4 +1,4 @@
1
- __version__ = "0.97.0"
1
+ __version__ = "0.98.0"
2
2
  from .sdk_client import AmigoClient, AsyncAmigoClient
3
3
 
4
4
  __all__ = ["__version__", "AmigoClient", "AsyncAmigoClient"]
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: <stdin>
3
- # timestamp: 2026-01-08T19:54:56+00:00
3
+ # timestamp: 2026-01-08T23:39:28+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -2,6 +2,7 @@ from amigo_sdk.generated.model import (
2
2
  GetUsersParametersQuery,
3
3
  UserCreateInvitedUserRequest,
4
4
  UserCreateInvitedUserResponse,
5
+ UserGetUserModelResponse,
5
6
  UserGetUsersResponse,
6
7
  UserUpdateUserInfoRequest,
7
8
  )
@@ -54,6 +55,14 @@ class AsyncUserResource:
54
55
  json=body.model_dump(mode="json", exclude_none=True),
55
56
  )
56
57
 
58
+ async def get_user_model(self, user_id: str) -> UserGetUserModelResponse:
59
+ """Get the latest user model for a user."""
60
+ response = await self._http.request(
61
+ "GET",
62
+ f"/v1/{self._organization_id}/user/{user_id}/user_model",
63
+ )
64
+ return UserGetUserModelResponse.model_validate_json(response.text)
65
+
57
66
 
58
67
  class UserResource:
59
68
  """User resource (synchronous)."""
@@ -93,3 +102,10 @@ class UserResource:
93
102
  f"/v1/{self._organization_id}/user/{user_id}",
94
103
  json=body.model_dump(mode="json", exclude_none=True),
95
104
  )
105
+
106
+ def get_user_model(self, user_id: str) -> UserGetUserModelResponse:
107
+ response = self._http.request(
108
+ "GET",
109
+ f"/v1/{self._organization_id}/user/{user_id}/user_model",
110
+ )
111
+ return UserGetUserModelResponse.model_validate_json(response.text)
@@ -60,6 +60,17 @@ class TestUserIntegration:
60
60
  assert by_email is not None
61
61
  assert any(u.email == type(self).created_user_email for u in by_email.users)
62
62
 
63
+ # we need to get the user model for the authenticated user because the permission grant for the user model
64
+ # does not allow access to non-admin user user models
65
+ async def test_get_user_model(self):
66
+ user_id = os.environ.get("AMIGO_USER_ID")
67
+ assert user_id is not None, "AMIGO_USER_ID environment variable must be set"
68
+ async with AsyncAmigoClient() as client:
69
+ result = await client.users.get_user_model(user_id)
70
+ assert result is not None
71
+ assert isinstance(result.user_models, list)
72
+ assert isinstance(result.additional_context, list)
73
+
63
74
  async def test_delete_user(self):
64
75
  assert type(self).created_user_id is not None
65
76
  async with AsyncAmigoClient() as client:
@@ -94,6 +105,10 @@ class TestUserIntegration:
94
105
  with pytest.raises(errors.AuthenticationError):
95
106
  await bad_client.users.get_users()
96
107
 
108
+ # Get user model for non-existent user
109
+ with pytest.raises(errors.NotFoundError):
110
+ await client.users.get_user_model("non-existent-id")
111
+
97
112
  # Delete non-existent user
98
113
  with pytest.raises(errors.NotFoundError):
99
114
  await client.users.delete_user("non-existent-id")
@@ -148,6 +163,15 @@ class TestUserIntegrationSync:
148
163
  assert by_email is not None
149
164
  assert any(u.email == type(self).created_user_email for u in by_email.users)
150
165
 
166
+ def test_get_user_model(self):
167
+ user_id = os.environ.get("AMIGO_USER_ID")
168
+ assert user_id is not None, "AMIGO_USER_ID environment variable not set"
169
+ with AmigoClient() as client:
170
+ result = client.users.get_user_model(user_id)
171
+ assert result is not None
172
+ assert isinstance(result.user_models, list)
173
+ assert isinstance(result.additional_context, list)
174
+
151
175
  def test_delete_user(self):
152
176
  assert type(self).created_user_id is not None
153
177
  with AmigoClient() as client:
@@ -177,5 +201,8 @@ class TestUserIntegrationSync:
177
201
  with pytest.raises(errors.AuthenticationError):
178
202
  bad_client.users.get_users()
179
203
 
204
+ with pytest.raises(errors.NotFoundError):
205
+ client.users.get_user_model("non-existent-id")
206
+
180
207
  with pytest.raises(errors.NotFoundError):
181
208
  client.users.delete_user("non-existent-id")
@@ -4,9 +4,12 @@ from amigo_sdk.config import AmigoConfig
4
4
  from amigo_sdk.errors import NotFoundError, ValidationError
5
5
  from amigo_sdk.generated.model import (
6
6
  GetUsersParametersQuery,
7
+ MongoCollectionsUserUserUserModelUserDimension,
7
8
  UserCreateInvitedUserRequest,
8
9
  UserCreateInvitedUserResponse,
10
+ UserGetUserModelResponse,
9
11
  UserGetUsersResponse,
12
+ UserModel,
10
13
  UserUpdateUserInfoRequest,
11
14
  )
12
15
  from amigo_sdk.http_client import AmigoAsyncHttpClient, AmigoHttpClient
@@ -122,6 +125,34 @@ class TestUserResource:
122
125
  with pytest.raises(ValidationError):
123
126
  await user_resource.update_user("u-1", body)
124
127
 
128
+ @pytest.mark.asyncio
129
+ async def test_get_user_model_returns_data(self, user_resource):
130
+ mock_response = UserGetUserModelResponse(
131
+ user_models=[
132
+ UserModel(
133
+ content="model-content",
134
+ insight_ids=["insight-1"],
135
+ dimensions=[
136
+ MongoCollectionsUserUserUserModelUserDimension(
137
+ description="detail", tags=["tag"]
138
+ )
139
+ ],
140
+ )
141
+ ],
142
+ additional_context=["context"],
143
+ )
144
+
145
+ async with mock_http_request(mock_response):
146
+ result = await user_resource.get_user_model("u-1")
147
+ assert isinstance(result, UserGetUserModelResponse)
148
+ assert result.user_models[0].content == "model-content"
149
+
150
+ @pytest.mark.asyncio
151
+ async def test_get_user_model_not_found_raises(self, user_resource):
152
+ async with mock_http_request("{}", status_code=404):
153
+ with pytest.raises(NotFoundError):
154
+ await user_resource.get_user_model("missing")
155
+
125
156
 
126
157
  @pytest.mark.unit
127
158
  class TestUserResourceSync:
@@ -211,3 +242,30 @@ class TestUserResourceSync:
211
242
  with mock_http_request_sync({"detail": "bad"}, status_code=422):
212
243
  with pytest.raises(ValidationError):
213
244
  res.update_user("u-1", body)
245
+
246
+ def test_get_user_model_returns_data_sync(self, mock_config):
247
+ res = self._resource(mock_config)
248
+ mock_response = UserGetUserModelResponse(
249
+ user_models=[
250
+ UserModel(
251
+ content="model-content",
252
+ insight_ids=["insight-1"],
253
+ dimensions=[
254
+ MongoCollectionsUserUserUserModelUserDimension(
255
+ description="detail", tags=["tag"]
256
+ )
257
+ ],
258
+ )
259
+ ],
260
+ additional_context=["context"],
261
+ )
262
+ with mock_http_request_sync(mock_response):
263
+ result = res.get_user_model("u-1")
264
+ assert isinstance(result, UserGetUserModelResponse)
265
+ assert result.user_models[0].content == "model-content"
266
+
267
+ def test_get_user_model_not_found_raises_sync(self, mock_config):
268
+ res = self._resource(mock_config)
269
+ with mock_http_request_sync("{}", status_code=404):
270
+ with pytest.raises(NotFoundError):
271
+ res.get_user_model("missing")
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes