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.
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/.github/workflows/test.yml +1 -1
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/PKG-INFO +1 -1
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/__init__.py +1 -1
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/generated/model.py +1 -1
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/resources/user.py +16 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/integration/test_user_integration.py +27 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/test_user.py +58 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/.github/workflows/auto-release.yml +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/.github/workflows/release.yml +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/.gitignore +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/CONTRIBUTING.md +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/LICENSE +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/README.md +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/pyproject.toml +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/scripts/__init__.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/scripts/aliases.json +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/scripts/check.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/scripts/gen_models.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/specs/openapi-baseline.json +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/_retry_utils.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/auth.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/config.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/errors.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/http_client.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/models.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/resources/conversation.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/resources/organization.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/resources/service.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/src/amigo_sdk/sdk_client.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/__init__.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/conftest.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/integration/test_conversation_integration.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/integration/test_organization_integration.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/__init__.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/helpers.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/test_conversation.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/test_organization.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/resources/test_service.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_auth.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_config.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_errors.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_http_client.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_retry_utils.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/tests/test_sdk_client.py +0 -0
- {amigo_sdk-0.97.0 → amigo_sdk-0.98.0}/uv.lock +0 -0
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|