Skip to content

Commit 01cebb0

Browse files
committed
Move repository content to ._repository.py
1 parent 9e971c1 commit 01cebb0

File tree

2 files changed

+148
-133
lines changed

2 files changed

+148
-133
lines changed

src/posit/connect/_repository.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
"""Content item repository."""
2+
3+
from __future__ import annotations
4+
5+
from abc import abstractmethod
6+
7+
from typing_extensions import (
8+
Any,
9+
Hashable,
10+
Optional,
11+
Protocol,
12+
overload,
13+
)
14+
15+
from .errors import ClientError
16+
from .resources import Resource, _Resource
17+
18+
19+
# TODO-barret: Replace with Resource class from https://github.com/posit-dev/posit-sdk-py/pull/364/files#diff-94b7dc3c7d7d7c7b1a5f25e06c37df5fc53e1921cb10d41d4f04b18a715fae55R72
20+
class ResourceP(Protocol):
21+
def __getitem__(self, key: Hashable, /) -> Any: ...
22+
23+
24+
# ContentItem Repository uses a PATCH method, not a PUT for updating.
25+
class _ContentItemRepository(_Resource):
26+
def update(self, **attributes):
27+
response = self._ctx.client.patch(self._path, json=attributes)
28+
result = response.json()
29+
# # Calling this method will call `_Resource.update` which will try to PUT to the path.
30+
# super().update(**result)
31+
# Instead, update the dict directly.
32+
dict.update(self, **result)
33+
34+
35+
class ContentItemRepository(ResourceP, Protocol):
36+
"""
37+
Content items GitHub repository information.
38+
39+
See Also
40+
--------
41+
* Get info: https://docs.posit.co/connect/api/#get-/v1/content/-guid-/repository
42+
* Delete info: https://docs.posit.co/connect/api/#delete-/v1/content/-guid-/repository
43+
* Update info: https://docs.posit.co/connect/api/#patch-/v1/content/-guid-/repository
44+
"""
45+
46+
@abstractmethod
47+
def destroy(self) -> None:
48+
"""
49+
Delete the content's git repository location.
50+
51+
See Also
52+
--------
53+
* https://docs.posit.co/connect/api/#delete-/v1/content/-guid-/repository
54+
"""
55+
...
56+
57+
@abstractmethod
58+
def update(
59+
self,
60+
*,
61+
repository: Optional[str] = None,
62+
branch: str = "main",
63+
directory: str = ".",
64+
polling: bool = False,
65+
) -> None:
66+
"""Update the content's repository.
67+
68+
Parameters
69+
----------
70+
repository: str, optional
71+
URL for the repository. Default is None.
72+
branch: str, optional
73+
The tracked Git branch. Default is 'main'.
74+
directory: str, optional
75+
Directory containing the content. Default is '.'
76+
polling: bool, optional
77+
Indicates that the Git repository is regularly polled. Default is False.
78+
79+
Returns
80+
-------
81+
None
82+
83+
See Also
84+
--------
85+
* https://docs.posit.co/connect/api/#patch-/v1/content/-guid-/repository
86+
"""
87+
...
88+
89+
90+
class ContentItemRepositoryMixin(Resource):
91+
@property
92+
def repository(self) -> ContentItemRepository | None:
93+
try:
94+
path = f"v1/content/{self['guid']}/repository"
95+
response = self._ctx.client.get(path)
96+
result = response.json()
97+
return _ContentItemRepository(
98+
self._ctx,
99+
path,
100+
**result,
101+
)
102+
except ClientError:
103+
return None
104+
105+
@overload
106+
def create_repository(
107+
self,
108+
/,
109+
*,
110+
repository: Optional[str] = None,
111+
branch: str = "main",
112+
directory: str = ".",
113+
polling: bool = False,
114+
) -> ContentItemRepository: ...
115+
116+
@overload
117+
def create_repository(self, /, **attributes) -> ContentItemRepository: ...
118+
119+
def create_repository(self, /, **attributes) -> ContentItemRepository:
120+
"""Create repository.
121+
122+
Parameters
123+
----------
124+
repository : str
125+
URL for the respository.
126+
branch : str, optional
127+
The tracked Git branch. Default is 'main'.
128+
directory : str, optional
129+
Directory containing the content. Default is '.'.
130+
polling : bool, optional
131+
Indicates that the Git repository is regularly polled. Default is False.
132+
133+
Returns
134+
-------
135+
ContentItemRepository
136+
"""
137+
path = f"v1/content/{self['guid']}/repository"
138+
response = self._ctx.client.put(path, json=attributes)
139+
result = response.json()
140+
141+
return _ContentItemRepository(
142+
self._ctx,
143+
path,
144+
**result,
145+
)

src/posit/connect/content.py

Lines changed: 3 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,28 @@
44

55
import posixpath
66
import time
7-
from abc import abstractmethod
87

98
from typing_extensions import (
109
TYPE_CHECKING,
1110
Any,
12-
Hashable,
1311
List,
1412
Literal,
1513
NotRequired,
1614
Optional,
17-
Protocol,
1815
Required,
1916
TypedDict,
2017
Unpack,
2118
overload,
2219
)
2320

2421
from . import tasks
22+
from ._repository import ContentItemRepositoryMixin
2523
from .bundles import Bundles
2624
from .context import requires
2725
from .env import EnvVars
28-
from .errors import ClientError
2926
from .oauth.associations import ContentItemAssociations
3027
from .permissions import Permissions
31-
from .resources import Active, Resource, Resources, _Resource, _ResourceSequence
28+
from .resources import Active, Resource, Resources, _ResourceSequence
3229
from .tags import ContentItemTags
3330
from .vanities import VanityMixin
3431
from .variants import Variants
@@ -40,82 +37,11 @@
4037
from .tasks import Task
4138

4239

43-
# TODO-barret: Replace with Resource class from https://github.com/posit-dev/posit-sdk-py/pull/364/files#diff-94b7dc3c7d7d7c7b1a5f25e06c37df5fc53e1921cb10d41d4f04b18a715fae55R72
44-
class ResourceP(Protocol):
45-
def __getitem__(self, key: Hashable, /) -> Any: ...
46-
47-
4840
def _assert_guid(guid: str):
4941
assert isinstance(guid, str), "Expected 'guid' to be a string"
5042
assert len(guid) > 0, "Expected 'guid' to be non-empty"
5143

5244

53-
# ContentItem Repository uses a PATCH method, not a PUT for updating.
54-
class _ContentItemRepository(_Resource):
55-
def update(self, **attributes):
56-
response = self._ctx.client.patch(self._path, json=attributes)
57-
result = response.json()
58-
# # Calling this method will call `_Resource.update` which will try to PUT to the path.
59-
# super().update(**result)
60-
# Instead, update the dict directly.
61-
dict.update(self, **result)
62-
63-
64-
class ContentItemRepository(ResourceP, Protocol):
65-
"""
66-
Content items GitHub repository information.
67-
68-
See Also
69-
--------
70-
* Get info: https://docs.posit.co/connect/api/#get-/v1/content/-guid-/repository
71-
* Delete info: https://docs.posit.co/connect/api/#delete-/v1/content/-guid-/repository
72-
* Update info: https://docs.posit.co/connect/api/#patch-/v1/content/-guid-/repository
73-
"""
74-
75-
@abstractmethod
76-
def destroy(self) -> None:
77-
"""
78-
Delete the content's git repository location.
79-
80-
See Also
81-
--------
82-
* https://docs.posit.co/connect/api/#delete-/v1/content/-guid-/repository
83-
"""
84-
...
85-
86-
@abstractmethod
87-
def update(
88-
self,
89-
*,
90-
repository: Optional[str] = None,
91-
branch: str = "main",
92-
directory: str = ".",
93-
polling: bool = False,
94-
) -> None:
95-
"""Update the content's repository.
96-
97-
Parameters
98-
----------
99-
repository: str, optional
100-
URL for the repository. Default is None.
101-
branch: str, optional
102-
The tracked Git branch. Default is 'main'.
103-
directory: str, optional
104-
Directory containing the content. Default is '.'
105-
polling: bool, optional
106-
Indicates that the Git repository is regularly polled. Default is False.
107-
108-
Returns
109-
-------
110-
None
111-
112-
See Also
113-
--------
114-
* https://docs.posit.co/connect/api/#patch-/v1/content/-guid-/repository
115-
"""
116-
...
117-
118-
11945
class ContentItemOAuth(Resource):
12046
def __init__(self, ctx: Context, content_guid: str) -> None:
12147
super().__init__(ctx)
@@ -130,7 +56,7 @@ class ContentItemOwner(Resource):
13056
pass
13157

13258

133-
class ContentItem(Active, VanityMixin, Resource):
59+
class ContentItem(Active, ContentItemRepositoryMixin, VanityMixin, Resource):
13460
class _AttrsBase(TypedDict, total=False):
13561
# # `name` will be set by other _Attrs classes
13662
# name: str
@@ -217,62 +143,6 @@ def __getitem__(self, key: Any) -> Any:
217143
def oauth(self) -> ContentItemOAuth:
218144
return ContentItemOAuth(self._ctx, content_guid=self["guid"])
219145

220-
@property
221-
def repository(self) -> ContentItemRepository | None:
222-
try:
223-
path = f"v1/content/{self['guid']}/repository"
224-
response = self._ctx.client.get(path)
225-
result = response.json()
226-
return _ContentItemRepository(
227-
self._ctx,
228-
path,
229-
**result,
230-
)
231-
except ClientError:
232-
return None
233-
234-
@overload
235-
def create_repository(
236-
self,
237-
/,
238-
*,
239-
repository: Optional[str] = None,
240-
branch: str = "main",
241-
directory: str = ".",
242-
polling: bool = False,
243-
) -> ContentItemRepository: ...
244-
245-
@overload
246-
def create_repository(self, /, **attributes) -> ContentItemRepository: ...
247-
248-
def create_repository(self, /, **attributes) -> ContentItemRepository:
249-
"""Create repository.
250-
251-
Parameters
252-
----------
253-
repository : str
254-
URL for the respository.
255-
branch : str, optional
256-
The tracked Git branch. Default is 'main'.
257-
directory : str, optional
258-
Directory containing the content. Default is '.'.
259-
polling : bool, optional
260-
Indicates that the Git repository is regularly polled. Default is False.
261-
262-
Returns
263-
-------
264-
ContentItemRepository
265-
"""
266-
path = f"v1/content/{self['guid']}/repository"
267-
response = self._ctx.client.put(path, json=attributes)
268-
result = response.json()
269-
270-
return _ContentItemRepository(
271-
self._ctx,
272-
path,
273-
**result,
274-
)
275-
276146
def delete(self) -> None:
277147
"""Delete the content item."""
278148
path = f"v1/content/{self['guid']}"

0 commit comments

Comments
 (0)