Skip to content

Commit

Permalink
Merge pull request #8868 from kiendang/fix-user-search
Browse files Browse the repository at this point in the history
Fix user search
  • Loading branch information
shubham3121 authored Jun 11, 2024
2 parents e0a2ce1 + 5fdd197 commit f0711f5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 23 deletions.
54 changes: 31 additions & 23 deletions packages/syft/src/syft/client/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@

# third party
from nacl.exceptions import BadSignatureError
from pydantic import BaseModel
from pydantic import ConfigDict
from pydantic import EmailStr
from pydantic import TypeAdapter
from result import OkErr
from result import Result
from typeguard import check_type
Expand Down Expand Up @@ -85,6 +88,16 @@
IPYNB_BACKGROUND_PREFIXES = ["_ipy", "_repr", "__ipython", "__pydantic"]


def _has_config_dict(t: Any) -> bool:
return (
# Use this instead of `issubclass`` to be compatible with python 3.10
# `inspect.isclass(t) and issubclass(t, BaseModel)`` wouldn't work with
# generics, e.g. `set[sy.UID]`, in python 3.10
(hasattr(t, "__mro__") and BaseModel in t.__mro__)
or hasattr(t, "__pydantic_config__")
)


class APIRegistry:
__api_registry__: dict[tuple, SyftAPI] = OrderedDict()

Expand Down Expand Up @@ -1321,30 +1334,25 @@ def validate_callable_args_and_kwargs(
t = index_syft_by_module_name(param.annotation)
else:
t = param.annotation
msg = None
try:
if t is not inspect.Parameter.empty:
if isinstance(t, _GenericAlias) and type(None) in t.__args__:
success = False
for v in t.__args__:
if issubclass(v, EmailStr):
v = str
try:
check_type(value, v) # raises Exception
success = True
break # only need one to match
except Exception: # nosec
pass
if not success:
raise TypeError()
else:
check_type(value, t) # raises Exception
except TypeError:
_type_str = getattr(t, "__name__", str(t))
msg = f"`{key}` must be of type `{_type_str}` not `{type(value).__name__}`"

if msg:
return SyftError(message=msg)
if t is not inspect.Parameter.empty:
try:
config_kw = (
{"config": ConfigDict(arbitrary_types_allowed=True)}
if not _has_config_dict(t)
else {}
)

# TypeAdapter only accepts `config` arg if `t` does not
# already contain a ConfigDict
# i.e model_config in BaseModel and __pydantic_config__ in
# other types.
TypeAdapter(t, **config_kw).validate_python(value)
except Exception:
_type_str = getattr(t, "__name__", str(t))
return SyftError(
message=f"`{key}` must be of type `{_type_str}` not `{type(value).__name__}`"
)

_valid_kwargs[key] = value

Expand Down
18 changes: 18 additions & 0 deletions packages/syft/tests/syft/users/user_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,3 +423,21 @@ def test_user_view_set_role_admin(faker: Faker) -> None:

node.python_node.cleanup()
node.land()


@pytest.mark.parametrize(
"search_param",
[
("email", "logged_in_user"),
("name", "logged_in_username"),
],
)
def test_user_search(
root_client: DomainClient, ds_client: DomainClient, search_param: tuple[str, str]
) -> None:
k, attr = search_param
v = getattr(ds_client, attr)
users = root_client.api.services.user.search(**{k: v})

for user in users:
assert getattr(user, k) == v

0 comments on commit f0711f5

Please sign in to comment.