From b88bf12b6e28a7c84c53de690896b9ac3672b247 Mon Sep 17 00:00:00 2001 From: tdstein Date: Wed, 6 Mar 2024 16:42:26 -0500 Subject: [PATCH] feat: adds base class definition for resources --- src/posit/connect/content.py | 12 ++++++- src/posit/connect/resources.py | 31 +++++++++++++++++ src/posit/connect/users.py | 13 ++++++- tests/posit/connect/test_resources.py | 49 +++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 src/posit/connect/resources.py create mode 100644 tests/posit/connect/test_resources.py diff --git a/src/posit/connect/content.py b/src/posit/connect/content.py index 2816e715..f06f95bc 100644 --- a/src/posit/connect/content.py +++ b/src/posit/connect/content.py @@ -7,6 +7,7 @@ from . import urls from .config import Config +from .resources import Resources class ContentItem(TypedDict, total=False): @@ -14,7 +15,7 @@ class ContentItem(TypedDict, total=False): pass -class Content: +class Content(Resources[ContentItem]): def __init__(self, config: Config, session: Session) -> None: self.url = urls.append_path(config.url, "v1/content") self.config = config @@ -40,3 +41,12 @@ def get(self, id: str) -> ContentItem: url = urls.append_path(self.url, id) response = self.session.get(url) return ContentItem(**response.json()) + + def create(self) -> ContentItem: + raise NotImplementedError() + + def update(self) -> ContentItem: + raise NotImplementedError() + + def delete(self) -> None: + raise NotImplementedError() diff --git a/src/posit/connect/resources.py b/src/posit/connect/resources.py new file mode 100644 index 00000000..c7ade76c --- /dev/null +++ b/src/posit/connect/resources.py @@ -0,0 +1,31 @@ +from abc import ABC, abstractmethod +from typing import Generic, List, Optional, TypeVar + + +T = TypeVar("T") + + +class Resources(ABC, Generic[T]): + @abstractmethod + def create(self, *args, **kwargs) -> T: + raise NotImplementedError() + + @abstractmethod + def delete(self, *args, **kwargs) -> None: + raise NotImplementedError() + + @abstractmethod + def find(self, *args, **kwargs) -> List[T]: + raise NotImplementedError() + + @abstractmethod + def find_one(self, *args, **kwargs) -> Optional[T]: + raise NotImplementedError() + + @abstractmethod + def get(self, *args, **kwargs) -> T: + raise NotImplementedError() + + @abstractmethod + def update(self, *args, **kwargs) -> T: + raise NotImplementedError() diff --git a/src/posit/connect/users.py b/src/posit/connect/users.py index cdc71b7c..f1ee0de6 100644 --- a/src/posit/connect/users.py +++ b/src/posit/connect/users.py @@ -5,10 +5,12 @@ from requests import Session + from . import urls from .config import Config from .paginator import _MAX_PAGE_SIZE, Paginator +from .resources import Resources class User(TypedDict, total=False): @@ -25,7 +27,7 @@ class User(TypedDict, total=False): locked: bool -class Users: +class Users(Resources[User]): def __init__(self, config: Config, session: Session) -> None: self.url = urls.append_path(config.url, "v1/users") self.config = config @@ -54,3 +56,12 @@ def get(self, id: str) -> User: url = urls.append_path(self.url, id) response = self.session.get(url) return User(**response.json()) + + def create(self) -> User: + raise NotImplementedError() + + def update(self) -> User: + raise NotImplementedError() + + def delete(self) -> None: + raise NotImplementedError() diff --git a/tests/posit/connect/test_resources.py b/tests/posit/connect/test_resources.py new file mode 100644 index 00000000..44a96145 --- /dev/null +++ b/tests/posit/connect/test_resources.py @@ -0,0 +1,49 @@ +import pytest + +from typing import Any, List, Optional + +from posit.connect.resources import Resources + + +class TestResources(Resources[Any]): + def create(self) -> Any: + return super().create() # type: ignore [safe-super] + + def delete(self) -> None: + return super().delete() # type: ignore [safe-super] + + def find(self) -> List[Any]: + return super().find() # type: ignore [safe-super] + + def find_one(self) -> Optional[Any]: + return super().find_one() # type: ignore [safe-super] + + def get(self) -> Any: + return super().get() # type: ignore [safe-super] + + def update(self) -> Any: + return super().update() # type: ignore [safe-super] + + def test_create(self): + with pytest.raises(NotImplementedError): + self.create() + + def test_delete(self): + with pytest.raises(NotImplementedError): + self.delete() + + def test_find(self): + with pytest.raises(NotImplementedError): + self.find() + + def test_find_one(self): + with pytest.raises(NotImplementedError): + self.find_one() + + def test_get(self): + with pytest.raises(NotImplementedError): + self.get() + + def test_update(self): + with pytest.raises(NotImplementedError): + self.update()