crossplane-function-sdk-python 0.2.0__tar.gz → 0.3.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.
Files changed (22) hide show
  1. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/.github/workflows/ci.yml +2 -2
  2. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/PKG-INFO +2 -2
  3. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/__version__.py +1 -1
  4. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/proto/v1beta1/run_function.proto +19 -1
  5. crossplane_function_sdk_python-0.3.0/crossplane/function/proto/v1beta1/run_function_pb2.py +86 -0
  6. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/proto/v1beta1/run_function_pb2.pyi +30 -2
  7. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/resource.py +21 -0
  8. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/runtime.py +3 -1
  9. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/pyproject.toml +6 -6
  10. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/tests/test_resource.py +43 -0
  11. crossplane_function_sdk_python-0.2.0/crossplane/function/proto/v1beta1/run_function_pb2.py +0 -74
  12. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  13. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  14. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  15. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/.gitignore +0 -0
  16. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/LICENSE +0 -0
  17. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/README.md +0 -0
  18. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/logging.py +0 -0
  19. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/proto/v1beta1/run_function_pb2_grpc.py +0 -0
  20. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/response.py +0 -0
  21. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/renovate.json +0 -0
  22. {crossplane_function_sdk_python-0.2.0 → crossplane_function_sdk_python-0.3.0}/tests/test_response.py +0 -0
@@ -119,7 +119,7 @@ jobs:
119
119
  path: "dist"
120
120
 
121
121
  - name: Publish to PyPI
122
- uses: pypa/gh-action-pypi-publish@v1.8.11
122
+ uses: pypa/gh-action-pypi-publish@v1.9.0
123
123
  with:
124
124
  # Note that this is currently being pushed to the 'crossplane' PyPI
125
125
  # user (not org). See @negz if you need access - PyPI requires 2FA to
@@ -149,7 +149,7 @@ jobs:
149
149
  run: hatch run docs:pdoc -d google crossplane/function -o docs
150
150
 
151
151
  - name: Setup Pages
152
- uses: actions/configure-pages@v4
152
+ uses: actions/configure-pages@v5
153
153
 
154
154
  - name: Upload artifact
155
155
  uses: actions/upload-pages-artifact@v3
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: crossplane-function-sdk-python
3
- Version: 0.2.0
3
+ Version: 0.3.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
@@ -15,4 +15,4 @@
15
15
  """The version of function-sdk-python."""
16
16
 
17
17
  # This is set at build time, using "hatch version"
18
- __version__ = "0.2.0"
18
+ __version__ = "0.3.0"
@@ -69,6 +69,24 @@ message RunFunctionRequest {
69
69
  // did not exist, Crossplane sets the map key to an empty Resources message to
70
70
  // indicate that it attempted to satisfy the request.
71
71
  map<string, Resources> extra_resources = 6;
72
+
73
+ // Optional credentials that this Function may use to communicate with an
74
+ // external system.
75
+ map <string, Credentials> credentials = 7;
76
+ }
77
+
78
+ // Credentials that a Function may use to communicate with an external system.
79
+ message Credentials {
80
+ // Source of the credentials.
81
+ oneof source {
82
+ // Credential data loaded by Crossplane, for example from a Secret.
83
+ CredentialData credential_data = 1;
84
+ }
85
+ }
86
+
87
+ // CredentialData loaded by Crossplane, for example from a Secret.
88
+ message CredentialData {
89
+ map<string, bytes> data = 1;
72
90
  }
73
91
 
74
92
  // Resources represents the state of several Crossplane resources.
@@ -238,4 +256,4 @@ enum Severity {
238
256
  // Normal results are emitted as normal events and debug logs associated
239
257
  // with the composite resource.
240
258
  SEVERITY_NORMAL = 3;
241
- }
259
+ }
@@ -0,0 +1,86 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: crossplane/function/proto/v1beta1/run_function.proto
4
+ # Protobuf Python Version: 4.25.1
5
+ """Generated protocol buffer code."""
6
+ from google.protobuf import descriptor as _descriptor
7
+ from google.protobuf import descriptor_pool as _descriptor_pool
8
+ from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
10
+ # @@protoc_insertion_point(imports)
11
+
12
+ _sym_db = _symbol_database.Default()
13
+
14
+
15
+ from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
16
+ from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
17
+
18
+
19
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n4crossplane/function/proto/v1beta1/run_function.proto\x12\x1e\x61piextensions.fn.proto.v1beta1\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1egoogle/protobuf/duration.proto\"\xb0\x05\n\x12RunFunctionRequest\x12\x39\n\x04meta\x18\x01 \x01(\x0b\x32+.apiextensions.fn.proto.v1beta1.RequestMeta\x12\x37\n\x08observed\x18\x02 \x01(\x0b\x32%.apiextensions.fn.proto.v1beta1.State\x12\x36\n\x07\x64\x65sired\x18\x03 \x01(\x0b\x32%.apiextensions.fn.proto.v1beta1.State\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x88\x01\x01\x12-\n\x07\x63ontext\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x01\x88\x01\x01\x12_\n\x0f\x65xtra_resources\x18\x06 \x03(\x0b\x32\x46.apiextensions.fn.proto.v1beta1.RunFunctionRequest.ExtraResourcesEntry\x12X\n\x0b\x63redentials\x18\x07 \x03(\x0b\x32\x43.apiextensions.fn.proto.v1beta1.RunFunctionRequest.CredentialsEntry\x1a`\n\x13\x45xtraResourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x01(\x0b\x32).apiextensions.fn.proto.v1beta1.Resources:\x02\x38\x01\x1a_\n\x10\x43redentialsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12:\n\x05value\x18\x02 \x01(\x0b\x32+.apiextensions.fn.proto.v1beta1.Credentials:\x02\x38\x01\x42\x08\n\x06_inputB\n\n\x08_context\"b\n\x0b\x43redentials\x12I\n\x0f\x63redential_data\x18\x01 \x01(\x0b\x32..apiextensions.fn.proto.v1beta1.CredentialDataH\x00\x42\x08\n\x06source\"\x85\x01\n\x0e\x43redentialData\x12\x46\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32\x38.apiextensions.fn.proto.v1beta1.CredentialData.DataEntry\x1a+\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"D\n\tResources\x12\x37\n\x05items\x18\x01 \x03(\x0b\x32(.apiextensions.fn.proto.v1beta1.Resource\"\xc1\x02\n\x13RunFunctionResponse\x12:\n\x04meta\x18\x01 \x01(\x0b\x32,.apiextensions.fn.proto.v1beta1.ResponseMeta\x12\x36\n\x07\x64\x65sired\x18\x02 \x01(\x0b\x32%.apiextensions.fn.proto.v1beta1.State\x12\x37\n\x07results\x18\x03 \x03(\x0b\x32&.apiextensions.fn.proto.v1beta1.Result\x12-\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x88\x01\x01\x12\x42\n\x0crequirements\x18\x05 \x01(\x0b\x32,.apiextensions.fn.proto.v1beta1.RequirementsB\n\n\x08_context\"\x1a\n\x0bRequestMeta\x12\x0b\n\x03tag\x18\x01 \x01(\t\"\xd2\x01\n\x0cRequirements\x12Y\n\x0f\x65xtra_resources\x18\x01 \x03(\x0b\x32@.apiextensions.fn.proto.v1beta1.Requirements.ExtraResourcesEntry\x1ag\n\x13\x45xtraResourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12?\n\x05value\x18\x02 \x01(\x0b\x32\x30.apiextensions.fn.proto.v1beta1.ResourceSelector:\x02\x38\x01\"\x99\x01\n\x10ResourceSelector\x12\x13\n\x0b\x61pi_version\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\x14\n\nmatch_name\x18\x03 \x01(\tH\x00\x12\x43\n\x0cmatch_labels\x18\x04 \x01(\x0b\x32+.apiextensions.fn.proto.v1beta1.MatchLabelsH\x00\x42\x07\n\x05match\"\x85\x01\n\x0bMatchLabels\x12G\n\x06labels\x18\x01 \x03(\x0b\x32\x37.apiextensions.fn.proto.v1beta1.MatchLabels.LabelsEntry\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"P\n\x0cResponseMeta\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12+\n\x03ttl\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x88\x01\x01\x42\x06\n\x04_ttl\"\xe9\x01\n\x05State\x12;\n\tcomposite\x18\x01 \x01(\x0b\x32(.apiextensions.fn.proto.v1beta1.Resource\x12G\n\tresources\x18\x02 \x03(\x0b\x32\x34.apiextensions.fn.proto.v1beta1.State.ResourcesEntry\x1aZ\n\x0eResourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x37\n\x05value\x18\x02 \x01(\x0b\x32(.apiextensions.fn.proto.v1beta1.Resource:\x02\x38\x01\"\x82\x02\n\x08Resource\x12)\n\x08resource\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12[\n\x12\x63onnection_details\x18\x02 \x03(\x0b\x32?.apiextensions.fn.proto.v1beta1.Resource.ConnectionDetailsEntry\x12\x34\n\x05ready\x18\x03 \x01(\x0e\x32%.apiextensions.fn.proto.v1beta1.Ready\x1a\x38\n\x16\x43onnectionDetailsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"U\n\x06Result\x12:\n\x08severity\x18\x01 \x01(\x0e\x32(.apiextensions.fn.proto.v1beta1.Severity\x12\x0f\n\x07message\x18\x02 \x01(\t*?\n\x05Ready\x12\x15\n\x11READY_UNSPECIFIED\x10\x00\x12\x0e\n\nREADY_TRUE\x10\x01\x12\x0f\n\x0bREADY_FALSE\x10\x02*c\n\x08Severity\x12\x18\n\x14SEVERITY_UNSPECIFIED\x10\x00\x12\x12\n\x0eSEVERITY_FATAL\x10\x01\x12\x14\n\x10SEVERITY_WARNING\x10\x02\x12\x13\n\x0fSEVERITY_NORMAL\x10\x03\x32\x91\x01\n\x15\x46unctionRunnerService\x12x\n\x0bRunFunction\x12\x32.apiextensions.fn.proto.v1beta1.RunFunctionRequest\x1a\x33.apiextensions.fn.proto.v1beta1.RunFunctionResponse\"\x00\x62\x06proto3')
20
+
21
+ _globals = globals()
22
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
23
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'crossplane.function.proto.v1beta1.run_function_pb2', _globals)
24
+ if _descriptor._USE_C_DESCRIPTORS == False:
25
+ DESCRIPTOR._options = None
26
+ _globals['_RUNFUNCTIONREQUEST_EXTRARESOURCESENTRY']._options = None
27
+ _globals['_RUNFUNCTIONREQUEST_EXTRARESOURCESENTRY']._serialized_options = b'8\001'
28
+ _globals['_RUNFUNCTIONREQUEST_CREDENTIALSENTRY']._options = None
29
+ _globals['_RUNFUNCTIONREQUEST_CREDENTIALSENTRY']._serialized_options = b'8\001'
30
+ _globals['_CREDENTIALDATA_DATAENTRY']._options = None
31
+ _globals['_CREDENTIALDATA_DATAENTRY']._serialized_options = b'8\001'
32
+ _globals['_REQUIREMENTS_EXTRARESOURCESENTRY']._options = None
33
+ _globals['_REQUIREMENTS_EXTRARESOURCESENTRY']._serialized_options = b'8\001'
34
+ _globals['_MATCHLABELS_LABELSENTRY']._options = None
35
+ _globals['_MATCHLABELS_LABELSENTRY']._serialized_options = b'8\001'
36
+ _globals['_STATE_RESOURCESENTRY']._options = None
37
+ _globals['_STATE_RESOURCESENTRY']._serialized_options = b'8\001'
38
+ _globals['_RESOURCE_CONNECTIONDETAILSENTRY']._options = None
39
+ _globals['_RESOURCE_CONNECTIONDETAILSENTRY']._serialized_options = b'8\001'
40
+ _globals['_READY']._serialized_start=2670
41
+ _globals['_READY']._serialized_end=2733
42
+ _globals['_SEVERITY']._serialized_start=2735
43
+ _globals['_SEVERITY']._serialized_end=2834
44
+ _globals['_RUNFUNCTIONREQUEST']._serialized_start=151
45
+ _globals['_RUNFUNCTIONREQUEST']._serialized_end=839
46
+ _globals['_RUNFUNCTIONREQUEST_EXTRARESOURCESENTRY']._serialized_start=624
47
+ _globals['_RUNFUNCTIONREQUEST_EXTRARESOURCESENTRY']._serialized_end=720
48
+ _globals['_RUNFUNCTIONREQUEST_CREDENTIALSENTRY']._serialized_start=722
49
+ _globals['_RUNFUNCTIONREQUEST_CREDENTIALSENTRY']._serialized_end=817
50
+ _globals['_CREDENTIALS']._serialized_start=841
51
+ _globals['_CREDENTIALS']._serialized_end=939
52
+ _globals['_CREDENTIALDATA']._serialized_start=942
53
+ _globals['_CREDENTIALDATA']._serialized_end=1075
54
+ _globals['_CREDENTIALDATA_DATAENTRY']._serialized_start=1032
55
+ _globals['_CREDENTIALDATA_DATAENTRY']._serialized_end=1075
56
+ _globals['_RESOURCES']._serialized_start=1077
57
+ _globals['_RESOURCES']._serialized_end=1145
58
+ _globals['_RUNFUNCTIONRESPONSE']._serialized_start=1148
59
+ _globals['_RUNFUNCTIONRESPONSE']._serialized_end=1469
60
+ _globals['_REQUESTMETA']._serialized_start=1471
61
+ _globals['_REQUESTMETA']._serialized_end=1497
62
+ _globals['_REQUIREMENTS']._serialized_start=1500
63
+ _globals['_REQUIREMENTS']._serialized_end=1710
64
+ _globals['_REQUIREMENTS_EXTRARESOURCESENTRY']._serialized_start=1607
65
+ _globals['_REQUIREMENTS_EXTRARESOURCESENTRY']._serialized_end=1710
66
+ _globals['_RESOURCESELECTOR']._serialized_start=1713
67
+ _globals['_RESOURCESELECTOR']._serialized_end=1866
68
+ _globals['_MATCHLABELS']._serialized_start=1869
69
+ _globals['_MATCHLABELS']._serialized_end=2002
70
+ _globals['_MATCHLABELS_LABELSENTRY']._serialized_start=1957
71
+ _globals['_MATCHLABELS_LABELSENTRY']._serialized_end=2002
72
+ _globals['_RESPONSEMETA']._serialized_start=2004
73
+ _globals['_RESPONSEMETA']._serialized_end=2084
74
+ _globals['_STATE']._serialized_start=2087
75
+ _globals['_STATE']._serialized_end=2320
76
+ _globals['_STATE_RESOURCESENTRY']._serialized_start=2230
77
+ _globals['_STATE_RESOURCESENTRY']._serialized_end=2320
78
+ _globals['_RESOURCE']._serialized_start=2323
79
+ _globals['_RESOURCE']._serialized_end=2581
80
+ _globals['_RESOURCE_CONNECTIONDETAILSENTRY']._serialized_start=2525
81
+ _globals['_RESOURCE_CONNECTIONDETAILSENTRY']._serialized_end=2581
82
+ _globals['_RESULT']._serialized_start=2583
83
+ _globals['_RESULT']._serialized_end=2668
84
+ _globals['_FUNCTIONRUNNERSERVICE']._serialized_start=2837
85
+ _globals['_FUNCTIONRUNNERSERVICE']._serialized_end=2982
86
+ # @@protoc_insertion_point(module_scope)
@@ -29,7 +29,7 @@ SEVERITY_WARNING: Severity
29
29
  SEVERITY_NORMAL: Severity
30
30
 
31
31
  class RunFunctionRequest(_message.Message):
32
- __slots__ = ("meta", "observed", "desired", "input", "context", "extra_resources")
32
+ __slots__ = ("meta", "observed", "desired", "input", "context", "extra_resources", "credentials")
33
33
  class ExtraResourcesEntry(_message.Message):
34
34
  __slots__ = ("key", "value")
35
35
  KEY_FIELD_NUMBER: _ClassVar[int]
@@ -37,19 +37,47 @@ class RunFunctionRequest(_message.Message):
37
37
  key: str
38
38
  value: Resources
39
39
  def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Resources, _Mapping]] = ...) -> None: ...
40
+ class CredentialsEntry(_message.Message):
41
+ __slots__ = ("key", "value")
42
+ KEY_FIELD_NUMBER: _ClassVar[int]
43
+ VALUE_FIELD_NUMBER: _ClassVar[int]
44
+ key: str
45
+ value: Credentials
46
+ def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Credentials, _Mapping]] = ...) -> None: ...
40
47
  META_FIELD_NUMBER: _ClassVar[int]
41
48
  OBSERVED_FIELD_NUMBER: _ClassVar[int]
42
49
  DESIRED_FIELD_NUMBER: _ClassVar[int]
43
50
  INPUT_FIELD_NUMBER: _ClassVar[int]
44
51
  CONTEXT_FIELD_NUMBER: _ClassVar[int]
45
52
  EXTRA_RESOURCES_FIELD_NUMBER: _ClassVar[int]
53
+ CREDENTIALS_FIELD_NUMBER: _ClassVar[int]
46
54
  meta: RequestMeta
47
55
  observed: State
48
56
  desired: State
49
57
  input: _struct_pb2.Struct
50
58
  context: _struct_pb2.Struct
51
59
  extra_resources: _containers.MessageMap[str, Resources]
52
- def __init__(self, meta: _Optional[_Union[RequestMeta, _Mapping]] = ..., observed: _Optional[_Union[State, _Mapping]] = ..., desired: _Optional[_Union[State, _Mapping]] = ..., input: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., context: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., extra_resources: _Optional[_Mapping[str, Resources]] = ...) -> None: ...
60
+ credentials: _containers.MessageMap[str, Credentials]
61
+ def __init__(self, meta: _Optional[_Union[RequestMeta, _Mapping]] = ..., observed: _Optional[_Union[State, _Mapping]] = ..., desired: _Optional[_Union[State, _Mapping]] = ..., input: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., context: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., extra_resources: _Optional[_Mapping[str, Resources]] = ..., credentials: _Optional[_Mapping[str, Credentials]] = ...) -> None: ...
62
+
63
+ class Credentials(_message.Message):
64
+ __slots__ = ("credential_data",)
65
+ CREDENTIAL_DATA_FIELD_NUMBER: _ClassVar[int]
66
+ credential_data: CredentialData
67
+ def __init__(self, credential_data: _Optional[_Union[CredentialData, _Mapping]] = ...) -> None: ...
68
+
69
+ class CredentialData(_message.Message):
70
+ __slots__ = ("data",)
71
+ class DataEntry(_message.Message):
72
+ __slots__ = ("key", "value")
73
+ KEY_FIELD_NUMBER: _ClassVar[int]
74
+ VALUE_FIELD_NUMBER: _ClassVar[int]
75
+ key: str
76
+ value: bytes
77
+ def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ...
78
+ DATA_FIELD_NUMBER: _ClassVar[int]
79
+ data: _containers.ScalarMap[str, bytes]
80
+ def __init__(self, data: _Optional[_Mapping[str, bytes]] = ...) -> None: ...
53
81
 
54
82
  class Resources(_message.Message):
55
83
  __slots__ = ("items",)
@@ -106,3 +106,24 @@ def get_condition(resource: structpb.Struct, typ: str) -> Condition:
106
106
  return condition
107
107
 
108
108
  return unknown
109
+
110
+
111
+ @dataclasses.dataclass
112
+ class Credentials:
113
+ """Credentials."""
114
+
115
+ type: str
116
+ data: dict
117
+
118
+
119
+ def get_credentials(req: structpb.Struct, name: str) -> Credentials:
120
+ """Get the supplied credentials."""
121
+ empty = Credentials(type="data", data={})
122
+ if "credentials" not in req:
123
+ return empty
124
+ if name not in req["credentials"]:
125
+ return empty
126
+ return Credentials(
127
+ type=req["credentials"][name]["type"],
128
+ data=struct_to_dict(req["credentials"][name]["data"]),
129
+ )
@@ -82,6 +82,9 @@ def serve(
82
82
  If insecure is true requests will be served insecurely, even if credentials
83
83
  are supplied.
84
84
  """
85
+ # Define the loop before the server so everything uses the same loop.
86
+ loop = asyncio.get_event_loop()
87
+
85
88
  server = grpc.aio.server()
86
89
 
87
90
  grpcv1beta1.add_FunctionRunnerServiceServicer_to_server(function, server)
@@ -104,7 +107,6 @@ def serve(
104
107
  await server.start()
105
108
  await server.wait_for_termination()
106
109
 
107
- loop = asyncio.get_event_loop()
108
110
  try:
109
111
  loop.run_until_complete(start())
110
112
  finally:
@@ -32,13 +32,13 @@ validate-bump = false # Allow going from 0.0.0.dev0+x to 0
32
32
  [tool.hatch.envs.default]
33
33
  type = "virtual"
34
34
  path = ".venv-default"
35
- dependencies = ["ipython==8.21.0"]
35
+ dependencies = ["ipython==8.26.0"]
36
36
 
37
37
  [tool.hatch.envs.generate]
38
38
  type = "virtual"
39
39
  detached = true
40
40
  path = ".venv-generate"
41
- dependencies = ["grpcio-tools==1.60.1"]
41
+ dependencies = ["grpcio-tools==1.65.4"]
42
42
 
43
43
  [tool.hatch.envs.generate.scripts]
44
44
  protoc = "python -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=. --grpc_python_out=. crossplane/function/proto/v1beta1/run_function.proto"
@@ -47,7 +47,7 @@ protoc = "python -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=.
47
47
  type = "virtual"
48
48
  detached = true
49
49
  path = ".venv-lint"
50
- dependencies = ["ruff==0.2.2"]
50
+ dependencies = ["ruff==0.5.7"]
51
51
 
52
52
  [tool.hatch.envs.lint.scripts]
53
53
  check = "ruff check crossplane tests && ruff format --diff crossplane tests"
@@ -73,7 +73,7 @@ packages = ["crossplane"]
73
73
  [tool.ruff]
74
74
  target-version = "py311"
75
75
  exclude = ["crossplane/function/proto/*"]
76
- select = [
76
+ lint.select = [
77
77
  "A",
78
78
  "ARG",
79
79
  "ASYNC",
@@ -103,12 +103,12 @@ select = [
103
103
  "W",
104
104
  "YTT",
105
105
  ]
106
- ignore = ["ISC001"] # Ruff warns this is incompatible with ruff format.
106
+ lint.ignore = ["ISC001"] # Ruff warns this is incompatible with ruff format.
107
107
 
108
108
  [tool.ruff.lint.per-file-ignores]
109
109
  "tests/*" = ["D"] # Don't require docstrings for tests.
110
110
 
111
- [tool.ruff.isort]
111
+ [tool.ruff.lint.isort]
112
112
  known-first-party = ["crossplane"]
113
113
 
114
114
  [tool.ruff.lint.pydocstyle]
@@ -122,6 +122,49 @@ class TestResource(unittest.TestCase):
122
122
  dataclasses.asdict(case.want), dataclasses.asdict(got), "-want, +got"
123
123
  )
124
124
 
125
+ def test_get_credentials(self) -> None:
126
+ @dataclasses.dataclass
127
+ class TestCase:
128
+ reason: str
129
+ req: structpb.Struct
130
+ name: str
131
+ want: resource.Credentials
132
+
133
+ cases = [
134
+ TestCase(
135
+ reason="Return the specified credentials if they exist.",
136
+ req=resource.dict_to_struct(
137
+ {"credentials": {"test": {"type": "data", "data": {"foo": "bar"}}}}
138
+ ),
139
+ name="test",
140
+ want=resource.Credentials(type="data", data={"foo": "bar"}),
141
+ ),
142
+ TestCase(
143
+ reason="Return empty credentials if no credentials section exists.",
144
+ req=resource.dict_to_struct({}),
145
+ name="test",
146
+ want=resource.Credentials(type="data", data={}),
147
+ ),
148
+ TestCase(
149
+ reason="Return empty credentials if the specified name does not exist.",
150
+ req=resource.dict_to_struct(
151
+ {
152
+ "credentials": {
153
+ "nottest": {"type": "data", "data": {"foo": "bar"}}
154
+ }
155
+ }
156
+ ),
157
+ name="test",
158
+ want=resource.Credentials(type="data", data={}),
159
+ ),
160
+ ]
161
+
162
+ for case in cases:
163
+ got = resource.get_credentials(case.req, case.name)
164
+ self.assertEqual(
165
+ dataclasses.asdict(case.want), dataclasses.asdict(got), "-want, +got"
166
+ )
167
+
125
168
 
126
169
  if __name__ == "__main__":
127
170
  unittest.main()
@@ -1,74 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Generated by the protocol buffer compiler. DO NOT EDIT!
3
- # source: crossplane/function/proto/v1beta1/run_function.proto
4
- # Protobuf Python Version: 4.25.0
5
- """Generated protocol buffer code."""
6
- from google.protobuf import descriptor as _descriptor
7
- from google.protobuf import descriptor_pool as _descriptor_pool
8
- from google.protobuf import symbol_database as _symbol_database
9
- from google.protobuf.internal import builder as _builder
10
- # @@protoc_insertion_point(imports)
11
-
12
- _sym_db = _symbol_database.Default()
13
-
14
-
15
- from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
16
- from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
17
-
18
-
19
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n4crossplane/function/proto/v1beta1/run_function.proto\x12\x1e\x61piextensions.fn.proto.v1beta1\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1egoogle/protobuf/duration.proto\"\xf5\x03\n\x12RunFunctionRequest\x12\x39\n\x04meta\x18\x01 \x01(\x0b\x32+.apiextensions.fn.proto.v1beta1.RequestMeta\x12\x37\n\x08observed\x18\x02 \x01(\x0b\x32%.apiextensions.fn.proto.v1beta1.State\x12\x36\n\x07\x64\x65sired\x18\x03 \x01(\x0b\x32%.apiextensions.fn.proto.v1beta1.State\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x88\x01\x01\x12-\n\x07\x63ontext\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x01\x88\x01\x01\x12_\n\x0f\x65xtra_resources\x18\x06 \x03(\x0b\x32\x46.apiextensions.fn.proto.v1beta1.RunFunctionRequest.ExtraResourcesEntry\x1a`\n\x13\x45xtraResourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x01(\x0b\x32).apiextensions.fn.proto.v1beta1.Resources:\x02\x38\x01\x42\x08\n\x06_inputB\n\n\x08_context\"D\n\tResources\x12\x37\n\x05items\x18\x01 \x03(\x0b\x32(.apiextensions.fn.proto.v1beta1.Resource\"\xc1\x02\n\x13RunFunctionResponse\x12:\n\x04meta\x18\x01 \x01(\x0b\x32,.apiextensions.fn.proto.v1beta1.ResponseMeta\x12\x36\n\x07\x64\x65sired\x18\x02 \x01(\x0b\x32%.apiextensions.fn.proto.v1beta1.State\x12\x37\n\x07results\x18\x03 \x03(\x0b\x32&.apiextensions.fn.proto.v1beta1.Result\x12-\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x88\x01\x01\x12\x42\n\x0crequirements\x18\x05 \x01(\x0b\x32,.apiextensions.fn.proto.v1beta1.RequirementsB\n\n\x08_context\"\x1a\n\x0bRequestMeta\x12\x0b\n\x03tag\x18\x01 \x01(\t\"\xd2\x01\n\x0cRequirements\x12Y\n\x0f\x65xtra_resources\x18\x01 \x03(\x0b\x32@.apiextensions.fn.proto.v1beta1.Requirements.ExtraResourcesEntry\x1ag\n\x13\x45xtraResourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12?\n\x05value\x18\x02 \x01(\x0b\x32\x30.apiextensions.fn.proto.v1beta1.ResourceSelector:\x02\x38\x01\"\x99\x01\n\x10ResourceSelector\x12\x13\n\x0b\x61pi_version\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\x14\n\nmatch_name\x18\x03 \x01(\tH\x00\x12\x43\n\x0cmatch_labels\x18\x04 \x01(\x0b\x32+.apiextensions.fn.proto.v1beta1.MatchLabelsH\x00\x42\x07\n\x05match\"\x85\x01\n\x0bMatchLabels\x12G\n\x06labels\x18\x01 \x03(\x0b\x32\x37.apiextensions.fn.proto.v1beta1.MatchLabels.LabelsEntry\x1a-\n\x0bLabelsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"P\n\x0cResponseMeta\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12+\n\x03ttl\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00\x88\x01\x01\x42\x06\n\x04_ttl\"\xe9\x01\n\x05State\x12;\n\tcomposite\x18\x01 \x01(\x0b\x32(.apiextensions.fn.proto.v1beta1.Resource\x12G\n\tresources\x18\x02 \x03(\x0b\x32\x34.apiextensions.fn.proto.v1beta1.State.ResourcesEntry\x1aZ\n\x0eResourcesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x37\n\x05value\x18\x02 \x01(\x0b\x32(.apiextensions.fn.proto.v1beta1.Resource:\x02\x38\x01\"\x82\x02\n\x08Resource\x12)\n\x08resource\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12[\n\x12\x63onnection_details\x18\x02 \x03(\x0b\x32?.apiextensions.fn.proto.v1beta1.Resource.ConnectionDetailsEntry\x12\x34\n\x05ready\x18\x03 \x01(\x0e\x32%.apiextensions.fn.proto.v1beta1.Ready\x1a\x38\n\x16\x43onnectionDetailsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\"U\n\x06Result\x12:\n\x08severity\x18\x01 \x01(\x0e\x32(.apiextensions.fn.proto.v1beta1.Severity\x12\x0f\n\x07message\x18\x02 \x01(\t*?\n\x05Ready\x12\x15\n\x11READY_UNSPECIFIED\x10\x00\x12\x0e\n\nREADY_TRUE\x10\x01\x12\x0f\n\x0bREADY_FALSE\x10\x02*c\n\x08Severity\x12\x18\n\x14SEVERITY_UNSPECIFIED\x10\x00\x12\x12\n\x0eSEVERITY_FATAL\x10\x01\x12\x14\n\x10SEVERITY_WARNING\x10\x02\x12\x13\n\x0fSEVERITY_NORMAL\x10\x03\x32\x91\x01\n\x15\x46unctionRunnerService\x12x\n\x0bRunFunction\x12\x32.apiextensions.fn.proto.v1beta1.RunFunctionRequest\x1a\x33.apiextensions.fn.proto.v1beta1.RunFunctionResponse\"\x00\x62\x06proto3')
20
-
21
- _globals = globals()
22
- _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
23
- _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'crossplane.function.proto.v1beta1.run_function_pb2', _globals)
24
- if _descriptor._USE_C_DESCRIPTORS == False:
25
- DESCRIPTOR._options = None
26
- _globals['_RUNFUNCTIONREQUEST_EXTRARESOURCESENTRY']._options = None
27
- _globals['_RUNFUNCTIONREQUEST_EXTRARESOURCESENTRY']._serialized_options = b'8\001'
28
- _globals['_REQUIREMENTS_EXTRARESOURCESENTRY']._options = None
29
- _globals['_REQUIREMENTS_EXTRARESOURCESENTRY']._serialized_options = b'8\001'
30
- _globals['_MATCHLABELS_LABELSENTRY']._options = None
31
- _globals['_MATCHLABELS_LABELSENTRY']._serialized_options = b'8\001'
32
- _globals['_STATE_RESOURCESENTRY']._options = None
33
- _globals['_STATE_RESOURCESENTRY']._serialized_options = b'8\001'
34
- _globals['_RESOURCE_CONNECTIONDETAILSENTRY']._options = None
35
- _globals['_RESOURCE_CONNECTIONDETAILSENTRY']._serialized_options = b'8\001'
36
- _globals['_READY']._serialized_start=2247
37
- _globals['_READY']._serialized_end=2310
38
- _globals['_SEVERITY']._serialized_start=2312
39
- _globals['_SEVERITY']._serialized_end=2411
40
- _globals['_RUNFUNCTIONREQUEST']._serialized_start=151
41
- _globals['_RUNFUNCTIONREQUEST']._serialized_end=652
42
- _globals['_RUNFUNCTIONREQUEST_EXTRARESOURCESENTRY']._serialized_start=534
43
- _globals['_RUNFUNCTIONREQUEST_EXTRARESOURCESENTRY']._serialized_end=630
44
- _globals['_RESOURCES']._serialized_start=654
45
- _globals['_RESOURCES']._serialized_end=722
46
- _globals['_RUNFUNCTIONRESPONSE']._serialized_start=725
47
- _globals['_RUNFUNCTIONRESPONSE']._serialized_end=1046
48
- _globals['_REQUESTMETA']._serialized_start=1048
49
- _globals['_REQUESTMETA']._serialized_end=1074
50
- _globals['_REQUIREMENTS']._serialized_start=1077
51
- _globals['_REQUIREMENTS']._serialized_end=1287
52
- _globals['_REQUIREMENTS_EXTRARESOURCESENTRY']._serialized_start=1184
53
- _globals['_REQUIREMENTS_EXTRARESOURCESENTRY']._serialized_end=1287
54
- _globals['_RESOURCESELECTOR']._serialized_start=1290
55
- _globals['_RESOURCESELECTOR']._serialized_end=1443
56
- _globals['_MATCHLABELS']._serialized_start=1446
57
- _globals['_MATCHLABELS']._serialized_end=1579
58
- _globals['_MATCHLABELS_LABELSENTRY']._serialized_start=1534
59
- _globals['_MATCHLABELS_LABELSENTRY']._serialized_end=1579
60
- _globals['_RESPONSEMETA']._serialized_start=1581
61
- _globals['_RESPONSEMETA']._serialized_end=1661
62
- _globals['_STATE']._serialized_start=1664
63
- _globals['_STATE']._serialized_end=1897
64
- _globals['_STATE_RESOURCESENTRY']._serialized_start=1807
65
- _globals['_STATE_RESOURCESENTRY']._serialized_end=1897
66
- _globals['_RESOURCE']._serialized_start=1900
67
- _globals['_RESOURCE']._serialized_end=2158
68
- _globals['_RESOURCE_CONNECTIONDETAILSENTRY']._serialized_start=2102
69
- _globals['_RESOURCE_CONNECTIONDETAILSENTRY']._serialized_end=2158
70
- _globals['_RESULT']._serialized_start=2160
71
- _globals['_RESULT']._serialized_end=2245
72
- _globals['_FUNCTIONRUNNERSERVICE']._serialized_start=2414
73
- _globals['_FUNCTIONRUNNERSERVICE']._serialized_end=2559
74
- # @@protoc_insertion_point(module_scope)