crossplane-function-sdk-python 0.6.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/.github/workflows/ci.yml +1 -1
- crossplane_function_sdk_python-0.7.0/CODEOWNERS +22 -0
- crossplane_function_sdk_python-0.7.0/OWNERS.md +18 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/PKG-INFO +4 -3
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/__version__.py +1 -1
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/proto/v1/run_function_pb2.py +3 -3
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/proto/v1/run_function_pb2_grpc.py +1 -1
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/proto/v1beta1/run_function_pb2.py +3 -3
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/proto/v1beta1/run_function_pb2_grpc.py +1 -1
- crossplane_function_sdk_python-0.7.0/crossplane/function/py.typed +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/resource.py +5 -9
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/runtime.py +9 -1
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/pyproject.toml +11 -7
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/test_resource.py +82 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/.gitignore +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/LICENSE +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/README.md +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/logging.py +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/proto/v1/run_function.proto +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/proto/v1/run_function_pb2.pyi +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/proto/v1beta1/run_function.proto +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/proto/v1beta1/run_function_pb2.pyi +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/crossplane/function/response.py +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/renovate.json +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/test_response.py +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/test_runtime.py +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/testdata/models/io/k8s/apimachinery/pkg/apis/__init__.py +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/testdata/models/io/k8s/apimachinery/pkg/apis/meta/__init__.py +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/testdata/models/io/k8s/apimachinery/pkg/apis/meta/v1.py +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/testdata/models/io/upbound/aws/s3/__init__.py +0 -0
- {crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/testdata/models/io/upbound/aws/s3/v1beta2.py +0 -0
|
@@ -120,7 +120,7 @@ jobs:
|
|
|
120
120
|
path: "dist"
|
|
121
121
|
|
|
122
122
|
- name: Publish to PyPI
|
|
123
|
-
uses: pypa/gh-action-pypi-publish@v1.12.
|
|
123
|
+
uses: pypa/gh-action-pypi-publish@v1.12.4
|
|
124
124
|
with:
|
|
125
125
|
# Note that this is currently being pushed to the 'crossplane' PyPI
|
|
126
126
|
# user (not org). See @negz if you need access - PyPI requires 2FA to
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
# SPDX-FileCopyrightText: 2025 The Crossplane Authors <https://crossplane.io>
|
|
3
|
+
#
|
|
4
|
+
# SPDX-License-Identifier: CC0-1.0
|
|
5
|
+
|
|
6
|
+
# This file controls automatic PR reviewer assignment. See the following docs:
|
|
7
|
+
#
|
|
8
|
+
# * https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
|
9
|
+
# * https://docs.github.com/en/organizations/organizing-members-into-teams/managing-code-review-settings-for-your-team
|
|
10
|
+
#
|
|
11
|
+
# The goal of this file is for most PRs to automatically and fairly have one
|
|
12
|
+
# maintainer set as PR reviewers. All maintainers have permission to approve
|
|
13
|
+
# and merge PRs. All PRs must be approved by at least one maintainer before being merged.
|
|
14
|
+
#
|
|
15
|
+
# Where possible, prefer explicitly specifying a maintainer who is a subject
|
|
16
|
+
# matter expert for a particular part of the codebase rather than using fallback
|
|
17
|
+
# owners. Fallback owners are listed at the bottom of this file.
|
|
18
|
+
#
|
|
19
|
+
# See also OWNERS.md for governance details
|
|
20
|
+
|
|
21
|
+
# Fallback owners
|
|
22
|
+
* @negz @bobh66
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2025 The Crossplane Authors <https://crossplane.io>
|
|
3
|
+
|
|
4
|
+
SPDX-License-Identifier: CC-BY-4.0
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# OWNERS
|
|
8
|
+
|
|
9
|
+
This page lists all maintainers for **this** repository. Each repository in the
|
|
10
|
+
[Crossplane Contrib organization](https://github.com/crossplane-contrib/) will list their
|
|
11
|
+
repository maintainers in their own `OWNERS.md` file.
|
|
12
|
+
|
|
13
|
+
## Maintainers
|
|
14
|
+
* Nic Cope <negz@upbound.com> ([negz](https://github.com/negz))
|
|
15
|
+
* Bob Haddleton <bob.haddleton@nokia.com> ([bobh66](https://github.com/bobh66))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
See [CODEOWNERS](./CODEOWNERS) for automatic PR assignment.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crossplane-function-sdk-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: The Python SDK for Crossplane composition functions
|
|
5
5
|
Project-URL: Documentation, https://github.com/crossplane/function-sdk-python#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/crossplane/function-sdk-python/issues
|
|
@@ -11,12 +11,13 @@ License-File: LICENSE
|
|
|
11
11
|
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: Programming Language :: Python
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Typing :: Typed
|
|
14
15
|
Requires-Python: >=3.11
|
|
15
16
|
Requires-Dist: grpcio-reflection==1.*
|
|
16
|
-
Requires-Dist: grpcio==1
|
|
17
|
+
Requires-Dist: grpcio==1.71.0
|
|
17
18
|
Requires-Dist: protobuf==5.29.3
|
|
18
19
|
Requires-Dist: pydantic==2.*
|
|
19
|
-
Requires-Dist: structlog==
|
|
20
|
+
Requires-Dist: structlog==25.*
|
|
20
21
|
Description-Content-Type: text/markdown
|
|
21
22
|
|
|
22
23
|
# function-sdk-python
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
3
|
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
4
|
# source: crossplane/function/proto/v1/run_function.proto
|
|
5
|
-
# Protobuf Python Version: 5.
|
|
5
|
+
# Protobuf Python Version: 5.29.0
|
|
6
6
|
"""Generated protocol buffer code."""
|
|
7
7
|
from google.protobuf import descriptor as _descriptor
|
|
8
8
|
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
@@ -12,8 +12,8 @@ from google.protobuf.internal import builder as _builder
|
|
|
12
12
|
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
13
|
_runtime_version.Domain.PUBLIC,
|
|
14
14
|
5,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
29,
|
|
16
|
+
0,
|
|
17
17
|
'',
|
|
18
18
|
'crossplane/function/proto/v1/run_function.proto'
|
|
19
19
|
)
|
|
@@ -5,7 +5,7 @@ import warnings
|
|
|
5
5
|
|
|
6
6
|
from crossplane.function.proto.v1 import run_function_pb2 as crossplane_dot_function_dot_proto_dot_v1_dot_run__function__pb2
|
|
7
7
|
|
|
8
|
-
GRPC_GENERATED_VERSION = '1.
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.71.0'
|
|
9
9
|
GRPC_VERSION = grpc.__version__
|
|
10
10
|
_version_not_supported = False
|
|
11
11
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
3
|
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
4
|
# source: crossplane/function/proto/v1beta1/run_function.proto
|
|
5
|
-
# Protobuf Python Version: 5.
|
|
5
|
+
# Protobuf Python Version: 5.29.0
|
|
6
6
|
"""Generated protocol buffer code."""
|
|
7
7
|
from google.protobuf import descriptor as _descriptor
|
|
8
8
|
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
@@ -12,8 +12,8 @@ from google.protobuf.internal import builder as _builder
|
|
|
12
12
|
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
13
|
_runtime_version.Domain.PUBLIC,
|
|
14
14
|
5,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
29,
|
|
16
|
+
0,
|
|
17
17
|
'',
|
|
18
18
|
'crossplane/function/proto/v1beta1/run_function.proto'
|
|
19
19
|
)
|
|
@@ -5,7 +5,7 @@ import warnings
|
|
|
5
5
|
|
|
6
6
|
from crossplane.function.proto.v1beta1 import run_function_pb2 as crossplane_dot_function_dot_proto_dot_v1beta1_dot_run__function__pb2
|
|
7
7
|
|
|
8
|
-
GRPC_GENERATED_VERSION = '1.
|
|
8
|
+
GRPC_GENERATED_VERSION = '1.71.0'
|
|
9
9
|
GRPC_VERSION = grpc.__version__
|
|
10
10
|
_version_not_supported = False
|
|
11
11
|
|
|
File without changes
|
|
@@ -18,6 +18,7 @@ import dataclasses
|
|
|
18
18
|
import datetime
|
|
19
19
|
|
|
20
20
|
import pydantic
|
|
21
|
+
from google.protobuf import json_format
|
|
21
22
|
from google.protobuf import struct_pb2 as structpb
|
|
22
23
|
|
|
23
24
|
import crossplane.function.proto.v1.run_function_pb2 as fnv1
|
|
@@ -44,8 +45,8 @@ def update(r: fnv1.Resource, source: dict | structpb.Struct | pydantic.BaseModel
|
|
|
44
45
|
# apiVersion is set to its default value 's3.aws.upbound.io/v1beta2'
|
|
45
46
|
# (and not explicitly provided during initialization), it will be
|
|
46
47
|
# excluded from the serialized output.
|
|
47
|
-
data[
|
|
48
|
-
data[
|
|
48
|
+
data["apiVersion"] = source.apiVersion
|
|
49
|
+
data["kind"] = source.kind
|
|
49
50
|
r.resource.update(data)
|
|
50
51
|
case structpb.Struct():
|
|
51
52
|
# TODO(negz): Use struct_to_dict and update to match other semantics?
|
|
@@ -65,9 +66,7 @@ def dict_to_struct(d: dict) -> structpb.Struct:
|
|
|
65
66
|
function makes it possible to work with a Python dict, then convert it to a
|
|
66
67
|
struct in a RunFunctionResponse.
|
|
67
68
|
"""
|
|
68
|
-
|
|
69
|
-
s.update(d)
|
|
70
|
-
return s
|
|
69
|
+
return json_format.ParseDict(d, structpb.Struct())
|
|
71
70
|
|
|
72
71
|
|
|
73
72
|
def struct_to_dict(s: structpb.Struct) -> dict:
|
|
@@ -77,10 +76,7 @@ def struct_to_dict(s: structpb.Struct) -> dict:
|
|
|
77
76
|
protobuf struct. This function makes it possible to convert resources to a
|
|
78
77
|
dictionary.
|
|
79
78
|
"""
|
|
80
|
-
return
|
|
81
|
-
k: (struct_to_dict(v) if isinstance(v, structpb.Struct) else v)
|
|
82
|
-
for k, v in s.items()
|
|
83
|
-
}
|
|
79
|
+
return json_format.MessageToDict(s, preserving_proto_field_name=True)
|
|
84
80
|
|
|
85
81
|
|
|
86
82
|
@dataclasses.dataclass
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import asyncio
|
|
18
18
|
import os
|
|
19
|
+
import signal
|
|
19
20
|
|
|
20
21
|
import grpc
|
|
21
22
|
from grpc_reflection.v1alpha import reflection
|
|
@@ -31,6 +32,8 @@ SERVICE_NAMES = (
|
|
|
31
32
|
fnv1beta1.DESCRIPTOR.services_by_name["FunctionRunnerService"].full_name,
|
|
32
33
|
)
|
|
33
34
|
|
|
35
|
+
SHUTDOWN_GRACE_PERIOD_SECONDS = 5
|
|
36
|
+
|
|
34
37
|
|
|
35
38
|
def load_credentials(tls_certs_dir: str) -> grpc.ServerCredentials:
|
|
36
39
|
"""Load TLS credentials for a composition function gRPC server.
|
|
@@ -90,6 +93,11 @@ def serve(
|
|
|
90
93
|
|
|
91
94
|
server = grpc.aio.server()
|
|
92
95
|
|
|
96
|
+
loop.add_signal_handler(
|
|
97
|
+
signal.SIGTERM,
|
|
98
|
+
lambda: asyncio.ensure_future(server.stop(grace=SHUTDOWN_GRACE_PERIOD_SECONDS)),
|
|
99
|
+
)
|
|
100
|
+
|
|
93
101
|
grpcv1.add_FunctionRunnerServiceServicer_to_server(function, server)
|
|
94
102
|
grpcv1beta1.add_FunctionRunnerServiceServicer_to_server(
|
|
95
103
|
BetaFunctionRunner(wrapped=function), server
|
|
@@ -116,7 +124,7 @@ def serve(
|
|
|
116
124
|
try:
|
|
117
125
|
loop.run_until_complete(start())
|
|
118
126
|
finally:
|
|
119
|
-
loop.run_until_complete(server.stop(grace=
|
|
127
|
+
loop.run_until_complete(server.stop(grace=SHUTDOWN_GRACE_PERIOD_SECONDS))
|
|
120
128
|
loop.close()
|
|
121
129
|
|
|
122
130
|
|
{crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/pyproject.toml
RENAMED
|
@@ -14,14 +14,15 @@ classifiers = [
|
|
|
14
14
|
"Development Status :: 4 - Beta",
|
|
15
15
|
"Programming Language :: Python",
|
|
16
16
|
"Programming Language :: Python :: 3.11",
|
|
17
|
+
"Typing :: Typed",
|
|
17
18
|
]
|
|
18
19
|
|
|
19
20
|
dependencies = [
|
|
20
|
-
"grpcio==1
|
|
21
|
+
"grpcio==1.71.0",
|
|
21
22
|
"grpcio-reflection==1.*",
|
|
22
|
-
"protobuf==5.29.3",
|
|
23
|
+
"protobuf==5.29.3", # Must be compatible with grpcio-tools.
|
|
23
24
|
"pydantic==2.*",
|
|
24
|
-
"structlog==
|
|
25
|
+
"structlog==25.*",
|
|
25
26
|
]
|
|
26
27
|
|
|
27
28
|
dynamic = ["version"]
|
|
@@ -38,13 +39,16 @@ validate-bump = false # Allow going from 0.0.0.dev0+x to 0
|
|
|
38
39
|
[tool.hatch.envs.default]
|
|
39
40
|
type = "virtual"
|
|
40
41
|
path = ".venv-default"
|
|
41
|
-
dependencies = ["ipython==
|
|
42
|
+
dependencies = ["ipython==9.1.0"]
|
|
42
43
|
|
|
43
44
|
[tool.hatch.envs.generate]
|
|
44
45
|
type = "virtual"
|
|
45
46
|
detached = true
|
|
46
47
|
path = ".venv-generate"
|
|
47
|
-
dependencies = [
|
|
48
|
+
dependencies = [
|
|
49
|
+
"grpcio-tools==1.71.0",
|
|
50
|
+
"protobuf==5.29.3",
|
|
51
|
+
]
|
|
48
52
|
|
|
49
53
|
[tool.hatch.envs.generate.scripts]
|
|
50
54
|
protoc = "python -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=. --grpc_python_out=. crossplane/function/proto/v1beta1/run_function.proto crossplane/function/proto/v1/run_function.proto"
|
|
@@ -62,8 +66,8 @@ packages = ["crossplane"]
|
|
|
62
66
|
|
|
63
67
|
# This special environment is used by hatch fmt.
|
|
64
68
|
[tool.hatch.envs.hatch-static-analysis]
|
|
65
|
-
dependencies = ["ruff==0.
|
|
66
|
-
config-path = "none"
|
|
69
|
+
dependencies = ["ruff==0.11.6"]
|
|
70
|
+
config-path = "none" # Disable Hatch's default Ruff config.
|
|
67
71
|
|
|
68
72
|
[tool.ruff]
|
|
69
73
|
target-version = "py311"
|
{crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/test_resource.py
RENAMED
|
@@ -248,6 +248,66 @@ class TestResource(unittest.TestCase):
|
|
|
248
248
|
dataclasses.asdict(case.want), dataclasses.asdict(got), "-want, +got"
|
|
249
249
|
)
|
|
250
250
|
|
|
251
|
+
def test_dict_to_struct(self) -> None:
|
|
252
|
+
@dataclasses.dataclass
|
|
253
|
+
class TestCase:
|
|
254
|
+
reason: str
|
|
255
|
+
d: dict
|
|
256
|
+
want: structpb.Struct
|
|
257
|
+
|
|
258
|
+
cases = [
|
|
259
|
+
TestCase(
|
|
260
|
+
reason="Convert an empty dictionary to a struct.",
|
|
261
|
+
d={},
|
|
262
|
+
want=structpb.Struct(),
|
|
263
|
+
),
|
|
264
|
+
TestCase(
|
|
265
|
+
reason="Convert a dictionary with a single field to a struct.",
|
|
266
|
+
d={"foo": "bar"},
|
|
267
|
+
want=structpb.Struct(
|
|
268
|
+
fields={"foo": structpb.Value(string_value="bar")}
|
|
269
|
+
),
|
|
270
|
+
),
|
|
271
|
+
TestCase(
|
|
272
|
+
reason="Convert a nested dictionary to a struct.",
|
|
273
|
+
d={"foo": {"bar": "baz"}},
|
|
274
|
+
want=structpb.Struct(
|
|
275
|
+
fields={
|
|
276
|
+
"foo": structpb.Value(
|
|
277
|
+
struct_value=structpb.Struct(
|
|
278
|
+
fields={"bar": structpb.Value(string_value="baz")}
|
|
279
|
+
)
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
),
|
|
283
|
+
),
|
|
284
|
+
TestCase(
|
|
285
|
+
reason="Convert a nested dictionary containing lists to a struct.",
|
|
286
|
+
d={"foo": {"bar": ["baz", "qux"]}},
|
|
287
|
+
want=structpb.Struct(
|
|
288
|
+
fields={
|
|
289
|
+
"foo": structpb.Value(
|
|
290
|
+
struct_value=structpb.Struct(
|
|
291
|
+
fields={
|
|
292
|
+
"bar": structpb.Value(
|
|
293
|
+
list_value=structpb.ListValue(
|
|
294
|
+
values=[
|
|
295
|
+
structpb.Value(string_value="baz"),
|
|
296
|
+
structpb.Value(string_value="qux"),
|
|
297
|
+
]
|
|
298
|
+
)
|
|
299
|
+
)
|
|
300
|
+
}
|
|
301
|
+
)
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
),
|
|
305
|
+
),
|
|
306
|
+
]
|
|
307
|
+
for case in cases:
|
|
308
|
+
got = resource.dict_to_struct(case.d)
|
|
309
|
+
self.assertEqual(case.want, got, "-want, +got")
|
|
310
|
+
|
|
251
311
|
def test_struct_to_dict(self) -> None:
|
|
252
312
|
@dataclasses.dataclass
|
|
253
313
|
class TestCase:
|
|
@@ -279,6 +339,28 @@ class TestResource(unittest.TestCase):
|
|
|
279
339
|
),
|
|
280
340
|
want={"foo": {"bar": "baz"}},
|
|
281
341
|
),
|
|
342
|
+
TestCase(
|
|
343
|
+
reason="Convert a nested struct containing ListValues to a dictionary.",
|
|
344
|
+
s=structpb.Struct(
|
|
345
|
+
fields={
|
|
346
|
+
"foo": structpb.Value(
|
|
347
|
+
struct_value=structpb.Struct(
|
|
348
|
+
fields={
|
|
349
|
+
"bar": structpb.Value(
|
|
350
|
+
list_value=structpb.ListValue(
|
|
351
|
+
values=[
|
|
352
|
+
structpb.Value(string_value="baz"),
|
|
353
|
+
structpb.Value(string_value="qux"),
|
|
354
|
+
]
|
|
355
|
+
)
|
|
356
|
+
)
|
|
357
|
+
}
|
|
358
|
+
)
|
|
359
|
+
)
|
|
360
|
+
}
|
|
361
|
+
),
|
|
362
|
+
want={"foo": {"bar": ["baz", "qux"]}},
|
|
363
|
+
),
|
|
282
364
|
]
|
|
283
365
|
|
|
284
366
|
for case in cases:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/test_response.py
RENAMED
|
File without changes
|
{crossplane_function_sdk_python-0.6.0 → crossplane_function_sdk_python-0.7.0}/tests/test_runtime.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|