crossplane-function-sdk-python 0.1.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.
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/.github/workflows/ci.yml +47 -1
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/.gitignore +3 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/PKG-INFO +15 -7
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/README.md +12 -4
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/__version__.py +1 -1
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/proto/v1beta1/run_function.proto +58 -1
- crossplane_function_sdk_python-0.3.0/crossplane/function/proto/v1beta1/run_function_pb2.py +86 -0
- crossplane_function_sdk_python-0.3.0/crossplane/function/proto/v1beta1/run_function_pb2.pyi +192 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/resource.py +21 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/runtime.py +3 -1
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/pyproject.toml +16 -12
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/tests/test_resource.py +43 -0
- crossplane_function_sdk_python-0.1.0/crossplane/function/proto/v1beta1/run_function_pb2.py +0 -53
- crossplane_function_sdk_python-0.1.0/crossplane/function/proto/v1beta1/run_function_pb2.pyi +0 -109
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/LICENSE +0 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/logging.py +0 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/proto/v1beta1/run_function_pb2_grpc.py +0 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/crossplane/function/response.py +0 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/renovate.json +0 -0
- {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/tests/test_response.py +0 -0
|
@@ -12,6 +12,19 @@ on:
|
|
|
12
12
|
description: PyPI project version (e.g. v0.1.0)
|
|
13
13
|
required: false
|
|
14
14
|
|
|
15
|
+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages.
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
pages: write
|
|
19
|
+
id-token: write
|
|
20
|
+
|
|
21
|
+
# Allow only one concurrent deployment, skipping runs queued between the run
|
|
22
|
+
# in-progress and latest queued. However, do NOT cancel in-progress runs as we
|
|
23
|
+
# want to allow these production deployments to complete.
|
|
24
|
+
concurrency:
|
|
25
|
+
group: "pages"
|
|
26
|
+
cancel-in-progress: false
|
|
27
|
+
|
|
15
28
|
env:
|
|
16
29
|
# Common versions
|
|
17
30
|
PYTHON_VERSION: '3.11.5'
|
|
@@ -106,10 +119,43 @@ jobs:
|
|
|
106
119
|
path: "dist"
|
|
107
120
|
|
|
108
121
|
- name: Publish to PyPI
|
|
109
|
-
uses: pypa/gh-action-pypi-publish@v1.
|
|
122
|
+
uses: pypa/gh-action-pypi-publish@v1.9.0
|
|
110
123
|
with:
|
|
111
124
|
# Note that this is currently being pushed to the 'crossplane' PyPI
|
|
112
125
|
# user (not org). See @negz if you need access - PyPI requires 2FA to
|
|
113
126
|
# be enabled, which makes sharing the account hard. We're waiting for
|
|
114
127
|
# a crossplane org to be approved.
|
|
115
128
|
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
docs:
|
|
132
|
+
# The simple docs tool we're using doesn't support versions, so our docs
|
|
133
|
+
# will only reflect what's in main.
|
|
134
|
+
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
|
135
|
+
runs-on: ubuntu-22.04
|
|
136
|
+
steps:
|
|
137
|
+
- name: Checkout
|
|
138
|
+
uses: actions/checkout@v4
|
|
139
|
+
|
|
140
|
+
- name: Setup Python
|
|
141
|
+
uses: actions/setup-python@v5
|
|
142
|
+
with:
|
|
143
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
144
|
+
|
|
145
|
+
- name: Setup Hatch
|
|
146
|
+
run: pipx install hatch==1.7.0
|
|
147
|
+
|
|
148
|
+
- name: Build Documentation
|
|
149
|
+
run: hatch run docs:pdoc -d google crossplane/function -o docs
|
|
150
|
+
|
|
151
|
+
- name: Setup Pages
|
|
152
|
+
uses: actions/configure-pages@v5
|
|
153
|
+
|
|
154
|
+
- name: Upload artifact
|
|
155
|
+
uses: actions/upload-pages-artifact@v3
|
|
156
|
+
with:
|
|
157
|
+
path: docs
|
|
158
|
+
|
|
159
|
+
- name: Deploy to GitHub Pages
|
|
160
|
+
id: deployment
|
|
161
|
+
uses: actions/deploy-pages@v4
|
|
@@ -158,3 +158,6 @@ cython_debug/
|
|
|
158
158
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
159
159
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
160
160
|
#.idea/
|
|
161
|
+
|
|
162
|
+
# We don't commit our docs - instead we generate them and upload to GitHub pages.
|
|
163
|
+
docs
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: crossplane-function-sdk-python
|
|
3
|
-
Version: 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
|
|
@@ -14,11 +14,12 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
14
14
|
Requires-Python: >=3.11
|
|
15
15
|
Requires-Dist: grpcio-reflection==1.*
|
|
16
16
|
Requires-Dist: grpcio==1.*
|
|
17
|
-
Requires-Dist: structlog==
|
|
17
|
+
Requires-Dist: structlog==24.*
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
|
|
20
20
|
# function-sdk-python
|
|
21
|
-
[](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml) 
|
|
21
|
+
[](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml) [](https://github.com/crossplane/function-sdk-python/releases) [](https://pypi.org/project/crossplane-function-sdk-python/)
|
|
22
|
+
|
|
22
23
|
|
|
23
24
|
The [Python][python] SDK for writing [composition functions][functions].
|
|
24
25
|
|
|
@@ -28,14 +29,18 @@ guidelines] as Crossplane.
|
|
|
28
29
|
|
|
29
30
|
To learn how to use this SDK:
|
|
30
31
|
|
|
32
|
+
* [Follow the guide to writing a composition function in Python][function guide]
|
|
31
33
|
* [Learn about how composition functions work][functions]
|
|
32
|
-
* [
|
|
34
|
+
* [Read the package documentation][package docs]
|
|
33
35
|
|
|
34
36
|
The `RunFunctionRequest` and `RunFunctionResponse` types provided by this SDK
|
|
35
37
|
are generated from a proto3 protocol buffer schema. Their fields behave
|
|
36
38
|
similarly to built-in Python types like lists and dictionaries, but there are
|
|
37
|
-
some differences. Read the generated code documentation to
|
|
38
|
-
with the the differences.
|
|
39
|
+
some differences. Read the [generated code documentation][python-protobuf] to
|
|
40
|
+
familiarize yourself with the the differences.
|
|
41
|
+
|
|
42
|
+
If you just want to jump in and get started, consider using the
|
|
43
|
+
[function-template-python] template repository.
|
|
39
44
|
|
|
40
45
|
## Contributing
|
|
41
46
|
|
|
@@ -61,5 +66,8 @@ hatch build
|
|
|
61
66
|
[python]: https://python.org
|
|
62
67
|
[functions]: https://docs.crossplane.io/latest/concepts/composition-functions
|
|
63
68
|
[python-protobuf]: https://protobuf.dev/reference/python/python-generated/
|
|
69
|
+
[function-template-python]: https://github.com/crossplane/function-template-python
|
|
70
|
+
[function guide]: https://docs.crossplane.io/knowledge-base/guides/write-a-composition-function-in-python
|
|
71
|
+
[package docs]: https://crossplane.github.io/function-sdk-python
|
|
64
72
|
[contributing guidelines]: https://github.com/crossplane/crossplane/tree/master/contributing
|
|
65
73
|
[hatch]: https://github.com/pypa/hatch
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# function-sdk-python
|
|
2
|
-
[](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml) 
|
|
2
|
+
[](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml) [](https://github.com/crossplane/function-sdk-python/releases) [](https://pypi.org/project/crossplane-function-sdk-python/)
|
|
3
|
+
|
|
3
4
|
|
|
4
5
|
The [Python][python] SDK for writing [composition functions][functions].
|
|
5
6
|
|
|
@@ -9,14 +10,18 @@ guidelines] as Crossplane.
|
|
|
9
10
|
|
|
10
11
|
To learn how to use this SDK:
|
|
11
12
|
|
|
13
|
+
* [Follow the guide to writing a composition function in Python][function guide]
|
|
12
14
|
* [Learn about how composition functions work][functions]
|
|
13
|
-
* [
|
|
15
|
+
* [Read the package documentation][package docs]
|
|
14
16
|
|
|
15
17
|
The `RunFunctionRequest` and `RunFunctionResponse` types provided by this SDK
|
|
16
18
|
are generated from a proto3 protocol buffer schema. Their fields behave
|
|
17
19
|
similarly to built-in Python types like lists and dictionaries, but there are
|
|
18
|
-
some differences. Read the generated code documentation to
|
|
19
|
-
with the the differences.
|
|
20
|
+
some differences. Read the [generated code documentation][python-protobuf] to
|
|
21
|
+
familiarize yourself with the the differences.
|
|
22
|
+
|
|
23
|
+
If you just want to jump in and get started, consider using the
|
|
24
|
+
[function-template-python] template repository.
|
|
20
25
|
|
|
21
26
|
## Contributing
|
|
22
27
|
|
|
@@ -42,5 +47,8 @@ hatch build
|
|
|
42
47
|
[python]: https://python.org
|
|
43
48
|
[functions]: https://docs.crossplane.io/latest/concepts/composition-functions
|
|
44
49
|
[python-protobuf]: https://protobuf.dev/reference/python/python-generated/
|
|
50
|
+
[function-template-python]: https://github.com/crossplane/function-template-python
|
|
51
|
+
[function guide]: https://docs.crossplane.io/knowledge-base/guides/write-a-composition-function-in-python
|
|
52
|
+
[package docs]: https://crossplane.github.io/function-sdk-python
|
|
45
53
|
[contributing guidelines]: https://github.com/crossplane/crossplane/tree/master/contributing
|
|
46
54
|
[hatch]: https://github.com/pypa/hatch
|
|
@@ -61,6 +61,37 @@ message RunFunctionRequest {
|
|
|
61
61
|
// and that context will be passed to subsequent Functions. Crossplane
|
|
62
62
|
// discards all context returned by the last Function in the pipeline.
|
|
63
63
|
optional google.protobuf.Struct context = 5;
|
|
64
|
+
|
|
65
|
+
// Optional extra resources that the Function required.
|
|
66
|
+
// Note that extra resources is a map to Resources, plural.
|
|
67
|
+
// The map key corresponds to the key in a RunFunctionResponse's
|
|
68
|
+
// extra_resources field. If a Function requested extra resources that
|
|
69
|
+
// did not exist, Crossplane sets the map key to an empty Resources message to
|
|
70
|
+
// indicate that it attempted to satisfy the request.
|
|
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;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Resources represents the state of several Crossplane resources.
|
|
93
|
+
message Resources {
|
|
94
|
+
repeated Resource items = 1;
|
|
64
95
|
}
|
|
65
96
|
|
|
66
97
|
// A RunFunctionResponse contains the result of a Composition Function run.
|
|
@@ -88,6 +119,9 @@ message RunFunctionResponse {
|
|
|
88
119
|
// Optional context to be passed to the next Function in the pipeline as part
|
|
89
120
|
// of the RunFunctionRequest. Dropped on the last function in the pipeline.
|
|
90
121
|
optional google.protobuf.Struct context = 4;
|
|
122
|
+
|
|
123
|
+
// Requirements that must be satisfied for this Function to run successfully.
|
|
124
|
+
Requirements requirements = 5;
|
|
91
125
|
}
|
|
92
126
|
|
|
93
127
|
// RequestMeta contains metadata pertaining to a RunFunctionRequest.
|
|
@@ -97,6 +131,29 @@ message RequestMeta {
|
|
|
97
131
|
string tag = 1;
|
|
98
132
|
}
|
|
99
133
|
|
|
134
|
+
// Requirements that must be satisfied for a Function to run successfully.
|
|
135
|
+
message Requirements {
|
|
136
|
+
// Extra resources that this Function requires.
|
|
137
|
+
// The map key uniquely identifies the group of resources.
|
|
138
|
+
map<string, ResourceSelector> extra_resources = 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// ResourceSelector selects a group of resources, either by name or by label.
|
|
142
|
+
message ResourceSelector {
|
|
143
|
+
string api_version = 1;
|
|
144
|
+
string kind = 2;
|
|
145
|
+
|
|
146
|
+
oneof match {
|
|
147
|
+
string match_name = 3;
|
|
148
|
+
MatchLabels match_labels = 4;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// MatchLabels defines a set of labels to match resources against.
|
|
153
|
+
message MatchLabels {
|
|
154
|
+
map<string, string> labels = 1;
|
|
155
|
+
}
|
|
156
|
+
|
|
100
157
|
// ResponseMeta contains metadata pertaining to a RunFunctionResponse.
|
|
101
158
|
message ResponseMeta {
|
|
102
159
|
// An opaque string identifying the content of the request. Must match the
|
|
@@ -199,4 +256,4 @@ enum Severity {
|
|
|
199
256
|
// Normal results are emitted as normal events and debug logs associated
|
|
200
257
|
// with the composite resource.
|
|
201
258
|
SEVERITY_NORMAL = 3;
|
|
202
|
-
}
|
|
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)
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
from google.protobuf import struct_pb2 as _struct_pb2
|
|
2
|
+
from google.protobuf import duration_pb2 as _duration_pb2
|
|
3
|
+
from google.protobuf.internal import containers as _containers
|
|
4
|
+
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
|
5
|
+
from google.protobuf import descriptor as _descriptor
|
|
6
|
+
from google.protobuf import message as _message
|
|
7
|
+
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
|
8
|
+
|
|
9
|
+
DESCRIPTOR: _descriptor.FileDescriptor
|
|
10
|
+
|
|
11
|
+
class Ready(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
12
|
+
__slots__ = ()
|
|
13
|
+
READY_UNSPECIFIED: _ClassVar[Ready]
|
|
14
|
+
READY_TRUE: _ClassVar[Ready]
|
|
15
|
+
READY_FALSE: _ClassVar[Ready]
|
|
16
|
+
|
|
17
|
+
class Severity(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
18
|
+
__slots__ = ()
|
|
19
|
+
SEVERITY_UNSPECIFIED: _ClassVar[Severity]
|
|
20
|
+
SEVERITY_FATAL: _ClassVar[Severity]
|
|
21
|
+
SEVERITY_WARNING: _ClassVar[Severity]
|
|
22
|
+
SEVERITY_NORMAL: _ClassVar[Severity]
|
|
23
|
+
READY_UNSPECIFIED: Ready
|
|
24
|
+
READY_TRUE: Ready
|
|
25
|
+
READY_FALSE: Ready
|
|
26
|
+
SEVERITY_UNSPECIFIED: Severity
|
|
27
|
+
SEVERITY_FATAL: Severity
|
|
28
|
+
SEVERITY_WARNING: Severity
|
|
29
|
+
SEVERITY_NORMAL: Severity
|
|
30
|
+
|
|
31
|
+
class RunFunctionRequest(_message.Message):
|
|
32
|
+
__slots__ = ("meta", "observed", "desired", "input", "context", "extra_resources", "credentials")
|
|
33
|
+
class ExtraResourcesEntry(_message.Message):
|
|
34
|
+
__slots__ = ("key", "value")
|
|
35
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
36
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
37
|
+
key: str
|
|
38
|
+
value: Resources
|
|
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: ...
|
|
47
|
+
META_FIELD_NUMBER: _ClassVar[int]
|
|
48
|
+
OBSERVED_FIELD_NUMBER: _ClassVar[int]
|
|
49
|
+
DESIRED_FIELD_NUMBER: _ClassVar[int]
|
|
50
|
+
INPUT_FIELD_NUMBER: _ClassVar[int]
|
|
51
|
+
CONTEXT_FIELD_NUMBER: _ClassVar[int]
|
|
52
|
+
EXTRA_RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
53
|
+
CREDENTIALS_FIELD_NUMBER: _ClassVar[int]
|
|
54
|
+
meta: RequestMeta
|
|
55
|
+
observed: State
|
|
56
|
+
desired: State
|
|
57
|
+
input: _struct_pb2.Struct
|
|
58
|
+
context: _struct_pb2.Struct
|
|
59
|
+
extra_resources: _containers.MessageMap[str, Resources]
|
|
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: ...
|
|
81
|
+
|
|
82
|
+
class Resources(_message.Message):
|
|
83
|
+
__slots__ = ("items",)
|
|
84
|
+
ITEMS_FIELD_NUMBER: _ClassVar[int]
|
|
85
|
+
items: _containers.RepeatedCompositeFieldContainer[Resource]
|
|
86
|
+
def __init__(self, items: _Optional[_Iterable[_Union[Resource, _Mapping]]] = ...) -> None: ...
|
|
87
|
+
|
|
88
|
+
class RunFunctionResponse(_message.Message):
|
|
89
|
+
__slots__ = ("meta", "desired", "results", "context", "requirements")
|
|
90
|
+
META_FIELD_NUMBER: _ClassVar[int]
|
|
91
|
+
DESIRED_FIELD_NUMBER: _ClassVar[int]
|
|
92
|
+
RESULTS_FIELD_NUMBER: _ClassVar[int]
|
|
93
|
+
CONTEXT_FIELD_NUMBER: _ClassVar[int]
|
|
94
|
+
REQUIREMENTS_FIELD_NUMBER: _ClassVar[int]
|
|
95
|
+
meta: ResponseMeta
|
|
96
|
+
desired: State
|
|
97
|
+
results: _containers.RepeatedCompositeFieldContainer[Result]
|
|
98
|
+
context: _struct_pb2.Struct
|
|
99
|
+
requirements: Requirements
|
|
100
|
+
def __init__(self, meta: _Optional[_Union[ResponseMeta, _Mapping]] = ..., desired: _Optional[_Union[State, _Mapping]] = ..., results: _Optional[_Iterable[_Union[Result, _Mapping]]] = ..., context: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., requirements: _Optional[_Union[Requirements, _Mapping]] = ...) -> None: ...
|
|
101
|
+
|
|
102
|
+
class RequestMeta(_message.Message):
|
|
103
|
+
__slots__ = ("tag",)
|
|
104
|
+
TAG_FIELD_NUMBER: _ClassVar[int]
|
|
105
|
+
tag: str
|
|
106
|
+
def __init__(self, tag: _Optional[str] = ...) -> None: ...
|
|
107
|
+
|
|
108
|
+
class Requirements(_message.Message):
|
|
109
|
+
__slots__ = ("extra_resources",)
|
|
110
|
+
class ExtraResourcesEntry(_message.Message):
|
|
111
|
+
__slots__ = ("key", "value")
|
|
112
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
113
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
114
|
+
key: str
|
|
115
|
+
value: ResourceSelector
|
|
116
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[ResourceSelector, _Mapping]] = ...) -> None: ...
|
|
117
|
+
EXTRA_RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
118
|
+
extra_resources: _containers.MessageMap[str, ResourceSelector]
|
|
119
|
+
def __init__(self, extra_resources: _Optional[_Mapping[str, ResourceSelector]] = ...) -> None: ...
|
|
120
|
+
|
|
121
|
+
class ResourceSelector(_message.Message):
|
|
122
|
+
__slots__ = ("api_version", "kind", "match_name", "match_labels")
|
|
123
|
+
API_VERSION_FIELD_NUMBER: _ClassVar[int]
|
|
124
|
+
KIND_FIELD_NUMBER: _ClassVar[int]
|
|
125
|
+
MATCH_NAME_FIELD_NUMBER: _ClassVar[int]
|
|
126
|
+
MATCH_LABELS_FIELD_NUMBER: _ClassVar[int]
|
|
127
|
+
api_version: str
|
|
128
|
+
kind: str
|
|
129
|
+
match_name: str
|
|
130
|
+
match_labels: MatchLabels
|
|
131
|
+
def __init__(self, api_version: _Optional[str] = ..., kind: _Optional[str] = ..., match_name: _Optional[str] = ..., match_labels: _Optional[_Union[MatchLabels, _Mapping]] = ...) -> None: ...
|
|
132
|
+
|
|
133
|
+
class MatchLabels(_message.Message):
|
|
134
|
+
__slots__ = ("labels",)
|
|
135
|
+
class LabelsEntry(_message.Message):
|
|
136
|
+
__slots__ = ("key", "value")
|
|
137
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
138
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
139
|
+
key: str
|
|
140
|
+
value: str
|
|
141
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
|
|
142
|
+
LABELS_FIELD_NUMBER: _ClassVar[int]
|
|
143
|
+
labels: _containers.ScalarMap[str, str]
|
|
144
|
+
def __init__(self, labels: _Optional[_Mapping[str, str]] = ...) -> None: ...
|
|
145
|
+
|
|
146
|
+
class ResponseMeta(_message.Message):
|
|
147
|
+
__slots__ = ("tag", "ttl")
|
|
148
|
+
TAG_FIELD_NUMBER: _ClassVar[int]
|
|
149
|
+
TTL_FIELD_NUMBER: _ClassVar[int]
|
|
150
|
+
tag: str
|
|
151
|
+
ttl: _duration_pb2.Duration
|
|
152
|
+
def __init__(self, tag: _Optional[str] = ..., ttl: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ...) -> None: ...
|
|
153
|
+
|
|
154
|
+
class State(_message.Message):
|
|
155
|
+
__slots__ = ("composite", "resources")
|
|
156
|
+
class ResourcesEntry(_message.Message):
|
|
157
|
+
__slots__ = ("key", "value")
|
|
158
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
159
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
160
|
+
key: str
|
|
161
|
+
value: Resource
|
|
162
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Resource, _Mapping]] = ...) -> None: ...
|
|
163
|
+
COMPOSITE_FIELD_NUMBER: _ClassVar[int]
|
|
164
|
+
RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
165
|
+
composite: Resource
|
|
166
|
+
resources: _containers.MessageMap[str, Resource]
|
|
167
|
+
def __init__(self, composite: _Optional[_Union[Resource, _Mapping]] = ..., resources: _Optional[_Mapping[str, Resource]] = ...) -> None: ...
|
|
168
|
+
|
|
169
|
+
class Resource(_message.Message):
|
|
170
|
+
__slots__ = ("resource", "connection_details", "ready")
|
|
171
|
+
class ConnectionDetailsEntry(_message.Message):
|
|
172
|
+
__slots__ = ("key", "value")
|
|
173
|
+
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
174
|
+
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
175
|
+
key: str
|
|
176
|
+
value: bytes
|
|
177
|
+
def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ...
|
|
178
|
+
RESOURCE_FIELD_NUMBER: _ClassVar[int]
|
|
179
|
+
CONNECTION_DETAILS_FIELD_NUMBER: _ClassVar[int]
|
|
180
|
+
READY_FIELD_NUMBER: _ClassVar[int]
|
|
181
|
+
resource: _struct_pb2.Struct
|
|
182
|
+
connection_details: _containers.ScalarMap[str, bytes]
|
|
183
|
+
ready: Ready
|
|
184
|
+
def __init__(self, resource: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., connection_details: _Optional[_Mapping[str, bytes]] = ..., ready: _Optional[_Union[Ready, str]] = ...) -> None: ...
|
|
185
|
+
|
|
186
|
+
class Result(_message.Message):
|
|
187
|
+
__slots__ = ("severity", "message")
|
|
188
|
+
SEVERITY_FIELD_NUMBER: _ClassVar[int]
|
|
189
|
+
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
|
190
|
+
severity: Severity
|
|
191
|
+
message: str
|
|
192
|
+
def __init__(self, severity: _Optional[_Union[Severity, str]] = ..., message: _Optional[str] = ...) -> None: ...
|
|
@@ -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:
|
{crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/pyproject.toml
RENAMED
|
@@ -16,11 +16,7 @@ classifiers = [
|
|
|
16
16
|
"Programming Language :: Python :: 3.11",
|
|
17
17
|
]
|
|
18
18
|
|
|
19
|
-
dependencies = [
|
|
20
|
-
"grpcio==1.*",
|
|
21
|
-
"grpcio-reflection==1.*",
|
|
22
|
-
"structlog==23.*",
|
|
23
|
-
]
|
|
19
|
+
dependencies = ["grpcio==1.*", "grpcio-reflection==1.*", "structlog==24.*"]
|
|
24
20
|
|
|
25
21
|
dynamic = ["version"]
|
|
26
22
|
|
|
@@ -31,18 +27,18 @@ Source = "https://github.com/crossplane/function-sdk-python"
|
|
|
31
27
|
|
|
32
28
|
[tool.hatch.version]
|
|
33
29
|
path = "crossplane/function/__version__.py"
|
|
34
|
-
validate-bump = false
|
|
30
|
+
validate-bump = false # Allow going from 0.0.0.dev0+x to 0.0.0.dev0+y.
|
|
35
31
|
|
|
36
32
|
[tool.hatch.envs.default]
|
|
37
33
|
type = "virtual"
|
|
38
34
|
path = ".venv-default"
|
|
39
|
-
dependencies = ["ipython==8.
|
|
35
|
+
dependencies = ["ipython==8.26.0"]
|
|
40
36
|
|
|
41
37
|
[tool.hatch.envs.generate]
|
|
42
38
|
type = "virtual"
|
|
43
39
|
detached = true
|
|
44
40
|
path = ".venv-generate"
|
|
45
|
-
dependencies = ["grpcio-tools==1.
|
|
41
|
+
dependencies = ["grpcio-tools==1.65.4"]
|
|
46
42
|
|
|
47
43
|
[tool.hatch.envs.generate.scripts]
|
|
48
44
|
protoc = "python -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=. --grpc_python_out=. crossplane/function/proto/v1beta1/run_function.proto"
|
|
@@ -51,7 +47,7 @@ protoc = "python -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=.
|
|
|
51
47
|
type = "virtual"
|
|
52
48
|
detached = true
|
|
53
49
|
path = ".venv-lint"
|
|
54
|
-
dependencies = ["ruff==0.
|
|
50
|
+
dependencies = ["ruff==0.5.7"]
|
|
55
51
|
|
|
56
52
|
[tool.hatch.envs.lint.scripts]
|
|
57
53
|
check = "ruff check crossplane tests && ruff format --diff crossplane tests"
|
|
@@ -63,13 +59,21 @@ path = ".venv-test"
|
|
|
63
59
|
[tool.hatch.envs.test.scripts]
|
|
64
60
|
unit = "python -m unittest tests/*.py"
|
|
65
61
|
|
|
62
|
+
[tool.hatch.envs.docs]
|
|
63
|
+
type = "virtual"
|
|
64
|
+
path = ".venv-docs"
|
|
65
|
+
dependencies = ["pdoc"]
|
|
66
|
+
|
|
67
|
+
[tool.hatch.envs.docs.scripts]
|
|
68
|
+
generate = "pdoc -m google crossplane/function -o docs"
|
|
69
|
+
|
|
66
70
|
[tool.hatch.build.targets.wheel]
|
|
67
71
|
packages = ["crossplane"]
|
|
68
72
|
|
|
69
73
|
[tool.ruff]
|
|
70
74
|
target-version = "py311"
|
|
71
75
|
exclude = ["crossplane/function/proto/*"]
|
|
72
|
-
select = [
|
|
76
|
+
lint.select = [
|
|
73
77
|
"A",
|
|
74
78
|
"ARG",
|
|
75
79
|
"ASYNC",
|
|
@@ -99,12 +103,12 @@ select = [
|
|
|
99
103
|
"W",
|
|
100
104
|
"YTT",
|
|
101
105
|
]
|
|
102
|
-
ignore = ["ISC001"] # Ruff warns this is incompatible with ruff format.
|
|
106
|
+
lint.ignore = ["ISC001"] # Ruff warns this is incompatible with ruff format.
|
|
103
107
|
|
|
104
108
|
[tool.ruff.lint.per-file-ignores]
|
|
105
109
|
"tests/*" = ["D"] # Don't require docstrings for tests.
|
|
106
110
|
|
|
107
|
-
[tool.ruff.isort]
|
|
111
|
+
[tool.ruff.lint.isort]
|
|
108
112
|
known-first-party = ["crossplane"]
|
|
109
113
|
|
|
110
114
|
[tool.ruff.lint.pydocstyle]
|
{crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.3.0}/tests/test_resource.py
RENAMED
|
@@ -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,53 +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
|
-
"""Generated protocol buffer code."""
|
|
5
|
-
from google.protobuf import descriptor as _descriptor
|
|
6
|
-
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
7
|
-
from google.protobuf import symbol_database as _symbol_database
|
|
8
|
-
from google.protobuf.internal import builder as _builder
|
|
9
|
-
# @@protoc_insertion_point(imports)
|
|
10
|
-
|
|
11
|
-
_sym_db = _symbol_database.Default()
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
|
|
15
|
-
from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
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\"\xb2\x02\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\x42\x08\n\x06_inputB\n\n\x08_context\"\xfd\x01\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\x42\n\n\x08_context\"\x1a\n\x0bRequestMeta\x12\x0b\n\x03tag\x18\x01 \x01(\t\"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')
|
|
19
|
-
|
|
20
|
-
_globals = globals()
|
|
21
|
-
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
22
|
-
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'crossplane.function.proto.v1beta1.run_function_pb2', _globals)
|
|
23
|
-
if _descriptor._USE_C_DESCRIPTORS == False:
|
|
24
|
-
DESCRIPTOR._options = None
|
|
25
|
-
_STATE_RESOURCESENTRY._options = None
|
|
26
|
-
_STATE_RESOURCESENTRY._serialized_options = b'8\001'
|
|
27
|
-
_RESOURCE_CONNECTIONDETAILSENTRY._options = None
|
|
28
|
-
_RESOURCE_CONNECTIONDETAILSENTRY._serialized_options = b'8\001'
|
|
29
|
-
_globals['_READY']._serialized_start=1409
|
|
30
|
-
_globals['_READY']._serialized_end=1472
|
|
31
|
-
_globals['_SEVERITY']._serialized_start=1474
|
|
32
|
-
_globals['_SEVERITY']._serialized_end=1573
|
|
33
|
-
_globals['_RUNFUNCTIONREQUEST']._serialized_start=151
|
|
34
|
-
_globals['_RUNFUNCTIONREQUEST']._serialized_end=457
|
|
35
|
-
_globals['_RUNFUNCTIONRESPONSE']._serialized_start=460
|
|
36
|
-
_globals['_RUNFUNCTIONRESPONSE']._serialized_end=713
|
|
37
|
-
_globals['_REQUESTMETA']._serialized_start=715
|
|
38
|
-
_globals['_REQUESTMETA']._serialized_end=741
|
|
39
|
-
_globals['_RESPONSEMETA']._serialized_start=743
|
|
40
|
-
_globals['_RESPONSEMETA']._serialized_end=823
|
|
41
|
-
_globals['_STATE']._serialized_start=826
|
|
42
|
-
_globals['_STATE']._serialized_end=1059
|
|
43
|
-
_globals['_STATE_RESOURCESENTRY']._serialized_start=969
|
|
44
|
-
_globals['_STATE_RESOURCESENTRY']._serialized_end=1059
|
|
45
|
-
_globals['_RESOURCE']._serialized_start=1062
|
|
46
|
-
_globals['_RESOURCE']._serialized_end=1320
|
|
47
|
-
_globals['_RESOURCE_CONNECTIONDETAILSENTRY']._serialized_start=1264
|
|
48
|
-
_globals['_RESOURCE_CONNECTIONDETAILSENTRY']._serialized_end=1320
|
|
49
|
-
_globals['_RESULT']._serialized_start=1322
|
|
50
|
-
_globals['_RESULT']._serialized_end=1407
|
|
51
|
-
_globals['_FUNCTIONRUNNERSERVICE']._serialized_start=1576
|
|
52
|
-
_globals['_FUNCTIONRUNNERSERVICE']._serialized_end=1721
|
|
53
|
-
# @@protoc_insertion_point(module_scope)
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
from google.protobuf import struct_pb2 as _struct_pb2
|
|
2
|
-
from google.protobuf import duration_pb2 as _duration_pb2
|
|
3
|
-
from google.protobuf.internal import containers as _containers
|
|
4
|
-
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
|
5
|
-
from google.protobuf import descriptor as _descriptor
|
|
6
|
-
from google.protobuf import message as _message
|
|
7
|
-
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
|
8
|
-
|
|
9
|
-
DESCRIPTOR: _descriptor.FileDescriptor
|
|
10
|
-
|
|
11
|
-
class Ready(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
12
|
-
__slots__ = []
|
|
13
|
-
READY_UNSPECIFIED: _ClassVar[Ready]
|
|
14
|
-
READY_TRUE: _ClassVar[Ready]
|
|
15
|
-
READY_FALSE: _ClassVar[Ready]
|
|
16
|
-
|
|
17
|
-
class Severity(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
18
|
-
__slots__ = []
|
|
19
|
-
SEVERITY_UNSPECIFIED: _ClassVar[Severity]
|
|
20
|
-
SEVERITY_FATAL: _ClassVar[Severity]
|
|
21
|
-
SEVERITY_WARNING: _ClassVar[Severity]
|
|
22
|
-
SEVERITY_NORMAL: _ClassVar[Severity]
|
|
23
|
-
READY_UNSPECIFIED: Ready
|
|
24
|
-
READY_TRUE: Ready
|
|
25
|
-
READY_FALSE: Ready
|
|
26
|
-
SEVERITY_UNSPECIFIED: Severity
|
|
27
|
-
SEVERITY_FATAL: Severity
|
|
28
|
-
SEVERITY_WARNING: Severity
|
|
29
|
-
SEVERITY_NORMAL: Severity
|
|
30
|
-
|
|
31
|
-
class RunFunctionRequest(_message.Message):
|
|
32
|
-
__slots__ = ["meta", "observed", "desired", "input", "context"]
|
|
33
|
-
META_FIELD_NUMBER: _ClassVar[int]
|
|
34
|
-
OBSERVED_FIELD_NUMBER: _ClassVar[int]
|
|
35
|
-
DESIRED_FIELD_NUMBER: _ClassVar[int]
|
|
36
|
-
INPUT_FIELD_NUMBER: _ClassVar[int]
|
|
37
|
-
CONTEXT_FIELD_NUMBER: _ClassVar[int]
|
|
38
|
-
meta: RequestMeta
|
|
39
|
-
observed: State
|
|
40
|
-
desired: State
|
|
41
|
-
input: _struct_pb2.Struct
|
|
42
|
-
context: _struct_pb2.Struct
|
|
43
|
-
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]] = ...) -> None: ...
|
|
44
|
-
|
|
45
|
-
class RunFunctionResponse(_message.Message):
|
|
46
|
-
__slots__ = ["meta", "desired", "results", "context"]
|
|
47
|
-
META_FIELD_NUMBER: _ClassVar[int]
|
|
48
|
-
DESIRED_FIELD_NUMBER: _ClassVar[int]
|
|
49
|
-
RESULTS_FIELD_NUMBER: _ClassVar[int]
|
|
50
|
-
CONTEXT_FIELD_NUMBER: _ClassVar[int]
|
|
51
|
-
meta: ResponseMeta
|
|
52
|
-
desired: State
|
|
53
|
-
results: _containers.RepeatedCompositeFieldContainer[Result]
|
|
54
|
-
context: _struct_pb2.Struct
|
|
55
|
-
def __init__(self, meta: _Optional[_Union[ResponseMeta, _Mapping]] = ..., desired: _Optional[_Union[State, _Mapping]] = ..., results: _Optional[_Iterable[_Union[Result, _Mapping]]] = ..., context: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ...
|
|
56
|
-
|
|
57
|
-
class RequestMeta(_message.Message):
|
|
58
|
-
__slots__ = ["tag"]
|
|
59
|
-
TAG_FIELD_NUMBER: _ClassVar[int]
|
|
60
|
-
tag: str
|
|
61
|
-
def __init__(self, tag: _Optional[str] = ...) -> None: ...
|
|
62
|
-
|
|
63
|
-
class ResponseMeta(_message.Message):
|
|
64
|
-
__slots__ = ["tag", "ttl"]
|
|
65
|
-
TAG_FIELD_NUMBER: _ClassVar[int]
|
|
66
|
-
TTL_FIELD_NUMBER: _ClassVar[int]
|
|
67
|
-
tag: str
|
|
68
|
-
ttl: _duration_pb2.Duration
|
|
69
|
-
def __init__(self, tag: _Optional[str] = ..., ttl: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ...) -> None: ...
|
|
70
|
-
|
|
71
|
-
class State(_message.Message):
|
|
72
|
-
__slots__ = ["composite", "resources"]
|
|
73
|
-
class ResourcesEntry(_message.Message):
|
|
74
|
-
__slots__ = ["key", "value"]
|
|
75
|
-
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
76
|
-
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
77
|
-
key: str
|
|
78
|
-
value: Resource
|
|
79
|
-
def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[Resource, _Mapping]] = ...) -> None: ...
|
|
80
|
-
COMPOSITE_FIELD_NUMBER: _ClassVar[int]
|
|
81
|
-
RESOURCES_FIELD_NUMBER: _ClassVar[int]
|
|
82
|
-
composite: Resource
|
|
83
|
-
resources: _containers.MessageMap[str, Resource]
|
|
84
|
-
def __init__(self, composite: _Optional[_Union[Resource, _Mapping]] = ..., resources: _Optional[_Mapping[str, Resource]] = ...) -> None: ...
|
|
85
|
-
|
|
86
|
-
class Resource(_message.Message):
|
|
87
|
-
__slots__ = ["resource", "connection_details", "ready"]
|
|
88
|
-
class ConnectionDetailsEntry(_message.Message):
|
|
89
|
-
__slots__ = ["key", "value"]
|
|
90
|
-
KEY_FIELD_NUMBER: _ClassVar[int]
|
|
91
|
-
VALUE_FIELD_NUMBER: _ClassVar[int]
|
|
92
|
-
key: str
|
|
93
|
-
value: bytes
|
|
94
|
-
def __init__(self, key: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ...
|
|
95
|
-
RESOURCE_FIELD_NUMBER: _ClassVar[int]
|
|
96
|
-
CONNECTION_DETAILS_FIELD_NUMBER: _ClassVar[int]
|
|
97
|
-
READY_FIELD_NUMBER: _ClassVar[int]
|
|
98
|
-
resource: _struct_pb2.Struct
|
|
99
|
-
connection_details: _containers.ScalarMap[str, bytes]
|
|
100
|
-
ready: Ready
|
|
101
|
-
def __init__(self, resource: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., connection_details: _Optional[_Mapping[str, bytes]] = ..., ready: _Optional[_Union[Ready, str]] = ...) -> None: ...
|
|
102
|
-
|
|
103
|
-
class Result(_message.Message):
|
|
104
|
-
__slots__ = ["severity", "message"]
|
|
105
|
-
SEVERITY_FIELD_NUMBER: _ClassVar[int]
|
|
106
|
-
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
|
107
|
-
severity: Severity
|
|
108
|
-
message: str
|
|
109
|
-
def __init__(self, severity: _Optional[_Union[Severity, str]] = ..., message: _Optional[str] = ...) -> None: ...
|
|
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.1.0 → crossplane_function_sdk_python-0.3.0}/tests/test_response.py
RENAMED
|
File without changes
|