Skip to content

Commit 32559ab

Browse files
author
Patrick J. McNerthney
committed
Allow for multiple function-pythonic steps in a single composition.
1 parent 4c459f8 commit 32559ab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+939
-337
lines changed

.devcontainer/devcontainer.json

Lines changed: 0 additions & 17 deletions
This file was deleted.

.github/workflows/ci.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ on:
1515
env:
1616
# Common versions
1717
PYTHON_VERSION: '3.13.7' # TODO: Used?
18-
HATCH_VERSION: '1.12.0'
18+
HATCH_VERSION: '1.14.2'
1919
DOCKER_BUILDX_VERSION: 'v0.26.1'
2020

2121
# These environment variables are important to the Crossplane CLI install.sh
@@ -52,7 +52,7 @@ jobs:
5252
# python-version: ${{ env.PYTHON_VERSION }}
5353

5454
# - name: Setup Hatch
55-
# run: pipx install hatch==1.14.1
55+
# run: pipx install hatch==${{ env.HATCH_VERSION }}
5656

5757
# - name: Lint
5858
# run: hatch run lint:check
@@ -69,7 +69,7 @@ jobs:
6969
python-version: ${{ env.PYTHON_VERSION }}
7070

7171
- name: Setup Hatch
72-
run: pipx install hatch==1.14.1
72+
run: pipx install hatch==${{ env.HATCH_VERSION }}
7373

7474
- name: Run Unit Tests
7575
run: hatch run test:ci

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,4 @@ __marimo__/
214214
crossplane/pythonic/__version__.py
215215
pocs/
216216
pythonic-packages/
217+
tests/protobuf/pytest_pb2*

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"python.analysis.typeCheckingMode": "off"
3+
}

crossplane/pythonic/composite.py

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
import datetime
3+
from google.protobuf.duration_pb2 import Duration
34
from crossplane.function.proto.v1 import run_function_pb2 as fnv1
45

56
from . import protobuf
@@ -9,8 +10,18 @@
910

1011

1112
class BaseComposite:
12-
def __init__(self, request, response, logger):
13+
def __init__(self, request, logger):
1314
self.request = protobuf.Message(None, 'request', request.DESCRIPTOR, request, 'Function Request')
15+
response = fnv1.RunFunctionResponse(
16+
meta=fnv1.ResponseMeta(
17+
tag=request.meta.tag,
18+
ttl=Duration(
19+
seconds=60,
20+
),
21+
),
22+
desired=request.desired,
23+
context=request.context,
24+
)
1425
self.response = protobuf.Message(None, 'response', response.DESCRIPTOR, response)
1526
self.logger = logger
1627
self.credentials = Credentials(self.request)
@@ -36,11 +47,23 @@ def __init__(self, request, response, logger):
3647

3748
@property
3849
def ttl(self):
50+
if self.response.meta.ttl.nanos:
51+
return float(self.response.meta.ttl.seconds) + (float(self.response.meta.ttl.nanos) / 1000000000.0)
3952
return self.response.meta.ttl.seconds
4053

4154
@ttl.setter
4255
def ttl(self, ttl):
43-
self.response.meta.ttl.seconds = ttl
56+
if isinstance(ttl, int):
57+
self.response.meta.ttl.seconds = ttl
58+
self.response.meta.ttl.nanos = 0
59+
elif isinstance(ttl, float):
60+
self.response.meta.ttl.seconds = int(ttl)
61+
if ttl.is_integer():
62+
self.response.meta.ttl.nanos = 0
63+
else:
64+
self.response.meta.ttl.nanos = int((ttl - self.response.meta.ttl.seconds) * 1000000000)
65+
else:
66+
raise ValueError('ttl must be an int or float')
4467

4568
@property
4669
def ready(self):
@@ -73,22 +96,46 @@ def __getattr__(self, key):
7396
return self[key]
7497

7598
def __getitem__(self, key):
76-
return self._request.credentials[key].credentials_data.data
99+
return Credential(self._request.credentials[key])
77100

78101
def __bool__(self):
79-
return bool(_request.credentials)
102+
return bool(self._request.credentials)
80103

81104
def __len__(self):
82105
return len(self._request.credentials)
83106

84107
def __contains__(self, key):
85-
return key in _request.credentials
108+
return key in self._request.credentials
86109

87110
def __iter__(self):
88111
for key, resource in self._request.credentials:
89112
yield key, self[key]
90113

91114

115+
class Credential:
116+
def __init__(self, credential):
117+
self.__dict__['_credential'] = credential
118+
119+
def __getattr__(self, key):
120+
return self[key]
121+
122+
def __getitem__(self, key):
123+
return self._credential.credential_data.data[key]
124+
125+
def __bool__(self):
126+
return bool(self._credential.credential_data.data)
127+
128+
def __len__(self):
129+
return len(self._credential.credential_data.data)
130+
131+
def __contains__(self, key):
132+
return key in self._credential.credential_data.data
133+
134+
def __iter__(self):
135+
for key, resource in self._credential.credential_data.data:
136+
yield key, self[key]
137+
138+
92139
class Resources:
93140
def __init__(self, composite):
94141
self.__dict__['_composite'] = composite
@@ -587,7 +634,7 @@ def __len__(self):
587634
def __getitem__(self, key):
588635
if key >= len(self._results):
589636
return Event()
590-
return Event(self._results[ix])
637+
return Event(self._results[key])
591638

592639
def __iter__(self):
593640
for ix in range(len(self._results)):

0 commit comments

Comments
 (0)