Skip to content

Commit

Permalink
feat: adds partial users implementation based on lists
Browse files Browse the repository at this point in the history
  • Loading branch information
tdstein committed Feb 6, 2024
1 parent cfd9650 commit 48e86f2
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 35 deletions.
11 changes: 10 additions & 1 deletion src/posit/connect/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
from .client import Client # noqa
from typing import Optional

from .client import Client


def make_client(
api_key: Optional[str] = None, endpoint: Optional[str] = None
) -> Client:
client = Client(api_key=api_key, endpoint=endpoint)
return client
76 changes: 67 additions & 9 deletions src/posit/connect/users.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,75 @@
from __future__ import annotations

import os

from requests import Session, Response
from dataclasses import dataclass, asdict
from datetime import datetime
from requests import Session
from typing import Optional


@dataclass
class User:
guid: str
email: str
username: str
first_name: str
last_name: str
user_role: str
created_time: datetime
updated_time: datetime
active_time: datetime
confirmed: bool
locked: bool

def to_dict(self) -> dict:
return asdict(self)


class Users(list[User]):
"""An extension of :class:`list[User]` with additional fetch methods."""

_endpoint: str
_session: Session

class Users:
def __init__(self, endpoint: str, session: Session) -> None:
def __init__(self, endpoint: str, session: Session):
self._endpoint = endpoint
self._session = session

def get_user(self, user_id: str) -> Response:
endpoint = os.path.join(self._endpoint, "__api__/v1/users", user_id)
return self._session.get(endpoint)
def find(self, params: dict = {}) -> Users:
"""Finds any :class:`User` that matches the provided filter conditions
Keyword Arguments:
params -- filter conditions (default: {{}})
Returns:
`self`
"""
self.clear()
endpoint = os.path.join(self._endpoint, "__api__/v1/users")
response = self._session.get(endpoint)
data = response.json()
for user in data["results"]:
if all(user.get(k) == v for k, v in params.items()):
self.append(User(**user))
# todo - implement paging and caching
return self

def find_one(self, params: dict = {}) -> Optional[User]:
"""Finds one :class:`User`
Keyword Arguments:
params -- filter conditions (default: {{}})
Returns:
A matching :class:`User`.
"""
if "guid" in params:
# Use the user details API if a 'guid' is provided.
# This is an example of how we can use different API endpoints to optimize execution time.
endpoint = os.path.join(self._endpoint, "__api__/v1/users", params["guid"])
response = self._session.get(endpoint)
return User(**response.json())

def get_current_user(self) -> Response:
endpoint = os.path.join(self._endpoint, "__api__/v1/user")
return self._session.get(endpoint)
# Otherwise, perform a normal search.
return next(iter(self.find(params)), None)
21 changes: 0 additions & 21 deletions src/posit/connect/users_test.py
Original file line number Diff line number Diff line change
@@ -1,21 +0,0 @@
from unittest.mock import Mock

from .users import Users


class TestUsers:
def test_get_user(self):
session = Mock()
session.get = Mock(return_value={})
users = Users(endpoint="http://foo.bar/", session=session)
response = users.get_user(user_id="foo")
assert response == {}
session.get.assert_called_once_with("http://foo.bar/__api__/v1/users/foo")

def test_get_current_user(self):
session = Mock()
session.get = Mock(return_value={})
users = Users(endpoint="http://foo.bar/", session=session)
response = users.get_current_user()
assert response == {}
session.get.assert_called_once_with("http://foo.bar/__api__/v1/user")
12 changes: 8 additions & 4 deletions tinkering.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from posit.connect.client import Client
from posit.connect import make_client

client = Client()
res = client.users.get_current_user()
print(res.json())
client = make_client()
for user in client.users.find({"username": "aaron"}):
print(user)

print(client.users.find_one())

print(client.users.find_one({"guid": "f155520a-ca2e-4084-b0a0-12120b7d1add"}))

0 comments on commit 48e86f2

Please sign in to comment.