Skip to content
Open
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
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
- [Get Application by Id](#get-application-by-id)
- [Models](#models)
- [Get Model by Name](#get-model-by-name)
- [User](#user)
- [Get Authenticated User Info](#get-authenticated-user-info)
- [Toolsets](#toolsets)
- [Get Toolset by Id](#get-toolset-by-id)
- [Resource Permissions](#resource-permissions)
Expand Down Expand Up @@ -799,6 +801,22 @@ ModelInfo(
)
```

### User

#### Get Authenticated User Info

To retrieve information about the currently authenticated user:

```python
# Sync
user_info = client.user.info()

# Async
user_info = await async_client.user.info()
```

The response shape may evolve depending on DIAL deployment settings, so this method returns a plain `dict[str, Any]`.

### Toolsets

#### Get Toolset by Id
Expand Down
2 changes: 2 additions & 0 deletions aidial_client/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ def _init_resources(self) -> None:
self.client_channel = resources.ClientChannel(
http_client=self._http_client
)
self.user = resources.User(http_client=self._http_client)

def _create_http_client(self) -> SyncHTTPClient:
return SyncHTTPClient(
Expand Down Expand Up @@ -213,6 +214,7 @@ def _init_resources(self) -> None:
self.client_channel = resources.AsyncClientChannel(
http_client=self._http_client
)
self.user = resources.AsyncUser(http_client=self._http_client)

def _create_http_client(self) -> AsyncHTTPClient:
return AsyncHTTPClient(
Expand Down
3 changes: 3 additions & 0 deletions aidial_client/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
ResourcePermissions,
)
from aidial_client.resources.toolset import AsyncToolset, Toolset
from aidial_client.resources.user import AsyncUser, User

from .application import Application, AsyncApplication
from .bucket import AsyncBucket, Bucket
Expand Down Expand Up @@ -40,4 +41,6 @@
"AsyncResourcePermissions",
"ClientChannel",
"AsyncClientChannel",
"User",
"AsyncUser",
]
20 changes: 20 additions & 0 deletions aidial_client/resources/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from typing import Any, Dict

from aidial_client._internal_types._http_request import FinalRequestOptions
from aidial_client.resources.base import AsyncResource, Resource


class User(Resource):
def info(self) -> Dict[str, Any]:
return self.http_client.request(
cast_to=dict,
options=FinalRequestOptions(method="GET", url="v1/user/info"),
)


class AsyncUser(AsyncResource):
async def info(self) -> Dict[str, Any]:
return await self.http_client.request(
cast_to=dict,
options=FinalRequestOptions(method="GET", url="v1/user/info"),
)
79 changes: 79 additions & 0 deletions tests/resources/test_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import httpx
import pytest

from aidial_client import AsyncDial, Dial
from aidial_client._exception import DialException
from tests.client_mock import get_async_client_mock, get_client_mock

BASE_URL = "http://dial.core"

USER_INFO_MOCK = {
"sub": "user-123",
"email": "user@example.com",
"name": "Test User",
}


def test_get_user_info():
client = get_client_mock(status_code=200, json_mock=USER_INFO_MOCK)
result = client.user.info()
assert result == USER_INFO_MOCK


@pytest.mark.asyncio
async def test_async_get_user_info():
client = get_async_client_mock(status_code=200, json_mock=USER_INFO_MOCK)
result = await client.user.info()
assert result == USER_INFO_MOCK


def test_get_user_info_request_method_and_url():
captured: list[httpx.Request] = []
client = Dial(api_key="dummy", base_url=BASE_URL)

def send_mock(request: httpx.Request, **kwargs):
captured.append(request)
return httpx.Response(200, request=request, json=USER_INFO_MOCK)

client._http_client._internal_http_client.send = send_mock
client.user.info()

assert len(captured) == 1
assert captured[0].method == "GET"
assert captured[0].url.path == "/v1/user/info"


@pytest.mark.asyncio
async def test_async_get_user_info_request_method_and_url():
captured: list[httpx.Request] = []
client = AsyncDial(api_key="dummy", base_url=BASE_URL)

async def send_mock(request: httpx.Request, **kwargs):
captured.append(request)
return httpx.Response(200, request=request, json=USER_INFO_MOCK)

client._http_client._internal_http_client.send = send_mock
await client.user.info()

assert len(captured) == 1
assert captured[0].method == "GET"
assert captured[0].url.path == "/v1/user/info"


def test_get_user_info_http_error():
client = get_client_mock(
status_code=401,
json_mock={"error": {"message": "Unauthorized", "type": "auth_error"}},
)
with pytest.raises(DialException):
client.user.info()


@pytest.mark.asyncio
async def test_async_get_user_info_http_error():
client = get_async_client_mock(
status_code=401,
json_mock={"error": {"message": "Unauthorized", "type": "auth_error"}},
)
with pytest.raises(DialException):
await client.user.info()
Loading