Skip to content

Commit 8efbecf

Browse files
committed
--wip-- [skip ci]
1 parent 3805248 commit 8efbecf

File tree

9 files changed

+123
-178
lines changed

9 files changed

+123
-178
lines changed

integration/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,5 @@ test:
137137
set -o pipefail; \
138138
CONNECT_VERSION=${CONNECT_VERSION} \
139139
CONNECT_API_KEY="$(shell $(UV) run rsconnect bootstrap -i -s http://connect:3939 --raw)" \
140-
$(UV) run pytest -s --junit-xml=./reports/$(CONNECT_VERSION).xml | \
140+
$(UV) run pytest -s -k TestJobs --junit-xml=./reports/$(CONNECT_VERSION).xml | \
141141
tee ./logs/$(CONNECT_VERSION).log;

integration/tests/posit/connect/test_jobs.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,17 @@ def test(self):
3636

3737
jobs = content.jobs
3838
assert len(jobs) == 1
39+
40+
def test_find_by(self):
41+
content = self.content
42+
43+
path = Path("../../../resources/connect/bundles/example-quarto-minimal/bundle.tar.gz")
44+
path = Path(__file__).parent / path
45+
path = path.resolve()
46+
path = str(path)
47+
48+
bundle = content.bundles.create(path)
49+
bundle.deploy()
50+
51+
jobs = content.jobs.find_by(status=1)
52+
assert len(jobs) == 1

src/posit/connect/client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .groups import Groups
1515
from .metrics import Metrics
1616
from .oauth import OAuth
17+
from .packages import Packages
1718
from .resources import ResourceParameters
1819
from .tasks import Tasks
1920
from .users import User, Users
@@ -269,6 +270,10 @@ def oauth(self) -> OAuth:
269270
"""
270271
return OAuth(self.resource_params, self.cfg.api_key)
271272

273+
@property
274+
def packages(self) -> Packages:
275+
return Packages(self.ctx, "v1/packages")
276+
272277
@property
273278
def vanities(self) -> Vanities:
274279
return Vanities(self.resource_params)

src/posit/connect/content.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class ContentItemOwner(Resource):
3737
pass
3838

3939

40-
class ContentItem(JobsMixin, VanityMixin, Resource):
40+
class ContentItem(JobsMixin, PackagesMixin, VanityMixin, Resource):
4141
def __init__(self, /, params: ResourceParameters, **kwargs):
4242
ctx = Context(params.session, params.url)
4343
uid = kwargs["guid"]

src/posit/connect/packages.py

Lines changed: 43 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,64 @@
1-
from typing import Literal, Optional, Sequence, TypedDict
1+
import posixpath
2+
from typing import Optional, TypedDict, overload
23

34
from typing_extensions import NotRequired, Required, Unpack
45

5-
from .resources import Resource, ResourceParameters, Resources
6+
from .resources import Active, ActiveFinderMethods, ActiveSequence
67

78

8-
class Package(Resource):
9-
"""A package resource."""
10-
11-
class PackageAttributes(TypedDict):
12-
"""Package attributes."""
13-
14-
language: Required[Literal["r", "python"]]
9+
class Package(Active):
10+
class _Package(TypedDict):
11+
language: Required[str]
1512
name: Required[str]
1613
version: Required[str]
17-
hash: NotRequired[str]
14+
hash: Required[Optional[str]]
1815

19-
def __init__(self, params: ResourceParameters, **kwargs: Unpack[PackageAttributes]):
20-
super().__init__(params, **kwargs)
16+
def __init__(self, ctx, path, /, **attributes: Unpack[_Package]):
17+
super().__init__(ctx, path, **attributes)
2118

2219

23-
class Packages(Resources, Sequence[Package]):
20+
class Packages(ActiveFinderMethods["Package"], ActiveSequence["Package"]):
2421
"""A collection of packages."""
2522

26-
def __init__(self, params, endpoint):
27-
super().__init__(params)
28-
self._endpoint = endpoint
29-
self._packages = []
30-
self.reload()
31-
32-
def __getitem__(self, index):
33-
"""Retrieve an item or slice from the sequence."""
34-
return self._packages[index]
23+
def __init__(self, ctx, path):
24+
super().__init__(ctx, path, "name")
3525

36-
def __len__(self):
37-
"""Return the length of the sequence."""
38-
return len(self._packages)
26+
def _create_instance(self, path, /, **attributes):
27+
return Package(self._ctx, path, **attributes)
3928

40-
def __repr__(self):
41-
"""Return the string representation of the sequence."""
42-
return f"Packages({', '.join(map(str, self._packages))})"
29+
class _FindBy(TypedDict, total=False):
30+
language: NotRequired[str]
31+
name: NotRequired[str]
32+
version: NotRequired[str]
33+
hash: NotRequired[Optional[str]]
4334

44-
def count(self, value):
45-
"""Return the number of occurrences of a value in the sequence."""
46-
return self._packages.count(value)
35+
@overload
36+
def find_by(self, **conditions: Unpack[_FindBy]):
37+
...
4738

48-
def index(self, value, start=0, stop=None):
49-
"""Return the index of the first occurrence of a value in the sequence."""
50-
if stop is None:
51-
stop = len(self._packages)
52-
return self._packages.index(value, start, stop)
39+
@overload
40+
def find_by(self, **conditions):
41+
...
5342

54-
def reload(self) -> "Packages":
55-
"""Reload packages from the Connect server.
56-
57-
Returns
58-
-------
59-
List[Package]
60-
"""
61-
response = self.params.session.get(self._endpoint)
62-
results = response.json()
63-
packages = [Package(self.params, **result) for result in results]
64-
self._packages = packages
65-
return self
43+
def find_by(self, **conditions):
44+
return super().find_by(**conditions)
6645

46+
class PackagesMixin(Active):
47+
"""Mixin class to add a packages attribute."""
6748

68-
class PackagesMixin(Resource):
69-
"""Mixin class to add a packages to a resource."""
49+
def __init__(self, ctx, path, /, **attributes):
50+
"""Mixin class which adds a `packages` attribute.
7051
71-
class HasGuid(TypedDict):
72-
"""Has a guid."""
73-
74-
guid: Required[str]
75-
76-
def __init__(self, params: ResourceParameters, **kwargs: Unpack[HasGuid]):
77-
super().__init__(params, **kwargs)
78-
self._guid = kwargs["guid"]
79-
self._packages: Optional[Packages] = None
80-
81-
@property
82-
def packages(self) -> Packages:
83-
"""Get the packages."""
84-
if self._packages:
85-
return self._packages
52+
Parameters
53+
----------
54+
ctx : Context
55+
The context object containing the session and URL for API interactions
56+
path : str
57+
The HTTP path component for the resource endpoint
58+
**attributes : dict
59+
Resource attributes passed
60+
"""
61+
super().__init__(ctx, path, **attributes)
8662

87-
endpoint = self.params.url + f"v1/content/{self._guid}/packages"
88-
self._packages = Packages(self.params, endpoint)
89-
return self._packages
63+
path = posixpath.join(path, "packages")
64+
self.packages = Packages(ctx, path)

src/posit/connect/resources.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import posixpath
22
import warnings
33
from abc import ABC, abstractmethod
4+
from copy import copy
45
from dataclasses import dataclass
56
from typing import Any, Generic, List, Optional, Sequence, TypeVar, overload
67

@@ -81,7 +82,7 @@ class ActiveSequence(ABC, Generic[T], Sequence[T]):
8182

8283
_cache: Optional[List[T]]
8384

84-
def __init__(self, ctx: Context, path: str, uid: str = "guid"):
85+
def __init__(self, ctx: Context, path: str, uid: str = "guid", params: dict = {}):
8586
"""A sequence abstraction for any HTTP GET endpoint that returns a collection.
8687
8788
Parameters
@@ -97,6 +98,7 @@ def __init__(self, ctx: Context, path: str, uid: str = "guid"):
9798
self._ctx = ctx
9899
self._path = path
99100
self._uid = uid
101+
self._params = params
100102
self._cache = None
101103

102104
@abstractmethod
@@ -114,7 +116,7 @@ def fetch(self) -> List[T]:
114116
List[T]
115117
"""
116118
endpoint = self._ctx.url + self._path
117-
response = self._ctx.session.get(endpoint)
119+
response = self._ctx.session.get(endpoint, params=self._params)
118120
results = response.json()
119121
return [self._to_instance(result) for result in results]
120122

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[
2+
{
3+
"language": "python",
4+
"name": "posit",
5+
"version": "0.6.0"
6+
}
7+
]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"results": [
3+
{
4+
"language": "python",
5+
"name": "posit",
6+
"version": "0.6.0"
7+
}
8+
],
9+
"current_page": 1,
10+
"total": 1
11+
}

0 commit comments

Comments
 (0)