Skip to content

Commit

Permalink
New rework of server user
Browse files Browse the repository at this point in the history
  • Loading branch information
pjdotson committed Sep 18, 2024
1 parent 61336ed commit c393055
Show file tree
Hide file tree
Showing 74 changed files with 965 additions and 342 deletions.
30 changes: 11 additions & 19 deletions client/py/synnax/ranger/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
RangeKeys,
RangeName,
RangeNames,
RangeParams,
RangePayload,
)
from synnax.ranger.retrieve import RangeRetriever
Expand Down Expand Up @@ -378,12 +377,10 @@ def _channel_retriever(self) -> ChannelRetriever:
return self._channels

@overload
def set_alias(self, channel: ChannelKey | ChannelName, alias: str):
...
def set_alias(self, channel: ChannelKey | ChannelName, alias: str): ...

@overload
def set_alias(self, channel: dict[ChannelKey | ChannelName, str]):
...
def set_alias(self, channel: dict[ChannelKey | ChannelName, str]): ...

def set_alias(
self,
Expand All @@ -409,20 +406,19 @@ def to_payload(self) -> RangePayload:
return RangePayload(name=self.name, time_range=self.time_range, key=self.key)

@overload
def write(self, to: ChannelKey | ChannelName | ChannelPayload, data: CrudeSeries):
...
def write(
self, to: ChannelKey | ChannelName | ChannelPayload, data: CrudeSeries
): ...

@overload
def write(
self,
to: ChannelKeys | ChannelNames | list[ChannelPayload],
series: list[CrudeSeries],
):
...
): ...

@overload
def write(self, frame: CrudeFrame):
...
def write(self, frame: CrudeFrame): ...

def write(
self,
Expand Down Expand Up @@ -596,20 +592,16 @@ def create(
return res if not is_single else res[0]

@overload
def retrieve(self, *, key: RangeKey) -> Range:
...
def retrieve(self, *, key: RangeKey) -> Range: ...

@overload
def retrieve(self, *, name: RangeName) -> Range:
...
def retrieve(self, *, name: RangeName) -> Range: ...

@overload
def retrieve(self, *, names: RangeNames) -> list[Range]:
...
def retrieve(self, *, names: RangeNames) -> list[Range]: ...

@overload
def retrieve(self, *, keys: RangeKeys) -> list[Range]:
...
def retrieve(self, *, keys: RangeKeys) -> list[Range]: ...

def retrieve(
self,
Expand Down
8 changes: 1 addition & 7 deletions client/py/synnax/ranger/payload.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023 Synnax Labs, Inc.
# Copyright 2024 Synnax Labs, Inc.
#
# Use of this software is governed by the Business Source License included in the file
# licenses/BSL.txt.
Expand All @@ -7,15 +7,9 @@
# License, use of this software will be governed by the Apache License, Version 2.0,
# included in the file licenses/APL.txt.

from dataclasses import dataclass
from typing import Literal
from uuid import UUID

from freighter import Payload

from synnax.exceptions import QueryError
from synnax.telem import TimeRange
from synnax.util.normalize import normalize


class RangePayload(Payload):
Expand Down
150 changes: 139 additions & 11 deletions client/py/synnax/user/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,154 @@
# License, use of this software will be governed by the Apache License, Version 2.0,
# included in the file licenses/APL.txt.

from freighter import UnaryClient, send_required
from synnax.auth import InsecureCredentials, TokenResponse
from synnax.user.payload import UserPayload
from uuid import UUID
from freighter import UnaryClient, send_required, Payload, Empty
from typing import overload
from synnax.user.payload import NewUser, UserPayload
from synnax.util.normalize import normalize


class _CreateRequest(Payload):
users: list[NewUser]


class _CreateResponse(Payload):
users: list[UserPayload]


class _RetrieveRequest(Payload):
keys: list[UUID] | None = None
usernames: list[str] | None = None


class _RetrieveResponse(Payload):
users: list[UserPayload] | None = None


class _DeleteRequest(Payload):
keys: list[UUID]


class _ChangeUsernameRequest(Payload):
key: UUID
username: str


class _ChangeNameRequest(Payload):
key: UUID
first_name: str
last_name: str


_CREATE_ENDPOINT = "/user/create"
_CHANGE_USERNAME_ENDPOINT = "/user/change_username"
_CHANGE_NAME_ENDPOINT = "/user/change_name"
_DELETE_ENDPOINT = "/user/delete"
_RETRIEVE_ENDPOINT = "/user/retrieve"


class UserClient:
client: UnaryClient

def __init__(
def __init__(self, transport: UnaryClient) -> None:
self.client = transport

@overload
def create(
self, *, username: str, password: str, first_name: str = "", last_name: str = ""
) -> UserPayload: ...

@overload
def create(self, *, users: list[NewUser]) -> list[UserPayload]: ...

def create(
self,
transport: UnaryClient,
*,
username: str | None,
password: str | None,
first_name: str | None,
last_name: str | None,
users: list[NewUser] | None,
) -> UserPayload | list[UserPayload]:
if user is not None:
users = normalize(user)
res = send_required(
self.client,
_CREATE_ENDPOINT,
_CreateRequest(users=users),
_CreateResponse,
).users
if user is not None:
return res[0]
return res

def change_username(self, key: UUID, username: str) -> None:
send_required(
self.client,
_CHANGE_USERNAME_ENDPOINT,
_ChangeUsernameRequest(key=key, username=username),
Empty,
)

def change_name(
self, key: UUID, *, first_name: str | None = None, last_name: str | None = None
) -> None:
self.client = transport
if first_name is None:
first_name = ""
if last_name is None:
last_name = ""
send_required(
self.client,
_CHANGE_NAME_ENDPOINT,
_ChangeNameRequest(key=key, first_name=first_name, last_name=last_name),
Empty,
)

@overload
def retrieve(self, *, key: UUID) -> UserPayload: ...

@overload
def retrieve(self, *, keys: list[UUID]) -> list[UserPayload]: ...

def register(self, username: str, password: str) -> UserPayload:
@overload
def retrieve(self, *, username: str) -> UserPayload: ...

@overload
def retrieve(self, *, usernames: list[str]) -> list[UserPayload]: ...

def retrieve(
self,
*,
key: UUID | None = None,
keys: list[UUID] | None = None,
username: str | None = None,
usernames: list[str] | None = None,
) -> UserPayload | list[UserPayload]:
if key is not None:
keys = normalize(key)
if username is not None:
usernames = normalize(username)
return send_required(
self.client,
_CREATE_ENDPOINT,
InsecureCredentials(username=username, password=password),
TokenResponse,
).user
_RETRIEVE_ENDPOINT,
_RetrieveRequest(keys=keys, usernames=usernames),
_RetrieveResponse,
).users

@overload
def delete(self, *, key: UUID) -> None: ...

@overload
def delete(self, *, keys: list[UUID]) -> None: ...

def delete(
self, *, key: UUID | None = None, keys: list[UUID] | None = None
) -> None:
if key is not None:
keys = normalize(key)
send_required(
self.client,
_DELETE_ENDPOINT,
_DeleteRequest(keys=keys),
Empty,
)
14 changes: 12 additions & 2 deletions client/py/synnax/user/payload.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023 Synnax Labs, Inc.
# Copyright 2024 Synnax Labs, Inc.
#
# Use of this software is governed by the Business Source License included in the file
# licenses/BSL.txt.
Expand All @@ -7,15 +7,25 @@
# License, use of this software will be governed by the Apache License, Version 2.0,
# included in the file licenses/APL.txt.

from uuid import UUID
from freighter import Payload
from synnax.ontology.payload import ID

user_ontology_type = ID(type="user")


class NewUser(Payload):
username: str
password: str
first_name: str | None
last_name: str | None


class UserPayload(Payload):
key: str
key: UUID
username: str
first_name: str | None
last_name: str | None

def ontology_id(self) -> ID:
return ID(key=self.key, type="user")
6 changes: 3 additions & 3 deletions client/py/tests/test_access.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def test_create_user(
):
host, port, _, _ = login_info
username = str(uuid.uuid4())
client.user.register(username, "pwd2")
client.user.create(username, "pwd2")
client2 = sy.Synnax(
host=host,
port=port,
Expand All @@ -114,14 +114,14 @@ def test_create_user(
)

with pytest.raises(sy.AuthError):
client2.user.register(str(uuid.uuid4()), "pwd3")
client2.user.create(str(uuid.uuid4()), "pwd3")

def test_user_privileges(
self, client: sy.Synnax, login_info: tuple[str, int, str, str]
):
host, port, _, _ = login_info
username = str(uuid.uuid4())
usr = client.user.register(username, "pwd3")
usr = client.user.create(username, "pwd3")
client2 = sy.Synnax(
host=host,
port=port,
Expand Down
22 changes: 22 additions & 0 deletions client/py/tests/test_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2024 Synnax Labs, Inc.
#
# Use of this software is governed by the Business Source License included in the file
# licenses/BSL.txt.
#
# As of the Change Date specified in that file, in accordance with the Business Source
# License, use of this software will be governed by the Apache License, Version 2.0,
# included in the file licenses/APL.txt.

import pytest
import synnax as sy
from uuid import UUID


@pytest.mark.user
class TestUserClient:

def test_create(self, client: sy.Synnax):
sy.NewUser(username="test", password="test")
user = client.user.create(user=(username="test", password="test"))
assert user.username == "test"
assert user.key is not None
Loading

0 comments on commit c393055

Please sign in to comment.