crossplane-function-sdk-python 0.1.0__tar.gz → 0.2.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.1.0 → crossplane_function_sdk_python-0.2.0}/.github/workflows/ci.yml +46 -0
  2. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/.gitignore +3 -0
  3. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/PKG-INFO +14 -6
  4. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/README.md +12 -4
  5. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/crossplane/function/__version__.py +1 -1
  6. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/crossplane/function/proto/v1beta1/run_function.proto +39 -0
  7. crossplane_function_sdk_python-0.2.0/crossplane/function/proto/v1beta1/run_function_pb2.py +74 -0
  8. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/crossplane/function/proto/v1beta1/run_function_pb2.pyi +68 -13
  9. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/pyproject.toml +13 -9
  10. crossplane_function_sdk_python-0.1.0/crossplane/function/proto/v1beta1/run_function_pb2.py +0 -53
  11. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  12. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  13. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  14. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/LICENSE +0 -0
  15. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/crossplane/function/logging.py +0 -0
  16. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/crossplane/function/proto/v1beta1/run_function_pb2_grpc.py +0 -0
  17. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/crossplane/function/resource.py +0 -0
  18. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/crossplane/function/response.py +0 -0
  19. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/crossplane/function/runtime.py +0 -0
  20. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/renovate.json +0 -0
  21. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.0}/tests/test_resource.py +0 -0
  22. {crossplane_function_sdk_python-0.1.0 → crossplane_function_sdk_python-0.2.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'
@@ -113,3 +126,36 @@ jobs:
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@v4
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
1
  Metadata-Version: 2.1
2
2
  Name: crossplane-function-sdk-python
3
- Version: 0.1.0
3
+ Version: 0.2.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==23.*
17
+ Requires-Dist: structlog==24.*
18
18
  Description-Content-Type: text/markdown
19
19
 
20
20
  # function-sdk-python
21
- [![CI](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml/badge.svg)](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/release/crossplane/function-sdk-python)
21
+ [![CI](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml/badge.svg)](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml) [![GitHub release (latest SemVer)](https://img.shields.io/github/release/crossplane/function-sdk-python)](https://github.com/crossplane/function-sdk-python/releases) [![PyPI - Version](https://img.shields.io/pypi/v/crossplane-function-sdk-python)](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
- * [Learn about Python code generated from protocol buffers][python-protobuf]
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 familiarize yourself
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
- [![CI](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml/badge.svg)](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/release/crossplane/function-sdk-python)
2
+ [![CI](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml/badge.svg)](https://github.com/crossplane/function-sdk-python/actions/workflows/ci.yml) [![GitHub release (latest SemVer)](https://img.shields.io/github/release/crossplane/function-sdk-python)](https://github.com/crossplane/function-sdk-python/releases) [![PyPI - Version](https://img.shields.io/pypi/v/crossplane-function-sdk-python)](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
- * [Learn about Python code generated from protocol buffers][python-protobuf]
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 familiarize yourself
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
@@ -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.1.0"
18
+ __version__ = "0.2.0"
@@ -61,6 +61,19 @@ 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
+
74
+ // Resources represents the state of several Crossplane resources.
75
+ message Resources {
76
+ repeated Resource items = 1;
64
77
  }
65
78
 
66
79
  // A RunFunctionResponse contains the result of a Composition Function run.
@@ -88,6 +101,9 @@ message RunFunctionResponse {
88
101
  // Optional context to be passed to the next Function in the pipeline as part
89
102
  // of the RunFunctionRequest. Dropped on the last function in the pipeline.
90
103
  optional google.protobuf.Struct context = 4;
104
+
105
+ // Requirements that must be satisfied for this Function to run successfully.
106
+ Requirements requirements = 5;
91
107
  }
92
108
 
93
109
  // RequestMeta contains metadata pertaining to a RunFunctionRequest.
@@ -97,6 +113,29 @@ message RequestMeta {
97
113
  string tag = 1;
98
114
  }
99
115
 
116
+ // Requirements that must be satisfied for a Function to run successfully.
117
+ message Requirements {
118
+ // Extra resources that this Function requires.
119
+ // The map key uniquely identifies the group of resources.
120
+ map<string, ResourceSelector> extra_resources = 1;
121
+ }
122
+
123
+ // ResourceSelector selects a group of resources, either by name or by label.
124
+ message ResourceSelector {
125
+ string api_version = 1;
126
+ string kind = 2;
127
+
128
+ oneof match {
129
+ string match_name = 3;
130
+ MatchLabels match_labels = 4;
131
+ }
132
+ }
133
+
134
+ // MatchLabels defines a set of labels to match resources against.
135
+ message MatchLabels {
136
+ map<string, string> labels = 1;
137
+ }
138
+
100
139
  // ResponseMeta contains metadata pertaining to a RunFunctionResponse.
101
140
  message ResponseMeta {
102
141
  // An opaque string identifying the content of the request. Must match the
@@ -0,0 +1,74 @@
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)
@@ -9,13 +9,13 @@ from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Map
9
9
  DESCRIPTOR: _descriptor.FileDescriptor
10
10
 
11
11
  class Ready(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
12
- __slots__ = []
12
+ __slots__ = ()
13
13
  READY_UNSPECIFIED: _ClassVar[Ready]
14
14
  READY_TRUE: _ClassVar[Ready]
15
15
  READY_FALSE: _ClassVar[Ready]
16
16
 
17
17
  class Severity(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
18
- __slots__ = []
18
+ __slots__ = ()
19
19
  SEVERITY_UNSPECIFIED: _ClassVar[Severity]
20
20
  SEVERITY_FATAL: _ClassVar[Severity]
21
21
  SEVERITY_WARNING: _ClassVar[Severity]
@@ -29,39 +29,94 @@ SEVERITY_WARNING: Severity
29
29
  SEVERITY_NORMAL: Severity
30
30
 
31
31
  class RunFunctionRequest(_message.Message):
32
- __slots__ = ["meta", "observed", "desired", "input", "context"]
32
+ __slots__ = ("meta", "observed", "desired", "input", "context", "extra_resources")
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: ...
33
40
  META_FIELD_NUMBER: _ClassVar[int]
34
41
  OBSERVED_FIELD_NUMBER: _ClassVar[int]
35
42
  DESIRED_FIELD_NUMBER: _ClassVar[int]
36
43
  INPUT_FIELD_NUMBER: _ClassVar[int]
37
44
  CONTEXT_FIELD_NUMBER: _ClassVar[int]
45
+ EXTRA_RESOURCES_FIELD_NUMBER: _ClassVar[int]
38
46
  meta: RequestMeta
39
47
  observed: State
40
48
  desired: State
41
49
  input: _struct_pb2.Struct
42
50
  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: ...
51
+ 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: ...
53
+
54
+ class Resources(_message.Message):
55
+ __slots__ = ("items",)
56
+ ITEMS_FIELD_NUMBER: _ClassVar[int]
57
+ items: _containers.RepeatedCompositeFieldContainer[Resource]
58
+ def __init__(self, items: _Optional[_Iterable[_Union[Resource, _Mapping]]] = ...) -> None: ...
44
59
 
45
60
  class RunFunctionResponse(_message.Message):
46
- __slots__ = ["meta", "desired", "results", "context"]
61
+ __slots__ = ("meta", "desired", "results", "context", "requirements")
47
62
  META_FIELD_NUMBER: _ClassVar[int]
48
63
  DESIRED_FIELD_NUMBER: _ClassVar[int]
49
64
  RESULTS_FIELD_NUMBER: _ClassVar[int]
50
65
  CONTEXT_FIELD_NUMBER: _ClassVar[int]
66
+ REQUIREMENTS_FIELD_NUMBER: _ClassVar[int]
51
67
  meta: ResponseMeta
52
68
  desired: State
53
69
  results: _containers.RepeatedCompositeFieldContainer[Result]
54
70
  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: ...
71
+ requirements: Requirements
72
+ 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: ...
56
73
 
57
74
  class RequestMeta(_message.Message):
58
- __slots__ = ["tag"]
75
+ __slots__ = ("tag",)
59
76
  TAG_FIELD_NUMBER: _ClassVar[int]
60
77
  tag: str
61
78
  def __init__(self, tag: _Optional[str] = ...) -> None: ...
62
79
 
80
+ class Requirements(_message.Message):
81
+ __slots__ = ("extra_resources",)
82
+ class ExtraResourcesEntry(_message.Message):
83
+ __slots__ = ("key", "value")
84
+ KEY_FIELD_NUMBER: _ClassVar[int]
85
+ VALUE_FIELD_NUMBER: _ClassVar[int]
86
+ key: str
87
+ value: ResourceSelector
88
+ def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[ResourceSelector, _Mapping]] = ...) -> None: ...
89
+ EXTRA_RESOURCES_FIELD_NUMBER: _ClassVar[int]
90
+ extra_resources: _containers.MessageMap[str, ResourceSelector]
91
+ def __init__(self, extra_resources: _Optional[_Mapping[str, ResourceSelector]] = ...) -> None: ...
92
+
93
+ class ResourceSelector(_message.Message):
94
+ __slots__ = ("api_version", "kind", "match_name", "match_labels")
95
+ API_VERSION_FIELD_NUMBER: _ClassVar[int]
96
+ KIND_FIELD_NUMBER: _ClassVar[int]
97
+ MATCH_NAME_FIELD_NUMBER: _ClassVar[int]
98
+ MATCH_LABELS_FIELD_NUMBER: _ClassVar[int]
99
+ api_version: str
100
+ kind: str
101
+ match_name: str
102
+ match_labels: MatchLabels
103
+ def __init__(self, api_version: _Optional[str] = ..., kind: _Optional[str] = ..., match_name: _Optional[str] = ..., match_labels: _Optional[_Union[MatchLabels, _Mapping]] = ...) -> None: ...
104
+
105
+ class MatchLabels(_message.Message):
106
+ __slots__ = ("labels",)
107
+ class LabelsEntry(_message.Message):
108
+ __slots__ = ("key", "value")
109
+ KEY_FIELD_NUMBER: _ClassVar[int]
110
+ VALUE_FIELD_NUMBER: _ClassVar[int]
111
+ key: str
112
+ value: str
113
+ def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
114
+ LABELS_FIELD_NUMBER: _ClassVar[int]
115
+ labels: _containers.ScalarMap[str, str]
116
+ def __init__(self, labels: _Optional[_Mapping[str, str]] = ...) -> None: ...
117
+
63
118
  class ResponseMeta(_message.Message):
64
- __slots__ = ["tag", "ttl"]
119
+ __slots__ = ("tag", "ttl")
65
120
  TAG_FIELD_NUMBER: _ClassVar[int]
66
121
  TTL_FIELD_NUMBER: _ClassVar[int]
67
122
  tag: str
@@ -69,9 +124,9 @@ class ResponseMeta(_message.Message):
69
124
  def __init__(self, tag: _Optional[str] = ..., ttl: _Optional[_Union[_duration_pb2.Duration, _Mapping]] = ...) -> None: ...
70
125
 
71
126
  class State(_message.Message):
72
- __slots__ = ["composite", "resources"]
127
+ __slots__ = ("composite", "resources")
73
128
  class ResourcesEntry(_message.Message):
74
- __slots__ = ["key", "value"]
129
+ __slots__ = ("key", "value")
75
130
  KEY_FIELD_NUMBER: _ClassVar[int]
76
131
  VALUE_FIELD_NUMBER: _ClassVar[int]
77
132
  key: str
@@ -84,9 +139,9 @@ class State(_message.Message):
84
139
  def __init__(self, composite: _Optional[_Union[Resource, _Mapping]] = ..., resources: _Optional[_Mapping[str, Resource]] = ...) -> None: ...
85
140
 
86
141
  class Resource(_message.Message):
87
- __slots__ = ["resource", "connection_details", "ready"]
142
+ __slots__ = ("resource", "connection_details", "ready")
88
143
  class ConnectionDetailsEntry(_message.Message):
89
- __slots__ = ["key", "value"]
144
+ __slots__ = ("key", "value")
90
145
  KEY_FIELD_NUMBER: _ClassVar[int]
91
146
  VALUE_FIELD_NUMBER: _ClassVar[int]
92
147
  key: str
@@ -101,7 +156,7 @@ class Resource(_message.Message):
101
156
  def __init__(self, resource: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., connection_details: _Optional[_Mapping[str, bytes]] = ..., ready: _Optional[_Union[Ready, str]] = ...) -> None: ...
102
157
 
103
158
  class Result(_message.Message):
104
- __slots__ = ["severity", "message"]
159
+ __slots__ = ("severity", "message")
105
160
  SEVERITY_FIELD_NUMBER: _ClassVar[int]
106
161
  MESSAGE_FIELD_NUMBER: _ClassVar[int]
107
162
  severity: Severity
@@ -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 # Allow going from 0.0.0.dev0+x to 0.0.0.dev0+y.
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.19.0"]
35
+ dependencies = ["ipython==8.21.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.60.0"]
41
+ dependencies = ["grpcio-tools==1.60.1"]
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.1.11"]
50
+ dependencies = ["ruff==0.2.2"]
55
51
 
56
52
  [tool.hatch.envs.lint.scripts]
57
53
  check = "ruff check crossplane tests && ruff format --diff crossplane tests"
@@ -63,6 +59,14 @@ 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
 
@@ -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)