Skip to content

Commit

Permalink
Updated Integrations
Browse files Browse the repository at this point in the history
  • Loading branch information
schloerke committed Nov 14, 2024
1 parent faa2d8a commit fbfe8c8
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 42 deletions.
9 changes: 9 additions & 0 deletions src/posit/connect/_api_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def _endpoint(self, *path) -> str: ...
def _get_api(self, *path) -> Jsonifiable: ...
def _delete_api(self, *path) -> Jsonifiable | None: ...
def _patch_api(self, *path, json: Any | None) -> Jsonifiable: ...
def _post_api(self, *path, json: Any | None) -> Jsonifiable: ...
def _put_api(self, *path, json: Any | None) -> Jsonifiable: ...


Expand Down Expand Up @@ -64,6 +65,14 @@ def _patch_api(
response = self._ctx.session.patch(self._endpoint(*path), json=json)
return response.json()

def _post_api(
self: ApiCallProtocol,
*path,
json: Any | None,
) -> Jsonifiable:
response = self._ctx.session.post(self._endpoint(*path), json=json)
return response.json()

def _put_api(
self: ApiCallProtocol,
*path,
Expand Down
4 changes: 2 additions & 2 deletions src/posit/connect/oauth/associations.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def __init__(self, ctx: Context, /, **kwargs: Unpack[_Attrs]) -> None:
class IntegrationAssociations(ContextP[IntegrationContext]):
"""IntegrationAssociations resource."""

def __init__(self, ctx: Context, integration_guid: str) -> None:
def __init__(self, ctx: IntegrationContext) -> None:
super().__init__()
self._ctx = IntegrationContext(ctx, integration_guid=integration_guid)
self._ctx = ctx

def find(self) -> list[Association]:
"""Find OAuth associations.
Expand Down
91 changes: 54 additions & 37 deletions src/posit/connect/oauth/integrations.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,80 @@
"""OAuth integration resources."""

from typing import List, Optional, overload
from typing import List, Optional, cast, overload

from ..resources import Resource, Resources, resource_parameters_to_context
from typing_extensions import TypedDict, Unpack

from .._active import ActiveDict
from .._api_call import ApiCallMixin
from .._json import JsonifiableList
from .._types_context import ContextP
from .._utils import assert_guid
from ..context import Context
from ._types_context_integration import IntegrationContext
from .associations import IntegrationAssociations


class Integration(Resource):
class Integration(ActiveDict[IntegrationContext]):
"""OAuth integration resource."""

def __init__(self, ctx: Context, /, *, guid: str, **kwargs):
guid = assert_guid(guid)

integration_ctx = IntegrationContext(ctx, integration_guid=guid)
path = f"v1/oauth/integrations/{guid}"
get_data = len(kwargs) == 0 # `guid` is required
super().__init__(integration_ctx, path, get_data, guid=guid, **kwargs)

@property
def associations(self) -> IntegrationAssociations:
return IntegrationAssociations(
resource_parameters_to_context(self.params), integration_guid=self["guid"]
self._ctx,
)

def delete(self) -> None:
"""Delete the OAuth integration."""
path = f"v1/oauth/integrations/{self['guid']}"
url = self.params.url + path
self.params.session.delete(url)
url = self._ctx.url + path
self._ctx.session.delete(url)

class _AttrsUpdate(TypedDict, total=False):
name: str
description: str
config: dict

@overload
def update(
self,
*args,
name: str = ...,
description: str = ...,
config: dict = ...,
**kwargs,
) -> None:
**kwargs: Unpack[_AttrsUpdate],
) -> "Integration":
"""Update the OAuth integration.
Parameters
----------
name: str, optional
A descriptive name to identify each OAuth integration.
description: str, optional
A brief text to describe each OAuth integration.
config: dict, optional
The OAuth integration configuration based on the template. See List OAuth templates for
more information on available fields for each template. The configuration combines
elements from both options and fields from a given template.
"""
result = self._patch_api(json=kwargs)
return Integration(self._ctx, **result) # pyright: ignore[reportCallIssue]

@overload
def update(self, *args, **kwargs) -> None:
"""Update the OAuth integration."""

def update(self, *args, **kwargs) -> None:
"""Update the OAuth integration."""
body = dict(*args, **kwargs)
url = self.params.url + f"v1/oauth/integrations/{self['guid']}"
response = self.params.session.patch(url, json=body)
super().update(**response.json())
# TODO-barret; Should this auto retrieve? If so, it should inherit from ActiveSequence
class Integrations(ApiCallMixin, ContextP[Context]):
"""Integrations resource."""

@classmethod
def _api_path(cls) -> str:
return "v1/oauth/integrations"

class Integrations(Resources):
"""Integrations resource."""
def __init__(self, ctx: Context) -> None:
super().__init__()
self._ctx = ctx
self._path = self._api_path()

@overload
def create(
Expand Down Expand Up @@ -100,10 +122,8 @@ def create(self, **kwargs) -> Integration:
-------
Integration
"""
path = "v1/oauth/integrations"
url = self.params.url + path
response = self.params.session.post(url, json=kwargs)
return Integration(self.params, **response.json())
result = self._post_api(json=kwargs)
return Integration(self._ctx, **result) # pyright: ignore[reportCallIssue]

def find(self) -> List[Integration]:
"""Find OAuth integrations.
Expand All @@ -112,16 +132,15 @@ def find(self) -> List[Integration]:
-------
List[Integration]
"""
path = "v1/oauth/integrations"
url = self.params.url + path
results = self._get_api()
results_list = cast(JsonifiableList, results)

response = self.params.session.get(url)
return [
Integration(
self.params,
self._ctx,
**result,
)
for result in response.json()
for result in results_list
]

def get(self, guid: str) -> Integration:
Expand All @@ -135,7 +154,5 @@ def get(self, guid: str) -> Integration:
-------
Integration
"""
path = f"v1/oauth/integrations/{guid}"
url = self.params.url + path
response = self.params.session.get(url)
return Integration(self.params, **response.json())
result = self._get_api(guid)
return Integration(self._ctx, **result) # pyright: ignore[reportCallIssue]
2 changes: 1 addition & 1 deletion src/posit/connect/oauth/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(self, params: ResourceParameters, api_key: str) -> None:

@property
def integrations(self):
return Integrations(self.params)
return Integrations(resource_parameters_to_context(self.params))

@property
def sessions(self):
Expand Down
6 changes: 4 additions & 2 deletions tests/posit/connect/oauth/test_integrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def test(self):
c._ctx.version = None
integration = c.oauth.integrations.get(guid)
assert integration["guid"] == guid
old_name = integration["name"]

new_name = "New Name"

Expand All @@ -59,9 +60,10 @@ def test(self):
json=fake_integration,
)

integration.update(name=new_name)
updated_integration = integration.update(name=new_name)
assert mock_update.call_count == 1
assert integration["name"] == new_name
assert integration["name"] == old_name
assert updated_integration["name"] == new_name


class TestIntegrationsCreate:
Expand Down

0 comments on commit fbfe8c8

Please sign in to comment.