crossplane-function-pythonic 0.6.3__py3-none-any.whl → 0.7.0__py3-none-any.whl

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.
@@ -1,3 +1,4 @@
1
+ import argparse
1
2
  import asyncio
2
3
  import importlib
3
4
  import inspect
@@ -5,10 +6,13 @@ import json
5
6
  import logging
6
7
  import pathlib
7
8
  import sys
9
+ import typing
10
+ from typing import cast
8
11
 
9
12
  import inflect
10
13
  import kr8s
11
14
  import yaml
15
+ from kr8s._api import Api
12
16
 
13
17
  from . import (
14
18
  command,
@@ -27,7 +31,7 @@ class Command(command.Command):
27
31
  help = "Render a function-pythonic Composition"
28
32
 
29
33
  @classmethod
30
- def add_parser_arguments(cls, parser):
34
+ def add_parser_arguments(cls, parser: argparse.ArgumentParser) -> None:
31
35
  cls.add_function_arguments(parser)
32
36
  parser.add_argument(
33
37
  "composite",
@@ -113,16 +117,16 @@ class Command(command.Command):
113
117
  help="Include the context in the rendered output as a resource of kind: Context.",
114
118
  )
115
119
 
116
- def initialize(self):
117
- if self.args:
120
+ def initialize(self) -> None:
121
+ if vars(self.args):
118
122
  self.initialize_function()
119
123
  self.logger = logging.getLogger(__name__)
120
124
 
121
- async def run(self):
125
+ async def run(self) -> None:
122
126
  if self.args.kube_context:
123
- api = await kr8s.asyncio.api(context=self.args.kube_context)
127
+ api: Api | None = await kr8s.asyncio.api(context=self.args.kube_context)
124
128
  else:
125
- api = None
129
+ api: Api | None = None
126
130
  composite = await self.setup_composite(api)
127
131
  observed = self.collect_resources(self.args.observed_resources)
128
132
  composition = await self.setup_composition(composite, api)
@@ -180,13 +184,14 @@ class Command(command.Command):
180
184
  print("---")
181
185
  print(str(render.context), end="")
182
186
 
183
- async def setup_composite(self, api=None):
187
+ async def setup_composite(self, api=Api | None) -> protobuf.Value:
184
188
  # Obtain the Composite to render.
185
189
  if self.args.composite.is_file():
186
- return protobuf.Yaml(self.args.composite.read_text())
190
+ return cast(protobuf.Value, protobuf.Yaml(self.args.composite.read_text()))
187
191
  if not api:
188
192
  print(f'Composite "{self.args.composite}" is not a file', file=sys.stderr)
189
193
  sys.exit(1)
194
+ return
190
195
  composite = str(self.args.composite).split(":")
191
196
  if len(composite) == 3:
192
197
  namespace = None
@@ -202,14 +207,16 @@ class Command(command.Command):
202
207
  )
203
208
  sys.exit(1)
204
209
  composite = await self.kr8s_get(
205
- api, composite[0], composite[1], namespace, composite[-1]
210
+ cast(Api, api), composite[0], composite[1], namespace, composite[-1]
206
211
  )
207
212
  if not composite:
208
213
  print(f'Composite "{self.args.composite}" not found', file=sys.stderr)
209
214
  sys.exit(1)
210
215
  return composite
211
216
 
212
- async def setup_composition(self, composite, api=None):
217
+ async def setup_composition(
218
+ self, composite: protobuf.Value, api: Api | None = None
219
+ ) -> protobuf.Value | None:
213
220
  # Obtain the Composition that will be used to render the Composite.
214
221
  if not self.args.composition:
215
222
  return None
@@ -217,7 +224,7 @@ class Command(command.Command):
217
224
  composition = self.args.composition.read_text()
218
225
  if self.args.composition.suffix == ".py":
219
226
  return self.create_composition(composite, composition)
220
- composition = protobuf.Yaml(composition)
227
+ composition = cast(protobuf.Value, protobuf.Yaml(composition))
221
228
  if not len(composition.spec.pipeline):
222
229
  print(
223
230
  f"Composition file does not contain any pipeline steps: {self.args.composition}",
@@ -262,7 +269,9 @@ class Command(command.Command):
262
269
  sys.exit(1)
263
270
  return self.create_composition(composite, self.args.composition)
264
271
 
265
- def create_composition(self, composite, module=""):
272
+ def create_composition(
273
+ self, composite: protobuf.Value, module: str = ""
274
+ ) -> protobuf.Value:
266
275
  composition = protobuf.Map()
267
276
  composition.apiVersion = "apiextensions.crossplane.io/v1"
268
277
  composition.kind = "Composition"
@@ -279,7 +288,7 @@ class Command(command.Command):
279
288
  composition.spec.pipeline[0].input.composite = str(module)
280
289
  return composition
281
290
 
282
- def collect_resources(self, entries):
291
+ def collect_resources(self, entries: list[pathlib.Path]) -> list[protobuf.Value]:
283
292
  resources = []
284
293
  for entry in entries:
285
294
  if entry.is_file():
@@ -299,7 +308,7 @@ class Command(command.Command):
299
308
  resources.sort(key=lambda resource: str(resource.metadata.name))
300
309
  return resources
301
310
 
302
- def collect_schemas(self, entries):
311
+ def collect_schemas(self, entries: list[pathlib.Path]) -> list[protobuf.Value]:
303
312
  schemas = []
304
313
  for entry in entries:
305
314
  if entry.is_file():
@@ -318,7 +327,7 @@ class Command(command.Command):
318
327
  sys.exit(1)
319
328
  return schemas
320
329
 
321
- def setup_context(self):
330
+ def setup_context(self) -> protobuf.Value:
322
331
  # Load the request context with any specified command line options.
323
332
  context = protobuf.Map()
324
333
  for entry in self.args.context_files:
@@ -341,17 +350,17 @@ class Command(command.Command):
341
350
 
342
351
  async def render(
343
352
  self,
344
- composite,
345
- observed=None,
346
- composition=None,
347
- resources=None,
348
- schemas=None,
349
- context=None,
350
- api=None,
351
- render_unknowns=False,
352
- crossplane_v1=False,
353
- composite_observeds=False,
354
- ):
353
+ composite: protobuf.Value,
354
+ observed: list[protobuf.Value] | None = None,
355
+ composition: protobuf.Value | None = None,
356
+ resources: list[protobuf.Value] | None = None,
357
+ schemas: list[protobuf.Value] | None = None,
358
+ context: protobuf.Value | None = None,
359
+ api: Api | None = None,
360
+ render_unknowns: bool = False,
361
+ crossplane_v1: bool = False,
362
+ composite_observeds: bool = False,
363
+ ) -> protobuf.Value | None:
355
364
  # Create the request used when running Composition steps.
356
365
  if schemas is None:
357
366
  schemas = []
@@ -369,7 +378,9 @@ class Command(command.Command):
369
378
  request.context = context
370
379
 
371
380
  # Establish the request observed composite.
372
- await self.set_resource(composite, request.observed.composite, resources, api)
381
+ await self.set_resource(
382
+ composite, cast(protobuf.Value, request.observed.composite), resources, api
383
+ )
373
384
  # Establish the manually configured observed resources.
374
385
  if observed:
375
386
  async with asyncio.TaskGroup() as group:
@@ -381,7 +392,7 @@ class Command(command.Command):
381
392
  group.create_task(
382
393
  self.set_resource(
383
394
  resource,
384
- request.observed.resources[name],
395
+ cast(protobuf.Value, request.observed.resources[name]),
385
396
  resources,
386
397
  api,
387
398
  )
@@ -489,34 +500,49 @@ class Command(command.Command):
489
500
  for requirement in step.requirements.requiredResources:
490
501
  await self.set_required(
491
502
  requirement.requirementName,
492
- requirement,
493
- request.required_resources,
503
+ self.requirement_selector(requirement),
504
+ cast(protobuf.MapMessage, request.required_resources),
494
505
  resources,
495
506
  api,
496
507
  )
497
508
  # Fetch the required resources requested.
498
509
  for name, selector in requirements.resources:
499
510
  await self.set_required(
500
- name, selector, request.required_resources, resources, api
511
+ name,
512
+ selector,
513
+ cast(protobuf.MapMessage, request.required_resources),
514
+ resources,
515
+ api,
501
516
  )
502
517
  # Fetch the now deprecated extra resources requested.
503
518
  request.extra_resources()
504
519
  for name, selector in requirements.extra_resources:
505
520
  await self.set_required(
506
- name, selector, request.extra_resources, resources, api
521
+ name,
522
+ selector,
523
+ cast(protobuf.MapMessage, request.extra_resources),
524
+ resources,
525
+ api,
507
526
  )
508
527
  # Fetch the schemas requested.
509
528
  request.required_schemas()
510
529
  for name, selector in requirements.schemas:
511
530
  await self.set_schema(
512
- name, selector, request.required_schemas, schemas, api
531
+ name,
532
+ selector,
533
+ cast(protobuf.MapMessage, request.required_schemas),
534
+ schemas,
535
+ api,
513
536
  )
514
537
  # Run the step using the function-pythonic function runner.
515
538
  response = protobuf.Message(
516
539
  None,
517
540
  "response",
518
541
  fnv1.RunFunctionResponse.DESCRIPTOR,
519
- await runner.RunFunction(request._message, None),
542
+ await runner.RunFunction(
543
+ cast(fnv1.RunFunctionRequest, request._message),
544
+ None,
545
+ ),
520
546
  )
521
547
  # Copy the response context to the request context to use in subsequent steps.
522
548
  request.context = response.context
@@ -535,9 +561,14 @@ class Command(command.Command):
535
561
 
536
562
  # Copy the response desired state to the request desired state to use in subsequent steps.
537
563
  request.desired.resources()
538
- self.copy_resource(response.desired.composite, request.desired.composite)
564
+ self.copy_resource(
565
+ cast(protobuf.Message, response.desired.composite),
566
+ cast(protobuf.Message, request.desired.composite),
567
+ )
539
568
  for name, resource in response.desired.resources:
540
- self.copy_resource(resource, request.desired.resources[name])
569
+ self.copy_resource(
570
+ resource, cast(protobuf.Message, request.desired.resources[name])
571
+ )
541
572
 
542
573
  # Collect the step's returned conditions.
543
574
  for condition in response.conditions:
@@ -565,8 +596,8 @@ class Command(command.Command):
565
596
  break
566
597
 
567
598
  # Collect and format all the returned desired composed resources.
568
- resources = protobuf.List()
569
- unready = protobuf.List()
599
+ resources: protobuf.Value = protobuf.List()
600
+ unready: protobuf.Value = protobuf.List()
570
601
  prefix = composite.metadata.labels["crossplane.io/composite"]
571
602
  if not prefix:
572
603
  prefix = composite.metadata.name
@@ -580,7 +611,9 @@ class Command(command.Command):
580
611
  if not ready:
581
612
  unready[protobuf.append] = name
582
613
  resource = resource.resource
583
- observed = request.observed.resources[name].resource
614
+ observed: protobuf.Value = cast(
615
+ protobuf.Value, request.observed.resources[name].resource
616
+ )
584
617
  if observed:
585
618
  for key in ("namespace", "generateName", "name"):
586
619
  if observed.metadata[key]:
@@ -666,7 +699,14 @@ class Command(command.Command):
666
699
  response.observed[name] = resource.resource
667
700
  return response
668
701
 
669
- async def get_composite_ref(self, composite, ref, request, resources, api):
702
+ async def get_composite_ref(
703
+ self,
704
+ composite: protobuf.Value,
705
+ ref: protobuf.Value,
706
+ request: protobuf.Message,
707
+ resources: list[protobuf.Value],
708
+ api: Api,
709
+ ) -> None:
670
710
  namespace = ref.namespace
671
711
  if not namespace:
672
712
  namespace = composite.metadata.namespace
@@ -680,9 +720,18 @@ class Command(command.Command):
680
720
  if name:
681
721
  destination = request.observed.resources[name]
682
722
  if not destination: # Do not override manual observed
683
- await self.set_resource(source, destination, resources, api)
723
+ await self.set_resource(
724
+ source, cast(protobuf.Value, destination), resources, api
725
+ )
684
726
 
685
- async def set_required(self, name, selector, requireds, resources=None, api=None):
727
+ async def set_required(
728
+ self,
729
+ name: protobuf.TypeString,
730
+ selector: protobuf.Message,
731
+ requireds: protobuf.MapMessage,
732
+ resources: list[protobuf.Value] | None = None,
733
+ api: Api | None = None,
734
+ ) -> None:
686
735
  if resources is None:
687
736
  resources = []
688
737
  if not name:
@@ -718,10 +767,10 @@ class Command(command.Command):
718
767
  if len(selector.match_name):
719
768
  resource = await self.kr8s_get(
720
769
  api,
721
- selector.kind,
722
- selector.api_version,
723
- selector.namespace,
724
- selector.match_name,
770
+ cast(protobuf.TypeString, selector.kind),
771
+ cast(protobuf.TypeString, selector.api_version),
772
+ cast(protobuf.TypeString, selector.namespace),
773
+ cast(protobuf.TypeString, selector.match_name),
725
774
  )
726
775
  if resource:
727
776
  await self.set_resource(
@@ -730,16 +779,41 @@ class Command(command.Command):
730
779
  elif len(selector.match_labels.labels):
731
780
  for resource in await self.kr8s_list(
732
781
  api,
733
- selector.kind,
734
- selector.api_version,
735
- selector.namespace,
736
- selector.match_labels.labels,
782
+ cast(protobuf.TypeString, selector.kind),
783
+ cast(protobuf.TypeString, selector.api_version),
784
+ cast(protobuf.TypeString, selector.namespace),
785
+ cast(protobuf.MapMessage, selector.match_labels.labels),
737
786
  ):
738
787
  await self.set_resource(
739
788
  resource, items[protobuf.append], resources, api
740
789
  )
741
790
 
742
- async def set_resource(self, source, destination, resources=None, api=None):
791
+ def requirement_selector(self, requirement: protobuf.Value) -> protobuf.Message:
792
+ # Convert a Composition step requirement into a function ResourceSelector.
793
+ selector = protobuf.Message(
794
+ None,
795
+ "selector",
796
+ fnv1.ResourceSelector.DESCRIPTOR,
797
+ fnv1.ResourceSelector(),
798
+ )
799
+ selector.api_version = requirement.apiVersion
800
+ selector.kind = requirement.kind
801
+ if requirement.namespace:
802
+ selector.namespace = requirement.namespace
803
+ if requirement.name:
804
+ selector.match_name = requirement.name
805
+ elif requirement.matchLabels:
806
+ for key, value in requirement.matchLabels:
807
+ selector.match_labels.labels[key] = value
808
+ return selector
809
+
810
+ async def set_resource(
811
+ self,
812
+ source: protobuf.Value,
813
+ destination: protobuf.Value,
814
+ resources: list[protobuf.Value] | None = None,
815
+ api: Api | None = None,
816
+ ) -> None:
743
817
  if resources is None:
744
818
  resources = []
745
819
  destination.resource = source
@@ -769,7 +843,14 @@ class Command(command.Command):
769
843
  for key, value in connection.data:
770
844
  destination.connection_details[key] = protobuf.B64Decode(value)
771
845
 
772
- async def set_schema(self, name, selector, schemas, documents=None, api=None):
846
+ async def set_schema(
847
+ self,
848
+ name: protobuf.TypeString,
849
+ selector: protobuf.Value,
850
+ schemas: protobuf.MapMessage,
851
+ documents: list[protobuf.Value] | None = None,
852
+ api: Api | None = None,
853
+ ) -> None:
773
854
  if documents is None:
774
855
  documents = []
775
856
  if not name:
@@ -801,7 +882,9 @@ class Command(command.Command):
801
882
  return
802
883
  self.find_schema(gvk, document, schema)
803
884
 
804
- def find_schema(self, gvk, document, schema):
885
+ def find_schema(
886
+ self, gvk: protobuf.Value, document: protobuf.Value, schema: protobuf.Value
887
+ ) -> bool:
805
888
  for name, s in document.components.schemas:
806
889
  gvks = s["x-kubernetes-group-version-kind"]
807
890
  if len(gvks) == 1 and gvks[0] == gvk:
@@ -811,20 +894,23 @@ class Command(command.Command):
811
894
  return True
812
895
  return False
813
896
 
814
- def resolve_ref(self, document, visiting, ref, schema):
897
+ def resolve_ref(
898
+ self,
899
+ document: protobuf.Value,
900
+ visiting: set,
901
+ ref: protobuf.TypeString,
902
+ schema: protobuf.Value,
903
+ ) -> None:
815
904
  if not ref:
816
905
  return
817
906
  ref = str(ref)
818
907
  if ref in visiting:
819
908
  return
820
- d = None
821
- for segment in ref.split("/"):
822
- if segment == "#":
823
- d = document
824
- else:
825
- d = d[segment]
826
- if not d:
909
+ if not ref.startswith("#/"):
827
910
  return
911
+ d = document
912
+ for segment in ref.split("/")[1:]:
913
+ d = d[segment]
828
914
  visiting.add(ref)
829
915
  try:
830
916
  for name, value in d:
@@ -832,7 +918,14 @@ class Command(command.Command):
832
918
  finally:
833
919
  visiting.remove(ref)
834
920
 
835
- def copy_schema(self, document, visiting, key, value, schema):
921
+ def copy_schema(
922
+ self,
923
+ document: protobuf.Value,
924
+ visiting: set,
925
+ key: str | int,
926
+ value: protobuf.Value,
927
+ schema: protobuf.Value,
928
+ ) -> None:
836
929
  if key == "$ref":
837
930
  self.resolve_ref(document, visiting, value, schema)
838
931
  elif key == "allOf":
@@ -850,29 +943,37 @@ class Command(command.Command):
850
943
  else:
851
944
  schema[key] = value
852
945
 
853
- def copy_resource(self, source, destination):
946
+ def copy_resource(
947
+ self, source: protobuf.Message, destination: protobuf.Message
948
+ ) -> None:
854
949
  destination.resource = source.resource
855
950
  destination.connection_details()
856
951
  for key, value in source.connection_details:
857
952
  destination.connection_details[key] = value
858
953
  destination.ready = source.ready
859
954
 
860
- def create_condition(self, type, status, reason, message=None):
955
+ def create_condition(
956
+ self,
957
+ type: str,
958
+ status: protobuf.FieldMessage | bool | None,
959
+ reason: str,
960
+ message: str | None = None,
961
+ ) -> dict[str, str]:
861
962
  if isinstance(status, protobuf.FieldMessage):
862
963
  if status._value == fnv1.Status.STATUS_CONDITION_TRUE:
863
- status = "True"
964
+ status: str = "True"
864
965
  elif status._value == fnv1.Status.STATUS_CONDITION_FALSE:
865
- status = "False"
966
+ status: str = "False"
866
967
  else:
867
- status = "Unknown"
968
+ status: str = "Unknown"
868
969
  elif isinstance(status, bool):
869
970
  if status:
870
- status = "True"
971
+ status: str = "True"
871
972
  else:
872
- status = "False"
973
+ status: str = "False"
873
974
  elif status is None:
874
- status = "Unknown"
875
- condition = {
975
+ status: str = "Unknown"
976
+ condition: dict[str, str] = {
876
977
  "type": type,
877
978
  "status": status,
878
979
  "reason": reason,
@@ -882,8 +983,15 @@ class Command(command.Command):
882
983
  condition["message"] = message
883
984
  return condition
884
985
 
885
- async def kr8s_get(self, api, kind, apiVersion, namespace, name):
886
- namespaced = namespace and len(namespace)
986
+ async def kr8s_get(
987
+ self,
988
+ api: Api,
989
+ kind: protobuf.TypeString,
990
+ apiVersion: protobuf.TypeString,
991
+ namespace: protobuf.TypeString | None,
992
+ name: protobuf.TypeString,
993
+ ) -> protobuf.Value | None:
994
+ namespaced = bool(namespace) and bool(len(namespace))
887
995
  clazz = self.kr8s_class(kind, apiVersion, namespaced)
888
996
  try:
889
997
  fullName = [str(kind), str(apiVersion), str(name)]
@@ -900,15 +1008,27 @@ class Command(command.Command):
900
1008
  self.logger.debug(f"Resource {result}: {':'.join(fullName)}")
901
1009
  return resource
902
1010
 
903
- async def kr8s_list(self, api, kind, apiVersion, namespace, labelSelector):
904
- namespaced = namespace and len(namespace)
1011
+ async def kr8s_list(
1012
+ self,
1013
+ api: Api,
1014
+ kind: protobuf.TypeString,
1015
+ apiVersion: protobuf.TypeString,
1016
+ namespace: protobuf.TypeString | None,
1017
+ labelSelector: protobuf.MapMessage,
1018
+ ) -> list[protobuf.Value]:
1019
+ namespaced = bool(namespace) and bool(len(namespace))
905
1020
  clazz = self.kr8s_class(kind, apiVersion, namespaced)
906
1021
  resources = [
907
1022
  protobuf.Value(None, None, resource.raw)
908
- async for resource in clazz.list(
909
- namespace=str(namespace) if namespaced else None,
910
- label_selector={label: str(value) for label, value in labelSelector},
911
- api=api,
1023
+ async for resource in cast(
1024
+ typing.AsyncGenerator[kr8s.APIObject],
1025
+ clazz.list(
1026
+ namespace=str(namespace) if namespaced else None,
1027
+ label_selector={
1028
+ label: str(value) for label, value in labelSelector
1029
+ },
1030
+ api=api,
1031
+ ),
912
1032
  )
913
1033
  ]
914
1034
  if self.logger.isEnabledFor(logging.DEBUG):
@@ -919,13 +1039,18 @@ class Command(command.Command):
919
1039
  "&".join(f"{label}={value}" for label, value in labelSelector)
920
1040
  )
921
1041
  if resources:
922
- result = f"found {INFLECT.number_to_words(len(resources))}"
1042
+ result = f"found {INFLECT.number_to_words(str(len(resources)))}"
923
1043
  else:
924
1044
  result = "missing"
925
1045
  self.logger.debug(f"Resources {result}: {':'.join(fullName)}")
926
1046
  return resources
927
1047
 
928
- def kr8s_class(self, kind, apiVersion, namespaced):
1048
+ def kr8s_class(
1049
+ self,
1050
+ kind: protobuf.TypeString,
1051
+ apiVersion: protobuf.TypeString,
1052
+ namespaced: bool,
1053
+ ) -> type[kr8s.APIObject]:
929
1054
  try:
930
1055
  return kr8s.asyncio.objects.get_class(str(kind), str(apiVersion), True)
931
1056
  except KeyError:
@@ -8,5 +8,5 @@ class Command(command.Command):
8
8
  name = "version"
9
9
  help = "Print the function-pythonic version"
10
10
 
11
- async def run(self):
11
+ async def run(self) -> None:
12
12
  print(__about__.__version__)
@@ -1,18 +1,18 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: crossplane-function-pythonic
3
- Version: 0.6.3
3
+ Version: 0.7.0
4
4
  Summary: A Python centric Crossplane Function
5
5
  Author: Patrick J McNerthney
6
6
  Author-email: Patrick J McNerthney <pat@mcnerthney.com>
7
7
  License-Expression: Apache-2.0
8
- Requires-Dist: grpcio==1.84.0
8
+ Requires-Dist: grpcio==1.85.1
9
9
  Requires-Dist: inflect==7.6.0
10
10
  Requires-Dist: kr8s==0.20.15
11
11
  Requires-Dist: protobuf==7.36.2
12
12
  Requires-Dist: pyyaml==6.0.3
13
- Requires-Dist: kopf==1.45.1 ; extra == 'packages'
13
+ Requires-Dist: kopf==1.45.2 ; extra == 'packages'
14
14
  Requires-Dist: pip==26.2.2 ; extra == 'pip-install'
15
- Requires-Python: >=3.12, <3.16
15
+ Requires-Python: >=3.15, <3.16
16
16
  Project-URL: Documentation, https://github.com/crossplane-contrib/function-pythonic#readme
17
17
  Project-URL: Issues, https://github.com/crossplane-contrib/function-pythonic/issues
18
18
  Project-URL: Source, https://github.com/crossplane-contrib/function-pythonic
@@ -0,0 +1,22 @@
1
+ crossplane/pythonic/__about__.py,sha256=xViFFR_npzf2RXvljN98CNoUFOZ2KN9Hwgcbx4KCPpg,180
2
+ crossplane/pythonic/__init__.py,sha256=b4LHrCWoibhkzeIAWbXsT_JBW4S2X7twrA7c1BtMxAo,331
3
+ crossplane/pythonic/__main__.py,sha256=Ipm-KZJB7V1CFJ96iF1-pN8CBfK7qdsykjsmt4hl7LQ,32
4
+ crossplane/pythonic/auto_ready.py,sha256=n9hnv6f2vzCHFr-Lq_CAib5ik5vVxpORSQIUE1lOoVE,8153
5
+ crossplane/pythonic/command.py,sha256=vPx8zqg4NpIsZsECa75r6wFJse_g__jsPvspe9-5TXE,4691
6
+ crossplane/pythonic/composite.py,sha256=xg4ntzYJL-FfVsgQL452cy8yMB0NWv90VNAAk5WWZLU,45249
7
+ crossplane/pythonic/function.py,sha256=qRhr_QBuSucUZvjGrzEL92a3kH3z-BTyNp9Q0SBF6q4,22624
8
+ crossplane/pythonic/grpc.py,sha256=iQ5NUxnzvQ5zMgjNdjERiml2KpJHi9tgqd5Ez-xterc,6115
9
+ crossplane/pythonic/main.py,sha256=fa3mwEaULscAF2IszvIkLf7l-ryP3hElnlpJZXUhaM0,981
10
+ crossplane/pythonic/packages.py,sha256=8UIPuGz8xiCuDoNyuN-kcJIyjPQkcPyTQd1Gfdmz7CM,7855
11
+ crossplane/pythonic/proto/v1/run_function.proto,sha256=GbJ0wVUEjfpMsn2DsnhiPvtmL09z3oyMbWwf6viQtiw,16676
12
+ crossplane/pythonic/proto/v1/run_function_pb2.py,sha256=kj1vcbOGGMlnF0YxMR774JhTQsfIk0Y5ZRRBpF_F5nY,14440
13
+ crossplane/pythonic/proto/v1/run_function_pb2.pyi,sha256=eFq00EFNSY3Pj_6CUJR90qa_kc82uZ2Y3jSw8CVIWoQ,53056
14
+ crossplane/pythonic/proto/v1/run_function_pb2_grpc.py,sha256=VOIGzcYAbgJgXUPEg1iMZY4LJ27E448nfwQxxIVS5ag,3944
15
+ crossplane/pythonic/proto/v1/run_function_pb2_grpc.pyi,sha256=QQsbwTUlzW36c75ujlrgZMa3Zk8xalTpWm4q5oE2qWc,2406
16
+ crossplane/pythonic/protobuf.py,sha256=6IJGpo9WCEg9WVzYY0QV3h5Go2wk2pinEFruimV_a0g,61006
17
+ crossplane/pythonic/render.py,sha256=OUHrTBU3qFMiliXljnsdJ48yF9M1mI0sRW_plBlyoWo,42247
18
+ crossplane/pythonic/version.py,sha256=T70dXiH5zW7qhQ2Tigw4xBT-zBVDwm5Sp1BEmQ4SQrw,221
19
+ crossplane_function_pythonic-0.7.0.dist-info/WHEEL,sha256=3NO1oYsF7mANFUWVdyEQLM-zmecczWWEmmF5rEbXrWk,80
20
+ crossplane_function_pythonic-0.7.0.dist-info/entry_points.txt,sha256=yT7OSM0ZYJoX1rya2HZfIrGzCXbYdqMblBtqEDH8LzM,69
21
+ crossplane_function_pythonic-0.7.0.dist-info/METADATA,sha256=KDlgGfoLqVHwB_xXn4sHoJXnY5Vp2VJeQRM6hpFRD0E,36502
22
+ crossplane_function_pythonic-0.7.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.13.4
2
+ Generator: uv 0.13.6
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any